Skip to main content

OAuth2.0 and OpenID Connect Client Library

Project description

py-identity-model

Build License

Production-grade OIDC/OAuth2.0 client library for Python. Dual sync/async API with comprehensive RFC coverage. Inspired by Duende.IdentityModel.

Installation

pip install py-identity-model

Or with uv:

uv add py-identity-model

Requirements: Python 3.12+

Features

Protocol Support

Feature RFC/Spec Status
OpenID Connect Discovery 1.0 OIDC Discovery Done
JSON Web Key Sets RFC 7517 Done
JWT Validation RFC 7519 Done
Client Credentials Grant RFC 6749 Done
Authorization Code + PKCE RFC 7636 Done
Refresh Token Grant RFC 6749 Done
Token Introspection RFC 7662 Done
Token Revocation RFC 7009 Done
Device Authorization RFC 8628 Done
Token Exchange RFC 8693 Done
DPoP RFC 9449 Done
Pushed Authorization Requests RFC 9126 Done
JWT Secured Authorization Request RFC 9101 Done
FAPI 2.0 Security Profile FAPI 2.0 Done
UserInfo Endpoint OIDC Core Done
OAuth Callback State Validation RFC 6749 Done
Policy-Based Configuration Done

Architecture

  • Dual API: Synchronous (py_identity_model) and asynchronous (py_identity_model.aio)
  • Thread-safe: Sync uses thread-local HTTP clients; async uses singleton with lock protection
  • Modular: Shared business logic in core/, thin sync/async HTTP wrappers
  • Connection pooling: httpx-based with configurable timeouts and retry logic

Quick Start

Discovery

from py_identity_model import DiscoveryDocumentRequest, get_discovery_document

response = get_discovery_document(DiscoveryDocumentRequest(address="https://issuer.example.com"))
if response.is_successful:
    print(f"Token Endpoint: {response.token_endpoint}")

Token Validation

from py_identity_model import TokenValidationConfig, validate_token

config = TokenValidationConfig(perform_disco=True, audience="my-api")
claims = validate_token(jwt=token, token_validation_config=config, disco_doc_address="https://issuer.example.com")

Async API

from py_identity_model.aio import get_discovery_document, validate_token
from py_identity_model import DiscoveryDocumentRequest

response = await get_discovery_document(DiscoveryDocumentRequest(address=url))

Client Credentials

from py_identity_model import ClientCredentialsTokenRequest, request_client_credentials_token

token = request_client_credentials_token(ClientCredentialsTokenRequest(
    client_id="my-client", client_secret="secret",
    address=token_endpoint, scope="api"
))

Examples

Each protocol feature has a standalone example in examples/:

Example Feature
sync_examples.py Discovery, JWKS, token validation, client credentials
async_examples.py Async versions of all core operations
auth_code_pkce_example.py Authorization Code + PKCE flow
introspection_example.py Token introspection (RFC 7662)
revocation_example.py Token revocation (RFC 7009)
dpop_example.py DPoP proof creation (RFC 9449)
par_example.py Pushed Authorization Requests (RFC 9126)
jar_example.py JWT Secured Authorization Request (RFC 9101)
fapi_example.py FAPI 2.0 Security Profile
device_auth_example.py Device Authorization Grant (RFC 8628)
token_exchange_example.py Token Exchange (RFC 8693)

Framework Integration

py-identity-model is framework-agnostic — call validate_token (or py_identity_model.aio.validate_token) from any Python framework's auth layer. For FastAPI, examples/fastapi/ ships a complete, production-shaped integration you can copy into your own project:

  • TokenValidationMiddleware — Bearer token extraction, JWKS-cached validation, configurable excluded paths, pluggable custom-claim validators
  • Dependency injectionCurrentUser, Claims, Token annotated types for typed access to the authenticated principal from route handlers
  • Authorization guardsrequire_claim(type, value) and require_scope(scope) factories that plug into Depends(...) to enforce RBAC/ABAC at the route level
  • Token refresh helper — Proactive refresh of expiring access tokens for service-to-service flows
from fastapi import Depends, FastAPI

from .middleware import TokenValidationMiddleware
from .dependencies import CurrentUser, require_scope

app = FastAPI()

app.add_middleware(
    TokenValidationMiddleware,
    discovery_url="https://issuer.example.com/.well-known/openid-configuration",
    audience="my-api",
    excluded_paths=["/health", "/docs", "/openapi.json"],
)


@app.get("/me")
async def me(user: CurrentUser) -> dict:
    return {"sub": user.identity.name}


@app.get("/admin", dependencies=[Depends(require_scope("api.admin"))])
async def admin() -> dict:
    return {"status": "ok"}
Integration Path Highlights
FastAPI examples/fastapi/ Middleware, DI, authorization guards, token refresh
Descope (FastAPI) examples/descope/ Extends the FastAPI base with Descope-specific issuer/tenant handling

Configuration

Environment Variables

Variable Default Description
HTTP_TIMEOUT 30.0 Request timeout (seconds)
HTTP_RETRY_COUNT 3 Retries for rate-limited requests
HTTP_RETRY_BASE_DELAY 1.0 Base delay for exponential backoff
SSL_CERT_FILE CA bundle path (recommended)
REQUESTS_CA_BUNDLE CA bundle path (legacy compat)

Documentation

Full docs: jamescrowley321.github.io/py-identity-model

License

Apache License 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_identity_model-2.19.3.tar.gz (81.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_identity_model-2.19.3-py3-none-any.whl (115.0 kB view details)

Uploaded Python 3

File details

Details for the file py_identity_model-2.19.3.tar.gz.

File metadata

  • Download URL: py_identity_model-2.19.3.tar.gz
  • Upload date:
  • Size: 81.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for py_identity_model-2.19.3.tar.gz
Algorithm Hash digest
SHA256 6211c27ff5b6ad1d82fda6aa64d22811e6dda86a202cd666de9c8a16f41013d8
MD5 59882c305a124cccc512e0b73d441e77
BLAKE2b-256 236868efd390698fd1a53060d9fa65ac7a0208c246f5f49c559a3c5bb129cada

See more details on using hashes here.

File details

Details for the file py_identity_model-2.19.3-py3-none-any.whl.

File metadata

  • Download URL: py_identity_model-2.19.3-py3-none-any.whl
  • Upload date:
  • Size: 115.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for py_identity_model-2.19.3-py3-none-any.whl
Algorithm Hash digest
SHA256 317afe148c8f82a0d45bd262d228f76242636ee14475cad76dcb5251a9223b24
MD5 511e5efa4363e4d7518c89a3b7fa4d34
BLAKE2b-256 1fdb25606f7685d3821636aac5ed9453fa3986575236f94f1d974810aa0d33b2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page