Skip to main content

Production-grade, async-native authentication and authorization library for FastAPI

Project description

fastapi-fullauth

PyPI Python CI License: MIT

Async auth library for FastAPI. Handles JWT tokens, refresh rotation, password hashing, email verification, and role-based access out of the box.

Install

pip install fastapi-fullauth
# with an ORM adapter:
pip install fastapi-fullauth[sqlmodel]
pip install fastapi-fullauth[sqlalchemy]
# with redis for token blacklisting:
pip install fastapi-fullauth[sqlmodel,redis]

Quick start

from fastapi import FastAPI
from fastapi_fullauth import FullAuth
from fastapi_fullauth.adapters.memory import InMemoryAdapter

app = FastAPI()

fullauth = FullAuth(
    secret_key="your-secret-key",
    adapter=InMemoryAdapter(),
)
fullauth.init_app(app)

This gives you /auth/me, /auth/register, /auth/login, /auth/logout, /auth/refresh, /auth/change-password, /auth/password-reset/*, /auth/verify-email/*, and admin role management endpoints — all under /api/v1 by default.

Omit secret_key in dev and a random one is generated (tokens won't survive restarts).

Custom user fields

Just define your model — schemas are auto-derived:

from fastapi_fullauth.adapters.sqlmodel import UserBase, Role, UserRoleLink, RefreshTokenRecord, SQLModelAdapter
from sqlmodel import Field, Relationship

class MyUser(UserBase, table=True):
    __tablename__ = "fullauth_users"

    display_name: str = Field(default="", max_length=100)
    phone: str = Field(default="", max_length=20)

    roles: list[Role] = Relationship(link_model=UserRoleLink)
    refresh_tokens: list[RefreshTokenRecord] = Relationship()

fullauth = FullAuth(
    secret_key="...",
    adapter=SQLModelAdapter(session_maker, user_model=MyUser),
)

No need to create separate schema classes or subclass the adapter. Registration and response schemas pick up display_name and phone automatically. You can still pass explicit user_schema / create_user_schema if you want full control.

Protected routes

Use the Annotated types for clean route signatures:

from fastapi_fullauth.dependencies import CurrentUser, VerifiedUser, SuperUser, require_role

@app.get("/profile")
async def profile(user: CurrentUser):
    return user

@app.get("/dashboard")
async def dashboard(user: VerifiedUser):
    # only email-verified users
    return {"email": user.email}

@app.delete("/admin/users/{id}")
async def delete_user(user: SuperUser):
    # only superusers
    ...

# or use require_role for custom roles
from fastapi import Depends
from fastapi_fullauth.dependencies import require_role

@app.get("/editor")
async def editor_panel(user=Depends(require_role("editor"))):
    ...

Configuration

Pass inline kwargs or a full config object:

# inline
fullauth = FullAuth(
    secret_key="...",
    adapter=adapter,
    api_prefix="/api/v2",
    access_token_expire_minutes=60,
)

# or use FullAuthConfig for everything
from fastapi_fullauth import FullAuthConfig
fullauth = FullAuth(config=FullAuthConfig(SECRET_KEY="..."), adapter=adapter)

Config also reads env vars with FULLAUTH_ prefix.

Redis blacklist

fullauth = FullAuth(
    secret_key="...",
    adapter=adapter,
    blacklist_backend="redis",
    redis_url="redis://localhost:6379/0",
)

Refresh token security

Refresh tokens are stored in DB with family tracking. If a revoked token is replayed (possible theft), the entire token family gets revoked. Disable rotation with REFRESH_TOKEN_ROTATION=False.

Event hooks

async def welcome(user):
    await send_email(user.email, "Welcome!")

fullauth.hooks.on("after_register", welcome)

Events: after_register, after_login, after_logout, after_password_change, after_password_reset, after_email_verify, send_verification_email, send_password_reset_email

Custom token claims

Embed app-specific data into JWTs (available in payload.extra):

async def add_claims(user):
    return {"tenant_id": "acme", "plan": "pro"}

fullauth = FullAuth(
    secret_key="...",
    adapter=adapter,
    on_create_token_claims=add_claims,
)

Reserved keys (sub, exp, iat, jti, type, roles, extra, family_id) are rejected to prevent accidental overwrites.

Password hashing

Argon2id by default. Switch to bcrypt via config:

fullauth = FullAuth(
    secret_key="...",
    adapter=adapter,
    password_hash_algorithm="bcrypt",  # requires: pip install bcrypt
)

When switching algorithms, existing users are transparently rehashed on their next login.

Route control

fullauth = FullAuth(
    secret_key="...",
    adapter=adapter,
    enabled_routes=["login", "logout", "refresh"],
)

Middleware

SecurityHeaders, CSRF, and rate limiting are auto-wired from config flags. Pass auto_middleware=False to init_app() to handle it yourself.

Auth rate limiting

Login, register, and password-reset have per-IP rate limits enabled by default (5/3/3 per minute). Configure via AUTH_RATE_LIMIT_* settings.

Login field

By default, login uses email. Change it to any field on your user model:

# username login: POST /login {"username": "john", "password": "..."}
fullauth = FullAuth(secret_key="...", adapter=adapter, login_field="username")

# phone login: POST /login {"phone": "+1234567890", "password": "..."}
fullauth = FullAuth(secret_key="...", adapter=adapter, login_field="phone")

The Swagger UI and request body update automatically. The adapter looks up users by that field.

Development

git clone https://github.com/mdfarhankc/fastapi-fullauth.git
cd fastapi-fullauth
uv sync --dev --extra sqlalchemy --extra sqlmodel
uv run pytest tests/ -v

# run examples
uv run uvicorn examples.memory_app.main:app --reload
uv run uvicorn examples.sqlmodel_app.main:app --reload

License

MIT

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

fastapi_fullauth-0.3.0.tar.gz (95.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_fullauth-0.3.0-py3-none-any.whl (41.7 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_fullauth-0.3.0.tar.gz.

File metadata

  • Download URL: fastapi_fullauth-0.3.0.tar.gz
  • Upload date:
  • Size: 95.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastapi_fullauth-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b15c937a748a8cf1e240ef1ee1f877fb7f259728d108d839c842e596d665494f
MD5 13678c0639077f8d4ce7f3c738fb6250
BLAKE2b-256 ce19940d44a92c06ad71a7ef457af5f1e1803c5624cf75110e442450061410c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_fullauth-0.3.0.tar.gz:

Publisher: publish.yml on mdfarhankc/fastapi-fullauth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastapi_fullauth-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_fullauth-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8f7cc5b83d459b744364125e26a60fcff16e2723d821f2304df5878a750fcf75
MD5 94d2af9e7a102e15035bb3b2936768f8
BLAKE2b-256 28cf34289e5d71e323f769571f457d9dd4cb25e7609af1b478cca679c29ebb08

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_fullauth-0.3.0-py3-none-any.whl:

Publisher: publish.yml on mdfarhankc/fastapi-fullauth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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