Zero-setup JWT authentication for FastAPI and Flask
Project description
softauth
Zero-setup JWT authentication for FastAPI, Flask, and Django.
The problem
Every new project requires the same boilerplate:
- JWT helpers (create / decode / verify)
- Password hashing
- Auth routes (
/register,/login,/refresh,/me) - Middleware that parses the token on every request
- Role-based access control decorators or dependencies
- User model + database table
softauth eliminates all of it.
Installation
# FastAPI
pip install "softauth[fastapi]"
# Flask
pip install "softauth[flask]"
# Both
pip install "softauth[fastapi,flask]"
Quick start — FastAPI
from fastapi import FastAPI, Depends
from softauth import SoftAuth
auth = SoftAuth(secret_key="your-secret", framework="fastapi")
app = FastAPI()
auth.init_app(app) # mounts /auth/* routes + JWT middleware
auth.init_db() # creates the users table
@app.get("/profile")
def profile(user=Depends(auth.current_user)):
return user.to_dict()
@app.get("/admin")
def admin(user=Depends(auth.current_admin)):
return {"msg": f"hello admin {user.email}"}
@app.get("/editor")
def editor(user=Depends(auth.require_role("editor"))):
return {"msg": f"hello editor {user.email}"}
Visit /docs — Swagger UI shows all auth routes and lets you log in directly.
Quick start — Flask
from flask import Flask, g, jsonify
from softauth import SoftAuth
auth = SoftAuth(secret_key="your-secret", framework="flask")
app = Flask(__name__)
auth.init_app(app) # registers /auth/* blueprint + before_request hook
auth.init_db() # creates the users table
@app.route("/profile")
@auth.login_required
def profile():
return jsonify(g.user.to_dict())
@app.route("/admin")
@auth.admin_required
def admin():
return jsonify({"msg": f"hello admin {g.user.email}"})
@app.route("/editor")
@auth.require_role("editor")
def editor():
return jsonify({"msg": f"hello editor {g.user.email}"})
Auto-generated routes
| Method | Path | Description |
|---|---|---|
| POST | /auth/register |
Create a new account |
| POST | /auth/login |
Exchange credentials for a token pair |
| POST | /auth/refresh |
Exchange a refresh token for access token |
| GET | /auth/me |
Current user's profile |
| POST | /auth/logout |
Instruct client to discard tokens |
Configuration
auth = SoftAuth(
secret_key="your-secret", # required
framework="fastapi", # "fastapi" | "flask" | None (custom adapter)
algorithm="HS256", # JWT algorithm
access_expiry_minutes=15, # access token lifetime
refresh_expiry_days=7, # refresh token lifetime
database_url="sqlite:///auth.db", # any SQLAlchemy URL
auth_prefix="/auth", # route prefix
enable_refresh_tokens=True,
)
Environment variables
| Variable | Config field |
|---|---|
SOFTAUTH_SECRET |
secret_key |
SOFTAUTH_DB_URL |
database_url |
SOFTAUTH_ALGORITHM |
algorithm |
CLI
# Scaffold project
softauth init
# Generate FastAPI boilerplate
softauth setup fastapi
# Generate Flask boilerplate
softauth setup flask
# Print a secure secret key
softauth secret
RBAC
Roles are stored on each user record. Built-in roles: user, manager, admin.
Custom roles work out of the box — register a user with any role string.
| What | FastAPI | Flask |
|---|---|---|
| Any authenticated user | Depends(auth.current_user) |
@auth.login_required |
| Admin only | Depends(auth.current_admin) |
@auth.admin_required |
| Specific role | Depends(auth.require_role("mgr")) |
@auth.require_role("mgr") |
Admin users are always allowed through require_role() checks.
Custom adapters (Django, Litestar, Quart, …)
The core is 100% framework-agnostic. Add support for any framework by
implementing BaseAdapter and calling use_adapter():
from softauth import SoftAuth
from softauth.interfaces import BaseAdapter
class DjangoAdapter(BaseAdapter):
def init_app(self, app): ...
def get_current_user_dependency(self): ...
def get_current_admin_dependency(self): ...
def get_require_role_dependency(self, role): ...
auth = SoftAuth(secret_key="...", framework=None)
auth.use_adapter(DjangoAdapter(auth, auth.config), django_app)
Extension points
These interfaces are ready for future implementations without breaking the existing API:
| Interface | Purpose |
|---|---|
BaseAdapter |
Add any framework (Django, Litestar, Quart …) |
AuthProvider |
OAuth2 / social login (Google, GitHub …) |
TokenStore |
Redis token blacklisting, audit logs |
UserStore |
Custom identity backends, multi-tenant |
Architecture
softauth/
├── core/ # SoftAuth facade, SoftAuthConfig, exceptions
├── jwt/ # JWTHandler — zero framework imports
├── security/ # PasswordHandler — zero framework imports
├── database/ # SQLAlchemy models, session, repository
├── interfaces/ # BaseAdapter, AuthProvider, TokenStore, UserStore ABCs
├── fastapi/ # FastAPIAdapter, DependencyFactory, JWTMiddleware, routes
├── flask/ # FlaskAdapter, DecoratorFactory, middleware, routes
└── cli/ # Typer CLI commands
The JWT engine (softauth.jwt) and password handler (softauth.security) import
nothing from any web framework. Adapters are loaded lazily so installing only
fastapi or only flask works without errors.
Testing
pip install -e ".[dev]"
pytest --cov=softauth
Minimum required coverage: 90 %
Versioning
This project follows Semantic Versioning. See CHANGELOG.md for the full history.
Releasing
git tag v0.2.0
git push origin v0.2.0
# GitHub Actions builds and publishes to PyPI automatically
License
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 softauth-0.1.0.tar.gz.
File metadata
- Download URL: softauth-0.1.0.tar.gz
- Upload date:
- Size: 34.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1cce0a184e4e3f94803a47e4bbf689ba397cff200a951d86209982ee95426eb8
|
|
| MD5 |
2f18c1a52af793302bd2f37d7d7d50c4
|
|
| BLAKE2b-256 |
c7c589b3ddd8814101ecacc9cfdd807b7adb411c6cdbce2e5815166a2fe73945
|
File details
Details for the file softauth-0.1.0-py3-none-any.whl.
File metadata
- Download URL: softauth-0.1.0-py3-none-any.whl
- Upload date:
- Size: 37.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd733b92401affbf2b6cbdd98f3ab25e7c797a9145b5998dec503267ad93ac8a
|
|
| MD5 |
41df1625baf035974165e2cf266d6d77
|
|
| BLAKE2b-256 |
37ce7dc48611061b300578419f9168811b40eeb6bb169a701ed2f817f56ca218
|