Small helpers for FastAPI: JWT header auth, JSON responses, exception handlers, and Pydantic query types.
Project description
approck-fastapi-utils
Small utilities for FastAPI services: JWT payload decoding from headers, standardized JSON responses, reusable exception handlers, a Pydantic-friendly comma-separated list type, and optional SQLAlchemy error handlers.
Python: 3.10+
Install
From PyPI:
uv add approck-fastapi-utils
Or with pip:
pip install approck-fastapi-utils
Optional SQLAlchemy handlers:
uv add "approck-fastapi-utils[sqlalchemy]"
What is included
| Module | Purpose |
|---|---|
approck_fastapi_utils |
Public re-exports of the most common symbols |
approck_fastapi_utils.auth |
ensure_current_user, optional_current_user, ensure_current_superuser, JwtPayload |
approck_fastapi_utils.jwt |
encode_payload, decode_payload, get_token_from_header |
approck_fastapi_utils.exceptions |
CustomException hierarchy with HTTP status codes |
approck_fastapi_utils.exception_handlers |
Handlers and register_exception_handlers(profile=...) |
approck_fastapi_utils.responses |
JSON responses and OpenAPI schema helpers |
approck_fastapi_utils.response |
Prebuilt 404 response schema |
approck_fastapi_utils.types |
CommaSeparatedList for query parameters |
approck_fastapi_utils.testing |
JWT/auth helpers for pytest |
approck_fastapi_utils.gateway |
build_gateway_headers for proxy routes |
approck_fastapi_utils.sqlalchemy.exception_handlers |
Handlers for DBAPIError and NoResultFound (requires the sqlalchemy extra) |
Usage
Register exception handlers
Use a preset instead of wiring handlers manually:
from fastapi import FastAPI
from approck_fastapi_utils import register_exception_handlers
app = FastAPI()
register_exception_handlers(app, profile="api")
Profiles:
| Profile | Handlers |
|---|---|
minimal |
HTTPException, CustomException |
api |
minimal + RequestValidationError, NoResultFound |
internal |
api + DBAPIError (with optional database_sanitize=True) |
CustomException and HTTP status codes
Built-in exceptions map to HTTP codes automatically. Subclasses can set status_code on the class or pass it to __init__:
from approck_fastapi_utils import Conflict, CustomException, NotFound
class OrderAlreadyPaid(CustomException):
status_code = 409
raise Conflict("already exists") # -> 409
raise NotFound("missing") # -> 404
raise CustomException("bad", status_code=418)
Error body contract: {"successful": false, "code": "...", "detail": "..."}.
JWT payload header
ensure_current_user reads X-JWT-Payload (URL-safe base64 JSON). Invalid payloads raise Unauthorized (401).
from fastapi import APIRouter, Depends
from approck_fastapi_utils import ensure_current_user, optional_current_user
from approck_fastapi_utils.responses import SuccessfulResponse
router = APIRouter()
@router.get("/me")
async def read_me(payload: dict = Depends(ensure_current_user)):
return SuccessfulResponse()
@router.get("/public")
async def public(payload: dict | None = Depends(optional_current_user())):
...
JWT encode/decode
from approck_fastapi_utils import decode_payload, encode_payload
payload = {"user_id": 1, "is_superuser": False}
encoded = encode_payload(payload)
claims = decode_payload(encoded) # returns None on invalid input
Testing helpers
from approck_fastapi_utils.testing import auth_headers, override_current_user
headers = auth_headers(user_id=42, is_superuser=True)
override_current_user(app, user_id=42)
Standard JSON responses and OpenAPI examples
from approck_fastapi_utils import HTTP_404_NOT_FOUND, SuccessfulResponse, custom_exception_response_schema, error_response_schema
from approck_fastapi_utils.exceptions import NotFound
@router.get(
"/health",
responses={
**SuccessfulResponse.schema(),
**error_response_schema(400, "Bad request"),
**custom_exception_response_schema(NotFound),
**HTTP_404_NOT_FOUND,
},
)
async def health():
return SuccessfulResponse()
Comma-separated query lists
CommaSeparatedList[T] accepts ?ids=1,2,3. Whitespace is trimmed, empty string yields [].
from typing import Annotated
from fastapi import Query
from approck_fastapi_utils import CommaSeparatedList
ids: Annotated[CommaSeparatedList[int], Query(description="Example: 1,2,3")]
Gateway/proxy headers
from approck_fastapi_utils import build_gateway_headers
headers = build_gateway_headers(
authorization=request.headers.get("Authorization"),
x_jwt_payload=request.headers.get("X-JWT-Payload"),
)
Breaking changes in 0.2.0
- Invalid
X-JWT-Payloadinensure_current_usernow raisesUnauthorized(401) instead ofForbidden(403). decode_payloadreturnsNoneinstead of raising on invalid input.- Header alias is explicitly
X-JWT-Payload.
Development
This repository uses uv.
uv sync --group dev --extra sqlalchemy
uv run ruff check .
uv run ruff format --check .
uv run mypy approck_fastapi_utils
uv run pytest
License
MIT — see LICENSE.
Contributing
Issues and pull requests are welcome. Please run the checks above before submitting a change.
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 approck_fastapi_utils-0.2.0.tar.gz.
File metadata
- Download URL: approck_fastapi_utils-0.2.0.tar.gz
- Upload date:
- Size: 9.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
712ab9436ac83b5c42f0860d7bdabd7c3b91505c56c1978c0e3d2fac8900d885
|
|
| MD5 |
7de54f7d649b695081ad92b3c94f33f6
|
|
| BLAKE2b-256 |
6d089055dab271e7bd54c1c88f73e6115dcbb94ae1e62ac52259dc62f109dec2
|
File details
Details for the file approck_fastapi_utils-0.2.0-py3-none-any.whl.
File metadata
- Download URL: approck_fastapi_utils-0.2.0-py3-none-any.whl
- Upload date:
- Size: 13.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ce6d9b720cdae68ece6db084bab52f36ee0ffb2ec8b32d63a97ff0146bc4905
|
|
| MD5 |
836121b01a7fd02b3d906b6bb3539eb0
|
|
| BLAKE2b-256 |
4c6873fe1615c888f6ac84566225735131d34f5595bbc1695023fd1650293888
|