Metadata-Version: 2.4
Name: pydplus
Version: 2.0.1
Summary: A Python toolset for the RSA ID Plus cloud authentication platform
License-Expression: MIT
License-File: LICENSE
Keywords: rsa-security,id-plus,rsa-id-plus,securid,rsa-securid,authentication-manager,rsa-authentication-manager,cloud-access-service,single-sign-on,sso,mfa,iam,identity,authentication,multifactor-authentication,fido
Author: Jeff Shurtliff
Author-email: jeff@shurt.us
Maintainer: Jeff Shurtliff
Maintainer-email: jeff@shurt.us
Requires-Python: >=3.12,<3.14.0
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Developers
Classifier: Environment :: Web Environment
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Communications :: FIDO
Classifier: Topic :: Office/Business
Classifier: Topic :: Security
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: PyYAML (>=6.0.3,<7)
Requires-Dist: certifi (>=2024.7.4)
Requires-Dist: cryptography (>=50.0.0)
Requires-Dist: idna (>=3.15,<4)
Requires-Dist: pyjwt (>=2.13.0)
Requires-Dist: requests (>=2.32.5)
Requires-Dist: urllib3 (>=2.7.0,<3)
Project-URL: Changelog, https://pydplus.readthedocs.io/en/latest/CHANGELOG.html
Project-URL: Documentation, https://pydplus.readthedocs.io/en/stable/
Project-URL: Homepage, https://github.com/jeffshurtliff/pydplus
Project-URL: Issue Tracker, https://github.com/jeffshurtliff/pydplus/issues
Project-URL: Repository, https://github.com/jeffshurtliff/pydplus
Description-Content-Type: text/markdown

<img src="https://raw.githubusercontent.com/jeffshurtliff/pydplus/main/docs/_static/pydplus-icon-cropped.png" 
     class="pydplus-c-landing-page-logo" 
     style="background-color: transparent; max-height: 320px;"
     alt="PyDPlus Logo">

# PyDPlus
A Python toolset for the RSA<sup>&reg;</sup> ID Plus cloud authentication platform.

<table>
    <tr>
        <td>Latest Stable Release</td>
        <td>
            <a href="https://pypi.org/project/pydplus/">
                <img alt="PyPI" src="https://img.shields.io/pypi/v/pydplus">
            </a>
        </td>
    </tr>
    <tr>
        <td>Latest Pre-release</td>
        <td>
            <a href="https://pypi.org/project/pydplus/#history">
                <img alt="PyPI" src="https://img.shields.io/badge/pypi-none-blue">
            </a>
        </td>
    </tr>
    <tr>
        <td>Supported Versions (Stable Release)</td>
        <td>
            <a href="https://pypi.org/project/pydplus/">
                <img alt="PyPI - Python Versions Supported (Stable Release)" src="https://img.shields.io/pypi/pyversions/pydplus">
            </a>
        </td>
    </tr>
    <tr>
         <td>Commits Since Latest Release</td>
         <td>
            <a href="https://github.com/jeffshurtliff/pydplus/compare/2.0.0...HEAD">
                <img alt="GitHub commits since latest release" src="https://img.shields.io/github/commits-since/jeffshurtliff/pydplus/latest">
            </a>
        </td>
    </tr>
    <tr>
        <td>Build Status</td>
        <td>
            <a href="https://github.com/jeffshurtliff/pydplus/blob/main/.github/workflows/ci.yml">
                <img alt="GitHub Workflow Status" 
                src="https://img.shields.io/github/actions/workflow/status/jeffshurtliff/pydplus/ci.yml?branch=main">
            </a>
        </td>
    </tr>
    <tr>
        <td>Code Coverage</td>
        <td>
            <a href="https://codecov.io/gh/jeffshurtliff/pydplus">
                <img alt="Codecov - Code Coverage" src="https://codecov.io/gh/jeffshurtliff/pydplus/branch/main/graph/badge.svg?token=QBynJO48jN">
            </a>
        </td>
    </tr>
    <tr>
        <td>Documentation</td>
        <td>
            <a href="https://pydplus.readthedocs.io/en/stable/?badge=stable">
                <img alt="Documentation Status" src="https://readthedocs.org/projects/pydplus/badge/?version=stable">
            </a>
        </td>
    </tr>
    <tr>
        <td>Security Audits</td>
        <td>
            <a href="https://github.com/marketplace/actions/python-security-check-using-bandit">
                <img alt="Bandit" src="https://img.shields.io/badge/security-bandit-yellow.svg">
            </a>
        </td>
    </tr>
    <tr>
        <td>License</td>
        <td>
            <a href="https://github.com/jeffshurtliff/pydplus/blob/main/LICENSE">
                <img alt="License (GitHub)" src="https://img.shields.io/github/license/jeffshurtliff/pydplus">
            </a>
        </td>
    </tr>
    <tr>
        <td>Issues</td>
        <td>
            <a href="https://github.com/jeffshurtliff/pydplus/issues">
                <img alt="Issues (GitHub)" src="https://img.shields.io/github/issues/jeffshurtliff/pydplus">
            </a>
        </td>
    </tr>
    <tr>
        <td>Pull Requests</td>
        <td>
            <a href="https://github.com/jeffshurtliff/pydplus/pulls">
                <img alt="Pull Requests (GitHub)" src="https://img.shields.io/github/issues-pr/jeffshurtliff/pydplus">
            </a>
        </td>
    </tr>
</table>

## Installation

> [!IMPORTANT]
> PyDPlus `2.0.0` and newer require Python `3.12+`.<br>
> PyDPlus `1.0.1` is the final release line that supports Python `3.9`.

Install from PyPI:

```sh
python -m pip install --upgrade pydplus
```

Install from source:

```sh
git clone https://github.com/jeffshurtliff/pydplus.git
cd pydplus
poetry install
```

## Changelog
The changelog can be found in the [documentation](https://pydplus.readthedocs.io/en/latest/CHANGELOG.html).

## Usage
PyDPlus is designed for Python-based administration workflows in RSA ID Plus tenants, including:

- user lifecycle automation (lookup, disable, mark for deletion)
- admin reporting and audit integrations
- helpdesk and identity-operations scripting

### 1) Import the package

```python
from pydplus import PyDPlus, constants as const
```

### 2) Instantiate the client (OAuth example)

`pydplus.PyDPlus` supports both OAuth and Legacy credentials. OAuth (Private Key JWT) is recommended for new usage.

```python
from pydplus import PyDPlus, constants as const

OAUTH_SCOPE = [
    const.OAUTH_SCOPES.USER_READ,
    const.OAUTH_SCOPES.USER_MANAGE,
]

pydp = PyDPlus(
    connection_type="oauth",
    base_admin_url="https://example-company.access.securid.com",
    oauth_client_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    oauth_private_key="/path/to/oauth-private-key.jwk",
    oauth_scope=OAUTH_SCOPE,
)
```

Legacy API authentication is also supported. See the 
[Authentication](https://pydplus.readthedocs.io/en/stable/guides/authentication.html) guide for both patterns.

### 3) Define OAuth scopes (three practical options)

1. Configure default scope permissions in the OAuth client settings in the RSA Cloud Administration Console.
2. Define scopes explicitly in your code/helper/env configuration (manual string values or constants like
   `const.OAUTH_SCOPES.USER_READ` grouped in an `OAUTH_SCOPE` variable).
3. Use scope presets to apply scope bundles (for example `user_read_only` or `group_read_only`) via
   `oauth_scope_preset` (argument), `connection.oauth.scope_preset` (helper setting), or `PYDPLUS_OAUTH_SCOPE_PRESET`
   (environment variable).

In PyDPlus, keep `oauth_scope` explicitly defined (directly, helper file, or environment variable) so token requests
remain deterministic and validated.

Presets are additive and merged with explicit scopes:

```python
pydp = PyDPlus(
    connection_type="oauth",
    base_admin_url="https://example-company.access.securid.com",
    oauth_client_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    oauth_private_key="/path/to/oauth-private-key.jwk",
    oauth_scope=const.OAUTH_SCOPES.USER_MANAGE,
    oauth_scope_preset=("user_read_only", "group_read_only"),
)
```

### 4) Run an API operation

```python
user_id = pydp.users.get_user_id(email="john.doe@example.com")
response = pydp.users.disable_user(user_id=user_id)
```

For deeper coverage, see:

- Quickstart: <https://pydplus.readthedocs.io/en/stable/getting-started/quickstart.html>
- Authentication guide: <https://pydplus.readthedocs.io/en/stable/guides/authentication.html>
- Client reference: <https://pydplus.readthedocs.io/en/stable/reference/client.html>

## Documentation
The documentation is located here: [https://pydplus.readthedocs.io/en/stable/](https://pydplus.readthedocs.io/en/stable/)

## License
[MIT License](https://github.com/jeffshurtliff/pydplus/blob/main/LICENSE)

## Reporting Issues
Issues can be reported within the [GitHub repository](https://github.com/jeffshurtliff/pydplus/issues).

## Contributing
Contributions are welcome and appreciated, including bug fixes, documentation improvements, tests, and feature work.
For full contribution requirements and workflows, please see
[CONTRIBUTING.md](https://github.com/jeffshurtliff/pydplus/blob/main/CONTRIBUTING.md).

### Development Quality Checks
This repository uses [Ruff](https://docs.astral.sh/ruff/) for linting, import sorting, and formatting.
The standard maximum line length for this package is `130` characters.

Line-length exceptions should be rare and limited to comments or special cases where wrapping harms readability.
When an exception is required, use a targeted per-line `# noqa: E501` comment.

```sh
poetry run ruff check .
poetry run ruff check . --fix
poetry run ruff format .
poetry run ruff format . --check
```

These checks are enforced in CI via `.github/workflows/ci.yml`.

## Donations
If you would like to donate to this project then you can do so using [this PayPal link](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=XDZ8M6UV6EFK6&item_name=PyDPlus+Python+SDK&currency_code=USD).

## Disclaimer
This package is considered unofficial and is in no way endorsed or supported by [RSA Security LLC](https://rsa.com).

