Pluggable OIDC/OAuth 2.1 authentication routes and token validation.
Project description
A small, typed OpenID Connect helper for authentication and authorization.
It porvides
- a framework independent async core:
OIDCAuth - framework adapters that expose common auth endpoints
- simple
required()andoptional()helpers to protect routes
Supported frameworks
|
FastAPI |
Flask |
Quart |
|
Tornado |
Litestar |
Django |
Features
- Authorization code flow with PKCE (login and callback)
- Refresh token flow
- Device authorization flow
- Userinfo lookup
- Provider initiated logout (end session) when supported
- Bearer token validation using provider JWKS, issuer, and audience
- Optional scope checks and simple claim constraints
- Full type annotation 🏷️
Install
Pick your framework for installation:
python -m pip install py-oidc-auth[fastapi]
python -m pip install py-oidc-auth[flask]
python -m pip install py-oidc-auth[quart]
python -m pip install py-oidc-auth[tornado]
python -m pip install py-oidc-auth[litestar]
python -m pip install py-oidc-auth[django]
Import name is py_oidc_auth:
from py_oidc_auth import OIDCAuth
Concepts
Core
OIDCAuth is the framework independent client. It loads provider metadata from the
OpenID Connect discovery document, performs provider calls, and validates tokens.
Adapters
Each adapter subclasses OIDCAuth and adds:
- helpers to register the standard endpoints (router, blueprint, urlpatterns, etc.)
required()andoptional()helpers to validate bearer tokens on protected routes
Default endpoints
Adapters can expose these paths (customizable and individually disableable):
GET /auth/v2/loginGET /auth/v2/callbackPOST /auth/v2/tokenPOST /auth/v2/deviceGET /auth/v2/logoutGET /auth/v2/userinfo
Quick start
Create one auth instance at app startup:
auth = ...(
client_id="my client",
client_secret="secret",
discovery_url="https://idp.example.org/realms/demo/.well-known/openid-configuration",
scopes="openid profile email",
)
FastAPI
from typing import Optional
from fastapi import FastAPI
from py_oidc_auth import FastApiOIDCAuth
from py_oidc_auth.schema import IDToken
app = FastAPI()
auth = FastApiOIDCAuth(
client_id="my client",
client_secret="secret",
discovery_url="https://idp.example.org/realms/demo/.well-known/openid-configuration",
scopes="openid profile email",
)
app.include_router(auth.create_auth_router(prefix="/api"))
@app.get("/me")
async def me(token: IDToken = auth.required()):
return {"sub": token.sub}
@app.get("/feed")
async def feed(token: Optional[IDToken] = auth.optional()):
return {"authenticated": token is not None}
Flask
from flask import Flask
from py_oidc_auth import FlaskOIDCAuth
app = Flask(__name__)
auth = FlaskOIDCAuth(
client_id="my client",
client_secret="secret",
discovery_url="https://idp.example.org/realms/demo/.well-known/openid-configuration",
)
app.register_blueprint(auth.create_auth_blueprint(prefix="/api"))
@app.get("/protected")
@auth.required()
def protected(token):
return {"sub": token.sub}
Quart
from quart import Quart
from py_oidc_auth import QuartOIDCAuth
app = Quart(__name__)
auth = QuartOIDCAuth(
client_id="my client",
client_secret="secret",
discovery_url="https://idp.example.org/realms/demo/.well-known/openid-configuration",
)
app.register_blueprint(auth.create_auth_blueprint(prefix="/api"))
@app.get("/protected")
@auth.required()
async def protected(token):
return {"sub": token.sub}
Django
Decorator style:
from django.http import JsonResponse
from django.urls import path
from py_oidc_auth import DjangoOIDCAuth
auth = DjangoOIDCAuth(
client_id="my client",
client_secret="secret",
discovery_url="https://idp.example.org/realms/demo/.well-known/openid-configuration",
)
@auth.required()
async def protected_view(request, token):
return JsonResponse({"sub": token.sub})
urlpatterns = [
*auth.get_urlpatterns(prefix="api"),
path("protected/", protected_view),
]
Routes only:
urlpatterns = [
*auth.get_urlpatterns(prefix="api"),
]
Tornado
import tornado.web
from py_oidc_auth import TornadoOIDCAuth
auth = TornadoOIDCAuth(
client_id="my client",
client_secret="secret",
discovery_url="https://idp.example.org/realms/demo/.well-known/openid-configuration",
)
class ProtectedHandler(tornado.web.RequestHandler):
@auth.required()
async def get(self, token):
self.write({"sub": token.sub})
def make_app():
return tornado.web.Application(
auth.get_handlers(prefix="/api") + [
(r"/protected", ProtectedHandler),
]
)
Litestar
from litestar import Litestar, get
from py_oidc_auth import LitestarOIDCAuth
auth = LitestarOIDCAuth(
client_id="my client",
client_secret="secret",
discovery_url="https://idp.example.org/realms/demo/.well-known/openid-configuration",
)
@get("/protected")
@auth.required()
async def protected(token):
return {"sub": token.sub}
app = Litestar(
route_handlers=[
protected,
*auth.get_route_handlers(prefix="/api"),
]
)
Scopes and claim constraints
All adapters support:
scopes="a b c"to require scopes on a protected endpointclaims={...}to enforce simple claim constraints
Example:
@auth.required(scopes="admin", claims={"groups": ["admins"]})
def admin(token):
return {"sub": token.sub}
Contributing
See the CONTRIBUTING.md document to get involved.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_oidc_auth-2602.0.0.tar.gz.
File metadata
- Download URL: py_oidc_auth-2602.0.0.tar.gz
- Upload date:
- Size: 2.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76c42df455f761e1d2d5089eabf18a5f73071f7caf7140002269a3720f658f4e
|
|
| MD5 |
768f5de9d6e744edb67787e6358e49e9
|
|
| BLAKE2b-256 |
10633d6203c500d906f034f807f206c7c911080ce1f804dc24a43158f2a08ba9
|
File details
Details for the file py_oidc_auth-2602.0.0-py3-none-any.whl.
File metadata
- Download URL: py_oidc_auth-2602.0.0-py3-none-any.whl
- Upload date:
- Size: 37.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd6795fad7aef126c142ca6bb74fb5808ec073d9cbca5c8a9bc2e69a443ae300
|
|
| MD5 |
f57c458326e7a399ba3d25d6f445ef16
|
|
| BLAKE2b-256 |
cf0efe2ece62b0f61abe27905133c0646294441e07d1a39987a66b386322d805
|