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

Uploaded Python 3

File details

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

File metadata

  • Download URL: py_identity_model-2.19.1.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.1.tar.gz
Algorithm Hash digest
SHA256 121b37df0a7307676274906d1aa7f256d8fdb4d5f9fa2380511f8089cbade4c8
MD5 5e2364c7c4277905c2b39e0766a1cfd6
BLAKE2b-256 7efbe11bc02fd430d3547657d41c09410fcf73c560206f25c98c1bb721cbbe91

See more details on using hashes here.

File details

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

File metadata

  • Download URL: py_identity_model-2.19.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 63755eb8ad6ad135fc6e123befe6eda4b32c4de2dd598cc15bdab6b349dcd908
MD5 1036e8bbb7e29c062e349f8cc7fbe136
BLAKE2b-256 4726b2a6aa69558f56650eac097010555f5678dacf4a19eb6a716947ffbaa461

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