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.2.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.2-py3-none-any.whl (115.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: py_identity_model-2.19.2.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.2.tar.gz
Algorithm Hash digest
SHA256 8a6a132c1557675b29c24efd56436fa2473d2b8b05073240f963f2f0f385ad15
MD5 df861fe6b65b42b8a89cbf1a68e5c013
BLAKE2b-256 04061846fdafe3beb9ae7946f0c82a7403d65ff8305bca1c5164455cbece3f14

See more details on using hashes here.

File details

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

File metadata

  • Download URL: py_identity_model-2.19.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e0b82e727a4bb02bc6be27337441129d75c3e45d4c994e36408ee0e0b6ad1f8b
MD5 eb60e6377e44f71b7b669d957f39e121
BLAKE2b-256 166cb9069f3e154cb53381440cb77534e641371d5012e1ea181751b43d9bc38e

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