Professional OneID integration package for FastAPI applications
Project description
fastapi-oneid
fastapi-oneid is a self-developed OneID integration package for FastAPI applications. It gives you a clean, reusable way to start the OneID authorization flow, exchange the returned code for an access token, fetch the authenticated user profile, and hand the final login step back to your own application.
The package is designed for teams that want to integrate OneID quickly without rebuilding the HTTP flow for every project.
What This Package Does
- Generates a OneID authorization URL
- Redirects users to the OneID login page
- Exchanges the returned
codefor a OneID access token - Fetches user information from OneID using the access token
- Exposes ready-to-mount FastAPI routers for web and API flows
- Lets your application finish local authentication through a callback handler
What This Package Does Not Do
- It does not create local users automatically
- It does not issue JWTs or sessions automatically
- It does not manage your database models
- It does not bypass OneID redirect URI restrictions
Your application remains responsible for mapping the OneID user to a local account and issuing your own access token or session.
Requirements
- Python
3.11+ - FastAPI
0.115+ - OneID client credentials
- A callback URL registered in your OneID client configuration
Installation
Install from PyPI:
pip install fastapi-oneid
For local development:
pip install -e .[dev]
For release tooling:
pip install -e .[release]
Configuration
The package reads configuration from environment variables.
| Variable | Required | Description |
|---|---|---|
ONE_ID_SSO_URL |
Yes | OneID authorization/token endpoint URL |
ONE_ID_CLIENT_ID |
Yes | Your OneID client identifier |
ONE_ID_CLIENT_SECRET |
Yes | Your OneID client secret |
ONE_ID_CLIENT_SCOPE |
No | Scope to send to OneID. Default: test |
ONE_ID_CLIENT_STATE |
No | State value to send to OneID. Default: testState |
Example .env:
ONE_ID_SSO_URL=https://sso.egov.uz/sso/oauth/Authorization.do
ONE_ID_CLIENT_ID=your-client-id
ONE_ID_CLIENT_SECRET=your-client-secret
ONE_ID_CLIENT_SCOPE=test
ONE_ID_CLIENT_STATE=testState
Quick Start
Create a FastAPI app and mount the provided routers.
from fastapi import FastAPI, Request
from fastapi_oneid import OneIDAuthPayload, create_api_router, create_web_router
app = FastAPI(title="My OneID Integration")
async def auth_handler(payload: OneIDAuthPayload, request: Request) -> dict:
oneid_user = payload.user
# 1. Find or create a local user
# 2. Issue your own JWT or session
# 3. Return your final login response
return {
"token": "your-project-jwt",
"user": oneid_user,
"oneid_token": payload.token,
}
app.include_router(create_web_router(handler=auth_handler))
app.include_router(create_api_router(handler=auth_handler))
Run the app:
uvicorn main:app --reload
Integration Modes
1. Web Flow
Use the built-in redirect flow when your backend receives the callback directly.
Endpoints:
GET /one-id/loginGET /one-id/access
Flow:
- User opens
/one-id/login - The package redirects the user to OneID
- OneID redirects back to
/one-id/access?code=... - The package exchanges the code and fetches the user
- Your
auth_handlerdecides how to log the user into your application
This is usually the simplest approach for server-rendered or backend-controlled login flows.
2. API Flow
Use the API flow when your frontend wants to control the browser redirect.
Endpoints:
GET /api/one-id/urlPOST /api/one-id/urlPOST /api/one-id/tokenGET /api/one-id/access
Flow:
- Frontend requests
/api/one-id/url - Backend returns a OneID authorization URL
- Frontend redirects the user to that URL
- OneID redirects to the callback URL registered for your client
- Frontend sends the returned
codeto/api/one-id/token - The package resolves the OneID user and calls your
auth_handler
Default Routes
By default, the package exposes the following endpoints:
| Method | Path | Purpose |
|---|---|---|
GET |
/one-id/login |
Redirect user to OneID |
GET |
/one-id/access |
Handle web callback and resolve user |
GET |
/api/one-id/url |
Return authorization URL |
POST |
/api/one-id/url |
Return authorization URL |
POST |
/api/one-id/token |
Exchange code and resolve user |
GET |
/api/one-id/access |
Return received callback code |
You can override the router prefix:
app.include_router(create_web_router(prefix="/auth/oneid"))
app.include_router(create_api_router(prefix="/api/auth/oneid"))
Handler Contract
Your handler receives a OneIDAuthPayload object and the current FastAPI Request.
from fastapi import Request
from fastapi_oneid import OneIDAuthPayload
async def auth_handler(payload: OneIDAuthPayload, request: Request) -> dict:
return {
"token": "your-project-jwt",
"user": payload.user,
}
OneIDAuthPayload contains:
code: the authorization code returned by OneIDredirect_url: the callback URL used in the flowtoken: the raw token payload returned by OneIDuser: the raw user payload returned by OneID
Your handler may return:
- a JSON-serializable
dict - any FastAPI
Response
Programmatic Usage
If you want to call OneID without mounting routers, use the low-level client directly.
from fastapi_oneid import OneIDClient, OneIDSettings
settings = OneIDSettings()
client = OneIDClient(settings=settings)
authorization_url = client.get_authorization_url("https://example.com/callback")
Available client methods:
get_authorization_url(redirect_url, scope=None, state=None)exchange_code(code, redirect_url)get_user_info(access_token, scope=None)resolve_auth_payload(code, redirect_url)get_user(code, redirect_url)
Example Project
A minimal runnable example is available in:
examples/basic_app/main.py
Run it locally:
cp .env.example .env
set -a
source .env
set +a
uvicorn examples.basic_app.main:app --reload --port 8010
Then open:
http://127.0.0.1:8010/api/one-id/urlhttp://127.0.0.1:8010/one-id/login
Common Problems
REDIRECT_URI_NOT_ALLOWED
OneID rejects callback URLs that are not registered for your client.
To fix it:
- Register your callback URL in OneID
- Use the exact same callback URL in the login flow
- If you use the API flow, send the same
redirect_urlagain when calling/api/one-id/token
Example:
curl "http://127.0.0.1:8010/api/one-id/url?redirect_url=http://127.0.0.1:3000/callback"
Then:
curl -X POST "http://127.0.0.1:8010/api/one-id/token" \
-H "Content-Type: application/json" \
-d '{
"code": "oneid-returned-code",
"redirect_url": "http://127.0.0.1:3000/callback"
}'
Missing Environment Variables
If startup fails with validation errors for ONE_ID_SSO_URL, ONE_ID_CLIENT_ID, or ONE_ID_CLIENT_SECRET, load your environment variables before starting the application.
Localhost Callback Problems
If OneID does not allow localhost or 127.0.0.1 callbacks for your client, use a registered domain or a development tunnel and register that callback in OneID.
Testing
Run the unit tests:
python -m pytest -v
The tests mock OneID responses. Real OneID credentials are not required for the test suite.
Release to PyPI
Build the package:
python -m build --no-isolation
Validate package metadata:
python -m twine check dist/*
Upload to TestPyPI:
python -m twine upload --repository testpypi dist/*
Upload to PyPI:
python -m twine upload dist/*
Before publishing:
- Update
versioninpyproject.toml - Run the test suite
- Build and check the distribution
- Upload to TestPyPI before uploading to PyPI
Recommended verification after upload:
python3 -m venv /tmp/fastapi-oneid-check
source /tmp/fastapi-oneid-check/bin/activate
pip install fastapi-oneid
python -c "import fastapi_oneid; print('install ok')"
License
MIT
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 fastapi_oneid-0.1.0.tar.gz.
File metadata
- Download URL: fastapi_oneid-0.1.0.tar.gz
- Upload date:
- Size: 9.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9673618422cf52ea85098b638b257b617cde1026f09830e7c4d967bbec6a89f
|
|
| MD5 |
a9ee1092717b8ac2991c05be2f29779f
|
|
| BLAKE2b-256 |
14f2126d8a5d5874913c8a300112c43fdec990627e1f73a968604e5438333b98
|
Provenance
The following attestation bundles were made for fastapi_oneid-0.1.0.tar.gz:
Publisher:
workflow.yml on lochinbekdev/fastapi-oneid
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_oneid-0.1.0.tar.gz -
Subject digest:
a9673618422cf52ea85098b638b257b617cde1026f09830e7c4d967bbec6a89f - Sigstore transparency entry: 1393455111
- Sigstore integration time:
-
Permalink:
lochinbekdev/fastapi-oneid@730665e93a0977f2e549d6cbe4b290a825afcbe1 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/lochinbekdev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@730665e93a0977f2e549d6cbe4b290a825afcbe1 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file fastapi_oneid-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fastapi_oneid-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac8e699314c3de420d373aedbcdb917d39e611e382efd3ddeee4a8a2cc382ee7
|
|
| MD5 |
ba05374a1963dfcba6dffa296e718e83
|
|
| BLAKE2b-256 |
4df5c04e4c99031a7a687c73c7d88a3409197003f95906a5718cbe4762bae5bc
|
Provenance
The following attestation bundles were made for fastapi_oneid-0.1.0-py3-none-any.whl:
Publisher:
workflow.yml on lochinbekdev/fastapi-oneid
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_oneid-0.1.0-py3-none-any.whl -
Subject digest:
ac8e699314c3de420d373aedbcdb917d39e611e382efd3ddeee4a8a2cc382ee7 - Sigstore transparency entry: 1393455116
- Sigstore integration time:
-
Permalink:
lochinbekdev/fastapi-oneid@730665e93a0977f2e549d6cbe4b290a825afcbe1 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/lochinbekdev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@730665e93a0977f2e549d6cbe4b290a825afcbe1 -
Trigger Event:
workflow_dispatch
-
Statement type: