Skip to main content

Zero-setup JWT authentication for FastAPI and Flask

Project description

softauth

Zero-setup JWT authentication for FastAPI, Flask, and Django.

CI PyPI Python License: MIT


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

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

softauth-0.1.0.tar.gz (34.4 kB view details)

Uploaded Source

Built Distribution

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

softauth-0.1.0-py3-none-any.whl (37.5 kB view details)

Uploaded Python 3

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

Hashes for softauth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1cce0a184e4e3f94803a47e4bbf689ba397cff200a951d86209982ee95426eb8
MD5 2f18c1a52af793302bd2f37d7d7d50c4
BLAKE2b-256 c7c589b3ddd8814101ecacc9cfdd807b7adb411c6cdbce2e5815166a2fe73945

See more details on using hashes here.

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

Hashes for softauth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bd733b92401affbf2b6cbdd98f3ab25e7c797a9145b5998dec503267ad93ac8a
MD5 41df1625baf035974165e2cf266d6d77
BLAKE2b-256 37ce7dc48611061b300578419f9168811b40eeb6bb169a701ed2f817f56ca218

See more details on using hashes here.

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