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.9.tar.gz (84.2 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.9-py3-none-any.whl (117.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: py_identity_model-2.19.9.tar.gz
  • Upload date:
  • Size: 84.2 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.9.tar.gz
Algorithm Hash digest
SHA256 f677f7145f2d8b45ed32275a67bce082e0f5749dcf4beb9818ae317da4da0358
MD5 8fe65ef6b536b73eb28a43efc7bf11dc
BLAKE2b-256 c8ef99da118351f5be3b1e78bc5444e591cc44ade456e934bc7e199da7fda590

See more details on using hashes here.

File details

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

File metadata

  • Download URL: py_identity_model-2.19.9-py3-none-any.whl
  • Upload date:
  • Size: 117.5 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.9-py3-none-any.whl
Algorithm Hash digest
SHA256 5ee061c4c7003987fe206a62d9453d85fc126bfa6190521cc967681ba893b949
MD5 3d0d72c2095032f3a064bb86232e8709
BLAKE2b-256 805759e1711e553d95184421049dd82ec5c3647356d35fb3a99b9f17fc0f5b6e

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