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.11.tar.gz (84.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.11-py3-none-any.whl (117.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: py_identity_model-2.19.11.tar.gz
  • Upload date:
  • Size: 84.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","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.11.tar.gz
Algorithm Hash digest
SHA256 26d88e56321c453a7ea843c72ff1547948f4d7633772930a8104186cd5e292ac
MD5 7ab5ed1faed11d9d5b428bd352c6d007
BLAKE2b-256 ff880d261b480cf5feb28e15b59aedb00f5123f158955f98941cc2cd3679c49f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: py_identity_model-2.19.11-py3-none-any.whl
  • Upload date:
  • Size: 117.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","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.11-py3-none-any.whl
Algorithm Hash digest
SHA256 6d1142972d01963c2d6294007d94a64bcfbcc9965ed06e1bc32c0d32f365985f
MD5 c41f008cc3ccb20de2f7530558f457b2
BLAKE2b-256 f2b30c55ce469a53cebabc886afbe7ff9dcedbe83760244d171a72ebdfbb177e

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