Simple email/password authentication for Django, FastAPI, and Flask
Project description
auth101
Simple email/password authentication for Django, FastAPI, and Flask.
Configure once, mount anywhere. auth101 handles password hashing (Argon2), JWT tokens, and user storage so you can add authentication to any Python web app in minutes.
Features
- Email/password sign-up, sign-in, sign-out, and session verification
- Secure password hashing with Argon2 (bcrypt fallback)
- JWT token generation and verification
- Built-in framework integrations for FastAPI, Flask, and Django
- Pluggable storage backends: in-memory, SQLAlchemy, or Django ORM
Installation
pip install auth101
With extras for your framework and database:
pip install auth101[fastapi] # FastAPI + Pydantic
pip install auth101[flask] # Flask
pip install auth101[django] # Django
pip install auth101[sqlalchemy] # SQLAlchemy (any SQL database)
pip install auth101[all] # Everything
Quick Start
from auth101 import Auth101
auth = Auth101(secret="change-me-in-production")
# Sign up
result = auth.sign_up("alice@example.com", "s3cr3t")
# {"user": {"id": "...", "email": "alice@example.com", "is_active": true}, "token": "..."}
# Sign in
result = auth.sign_in("alice@example.com", "s3cr3t")
# {"user": {...}, "token": "..."}
# Get session from token
session = auth.get_session(result["token"])
# {"user": {"id": "...", "email": "alice@example.com", "is_active": true}}
# Sign out (validates the token; client discards it)
auth.sign_out(result["token"])
# {"success": true}
Configuration
auth = Auth101(
secret="your-secret-key", # Required — used to sign JWT tokens
db_url="sqlite:///auth.db", # SQLAlchemy database URL (optional)
django_model=AuthUser, # Django model class (optional)
token_expires_in=60 * 24 * 7, # Token lifetime in minutes (default: 7 days)
)
| Parameter | Description |
|---|---|
secret |
Required. Secret key for signing JWT tokens. |
db_url |
SQLAlchemy connection string (e.g. "postgresql://user:pass@localhost/db"). Creates tables automatically. |
django_model |
Django model class with id, email, password_hash, is_active fields. |
token_expires_in |
Token expiration in minutes. Default: 10080 (7 days). |
Note: Provide at most one of
db_urlordjango_model. If neither is given, an in-memory store is used (great for tests and demos).
Core API
All methods return plain dicts, so they work with any framework or without one.
auth.sign_up(email, password)
Register a new user. Returns {"user": {...}, "token": "..."} on success.
auth.sign_in(email, password)
Authenticate an existing user. Returns {"user": {...}, "token": "..."} on success.
auth.sign_out(token)
Validate a token and acknowledge sign-out. Returns {"success": True}. The client is responsible for discarding the token (JWT is stateless).
auth.get_session(token)
Return the user associated with a token. Returns {"user": {...}} on success.
auth.verify_token(token)
Verify a bearer token and return the corresponding User object, or None.
Error Responses
On failure, methods return {"error": {"message": "...", "code": "..."}} with one of these codes:
| Code | Meaning |
|---|---|
VALIDATION_ERROR |
Missing or invalid email/password |
USER_EXISTS |
Email already registered |
INVALID_CREDENTIALS |
Wrong email or password |
INVALID_TOKEN |
Token is malformed or expired |
UNAUTHORIZED |
No valid token provided |
USER_NOT_FOUND |
Token valid but user no longer exists |
Framework Integrations
FastAPI
pip install auth101[fastapi] sqlalchemy
from fastapi import Depends, FastAPI
from auth101 import Auth101
auth = Auth101(
secret="change-me-in-production",
db_url="sqlite:///auth.db",
)
app = FastAPI()
# Mount auth endpoints: POST /auth/sign-up/email, /auth/sign-in/email,
# POST /auth/sign-out, GET /auth/session
app.include_router(auth.fastapi_router(), prefix="/auth", tags=["auth"])
# Dependency that resolves to the authenticated User or raises 401
CurrentUser = auth.fastapi_current_user()
@app.get("/me")
async def me(user=Depends(CurrentUser)):
return {"id": user.id, "email": user.email}
Flask
pip install auth101[flask] sqlalchemy
from flask import Flask, g, jsonify
from auth101 import Auth101
auth = Auth101(
secret="change-me-in-production",
db_url="sqlite:///auth.db",
)
app = Flask(__name__)
# Mount auth endpoints under /auth
app.register_blueprint(auth.flask_blueprint(), url_prefix="/auth")
# Decorator that sets g.auth_user or returns 401
login_required = auth.flask_login_required()
@app.get("/me")
@login_required
def me():
return jsonify({"id": g.auth_user.id, "email": g.auth_user.email})
Django
pip install auth101[django]
1. Create your model (myapp/models.py):
import uuid
from django.db import models
class AuthUser(models.Model):
id = models.CharField(max_length=36, primary_key=True,
default=lambda: str(uuid.uuid4()))
email = models.EmailField(unique=True, db_index=True)
password_hash = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
class Meta:
db_table = "auth_users"
Then run python manage.py makemigrations && python manage.py migrate.
2. Configure auth101 (myapp/auth.py):
from django.conf import settings
from auth101 import Auth101
from myapp.models import AuthUser
auth = Auth101(
secret=settings.SECRET_KEY,
django_model=AuthUser,
)
Auth101Middleware = auth.get_django_middleware()
login_required = auth.django_login_required()
3. Add middleware (settings.py):
MIDDLEWARE = [
"myapp.auth.Auth101Middleware", # sets request.auth_user on every request
...
]
4. Mount URLs (urls.py):
from django.urls import include, path
from myapp.auth import auth
urlpatterns = [
path("auth/", include(auth.django_urls())),
...
]
5. Protect views (myapp/views.py):
from django.http import JsonResponse
from myapp.auth import login_required
@login_required
def profile(request):
return JsonResponse({"email": request.auth_user.email})
Auth Endpoints
All framework integrations expose the same four endpoints (relative to the mount prefix):
| Method | Path | Body / Header | Response |
|---|---|---|---|
| POST | /sign-up/email |
{"email": "...", "password": "..."} |
{"user": {...}, "token": "..."} |
| POST | /sign-in/email |
{"email": "...", "password": "..."} |
{"user": {...}, "token": "..."} |
| POST | /sign-out |
Authorization: Bearer <token> |
{"success": true} |
| GET | /session |
Authorization: Bearer <token> |
{"user": {...}} |
Database Persistence
SQLAlchemy
Pass a db_url and tables are created automatically:
auth = Auth101(
secret="...",
db_url="postgresql://user:pass@localhost/mydb",
)
Works with any SQLAlchemy-supported database: PostgreSQL, MySQL, SQLite, etc.
Django ORM
Pass a django_model with the required fields (id, email, password_hash, is_active):
auth = Auth101(
secret=settings.SECRET_KEY,
django_model=AuthUser,
)
In-Memory (default)
When no db_url or django_model is provided, an in-memory store is used. Useful for testing and quick demos -- data is lost when the process exits.
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
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 auth101-0.2.1.tar.gz.
File metadata
- Download URL: auth101-0.2.1.tar.gz
- Upload date:
- Size: 16.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9466cca1bbac7b43ab6901ded4ad7ac92d148e3d288af0c8aaa8ce53fcd6cfa
|
|
| MD5 |
458427509ac4bfebbb33fc9a1f13761e
|
|
| BLAKE2b-256 |
0a789625a44eb56e615f0c47ec5e6d6de8b11d0da79f983d2ecfb7f0e96dc42c
|
File details
Details for the file auth101-0.2.1-py3-none-any.whl.
File metadata
- Download URL: auth101-0.2.1-py3-none-any.whl
- Upload date:
- Size: 17.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b19a8b5282e1d774a508fb206617323356ed0102b0797432ebf14b73593ad604
|
|
| MD5 |
bbc17801560557d6a76132fea7172323
|
|
| BLAKE2b-256 |
77ffaf0691fceda3e1b9aa1781bf9a7d40bdec5a16f4eaf84287c000dd5a6915
|