Skip to main content

pyallauth

PyPI version Tests Coverage License: MIT Python versions

Plug-and-play authentication for FastAPI. One import, one mount, full auth.


What is pyallauth?

pyallauth is a batteries-included authentication library for FastAPI. If you've ever copy-pasted JWT boilerplate between projects, stood up a Django-allauth equivalent for FastAPI, or spent a weekend wiring together email verification, OAuth, and token refresh — this library is for you.

Mount it once and you get:

  • Local auth — register, login, logout, token refresh
  • Social OAuth2 — Google, GitHub, Facebook, Twitter/X
  • Email verification — mandatory, optional, or disabled
  • Password reset — single-use token flow with email
  • Account management — profile, change email, change password, delete
  • Secure JWT sessions — short-lived access + long-lived refresh with blacklisting
  • Async-first — every DB call, email send, and OAuth exchange is awaitable

Features

  • Single router mount — full auth in < 5 lines
  • Pluggable user model — extend the base or bring your own
  • Adapter pattern — SQLAlchemy async out of the box; Tortoise-ORM ready
  • Pydantic v2 schemas throughout
  • bcrypt password hashing with passlib CryptContext
  • PKCE support for Twitter/X OAuth2
  • Email backend abstraction — SMTP or console (for development)
  • Refresh token rotation and blacklisting
  • Single-use tokens with UTC-aware expiry
  • 85% test coverage


Installation

# pip
pip install pyallauth

# With PostgreSQL support (asyncpg driver)
pip install "pyallauth[postgres]"

# Poetry
poetry add pyallauth

Requirements: Python 3.11+, FastAPI ≥ 0.110, SQLAlchemy ≥ 2.0.


Quickstart

from fastapi import FastAPI
from pyallauth import PyAllAuth

app = FastAPI()

auth = PyAllAuth(
    secret_key="your-secret-key",                           # Required
    database_url="sqlite+aiosqlite:///./app.db",            # SQLite for dev
    email_verification="mandatory",
    email_backend="console",                                # Prints to terminal
)

auth.register_exception_handlers(app)
app.include_router(auth.router, prefix="/auth")

That's it. Open http://localhost:8000/docs to see all 16 auth endpoints.

Create database tables

from pyallauth.models.sqlalchemy import create_tables, make_engine

@app.on_event("startup")
async def startup():
    engine = make_engine("sqlite+aiosqlite:///./app.db")
    await create_tables(engine)
    await engine.dispose()

In production, use Alembic migrations instead.

Protecting your own endpoints

from fastapi import Depends

@app.get("/dashboard")
async def dashboard(current_user = Depends(auth._get_current_user)):
    return {"email": current_user.email}

Configuration Reference

All settings can be passed as constructor arguments to PyAllAuth or as environment variables with the PYALLAUTH_ prefix.

Setting Type Default Description
secret_key str required JWT signing secret
algorithm str "HS256" JWT algorithm
access_token_expire int 15 Access token lifetime (minutes)
refresh_token_expire int 7 Refresh token lifetime (days)
email_verification str "mandatory" "mandatory", "optional", "none"
email_backend str "console" "console" or "smtp"
smtp_host str "localhost" SMTP server hostname
smtp_port int 587 SMTP server port
smtp_user str "" SMTP username
smtp_password str "" SMTP password
smtp_from_email str "noreply@example.com" From address
smtp_tls bool True Use STARTTLS
frontend_url str "http://localhost:3000" Base URL for email links
social_providers list[str] [] Enabled providers
google_client_id str|None None Google OAuth2 client ID
google_client_secret str|None None Google OAuth2 client secret
github_client_id str|None None GitHub OAuth2 client ID
github_client_secret str|None None GitHub OAuth2 client secret
facebook_client_id str|None None Facebook app ID
facebook_client_secret str|None None Facebook app secret
twitter_client_id str|None None Twitter/X client ID
twitter_client_secret str|None None Twitter/X client secret

API Reference

All endpoints are mounted at the prefix you choose (/auth recommended).

Local Authentication

Method Path Auth Description
POST /auth/register — Register new account
POST /auth/login — Login, receive JWT pair
POST /auth/logout — Blacklist refresh token
POST /auth/token/refresh — Exchange refresh for new access token

Register POST /auth/register

{
  "email": "user@example.com",
  "password": "StrongPass1!",
  "full_name": "Jane Doe"
}

Login POST /auth/login

{
  "email": "user@example.com",
  "password": "StrongPass1!"
}

Response:

{
  "access_token": "eyJ...",
  "refresh_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 900
}

Email Verification

Method Path Auth Description
GET /auth/email/verify/{token} — Verify email with token
POST /auth/email/resend Bearer Resend verification email

Password Reset

Method Path Auth Description
POST /auth/password/reset — Send reset email
POST /auth/password/reset/confirm — Set new password with token

Reset request POST /auth/password/reset

{"email": "user@example.com"}

Reset confirm POST /auth/password/reset/confirm

{"token": "abc123...", "new_password": "NewStrongPass1!"}

Account Management

All endpoints require Authorization: Bearer <access_token>.

Method Path Description
GET /auth/account/me Get profile
PATCH /auth/account/me Update profile
POST /auth/account/change-password Change password
POST /auth/account/change-email Change email
DELETE /auth/account/me Delete account

Social OAuth2

Method Path Auth Description
GET /auth/social/{provider}/login — Get authorisation URL
GET /auth/social/{provider}/callback — Handle callback, return JWT
GET /auth/social/accounts Bearer List linked accounts
DELETE /auth/social/accounts/{id} Bearer Disconnect account

Supported {provider} values: google, github, facebook, twitter.


Custom User Model

pyallauth's user table (pyallauth_users) covers the required fields. To add custom fields, subclass UserModel:

# myapp/models.py
from pyallauth.models.sqlalchemy import UserModel
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import String

class User(UserModel):
    __tablename__ = "users"  # Override table name

    phone_number: Mapped[str | None] = mapped_column(String(20))
    avatar_url: Mapped[str | None] = mapped_column(String(512))

Then create tables using Alembic with User in the metadata.


Custom Adapter Guide

To use a different ORM (Tortoise, Beanie, etc.):

from pyallauth.models.base import AbstractUserAdapter, UserRecord

class MyAdapter(AbstractUserAdapter):
    async def get_user_by_email(self, email: str) -> UserRecord | None:
        ...  # implement all abstract methods

    # ... implement remaining 14 methods

# Pass to PyAllAuth
auth = PyAllAuth(
    secret_key="...",
    adapter=MyAdapter(),
)

See pyallauth/models/base.py for the full interface.


Social Provider Setup

Google

  1. Google Cloud Console → Credentials → OAuth 2.0 Client ID
  2. Add https://yourapp.com/auth/social/google/callback to Authorised redirect URIs
  3. Set PYALLAUTH_GOOGLE_CLIENT_ID and PYALLAUTH_GOOGLE_CLIENT_SECRET
auth = PyAllAuth(
    secret_key="...",
    database_url="...",
    social_providers=["google"],
    google_client_id="your-client-id",
    google_client_secret="your-client-secret",
)

GitHub

  1. GitHub Developer Settings → New OAuth App
  2. Set Authorization callback URL to https://yourapp.com/auth/social/github/callback
  3. Set PYALLAUTH_GITHUB_CLIENT_ID and PYALLAUTH_GITHUB_CLIENT_SECRET

How This Was Built

Read the full step-by-step implementation journal in DEVLOG.md. It covers every architectural decision, from the adapter pattern to token expiry handling to why we use hmac.compare_digest for token comparisons.


Roadmap

  • Tortoise-ORM adapter
  • Microsoft/Azure AD provider
  • LinkedIn provider
  • Apple Sign In provider
  • Magic link (passwordless) authentication
  • WebAuthn / passkey support
  • Redis-based refresh token store (for high-throughput scenarios)
  • Alembic migration scripts shipped with the package
  • Pre-built Jinja2 email templates
  • Rate limiting on auth endpoints

Contributing

We welcome contributions of all sizes — bug fixes, new providers, new ORM adapters, documentation improvements. See CONTRIBUTING.md for the local setup guide, branch naming convention, and PR checklist.


License

MIT © 2026 officialalkenes. See LICENSE for details.

Metadata

Release files for pyallauth 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyallauth 0.1.0
File Size Uploaded
pyallauth-0.1.0.tar.gz 43.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyallauth 0.1.0
File Interpreter ABI Platform
pyallauth-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 102.8 kB

Release files / pyallauth-0.1.0.tar.gz

Download URL pyallauth-0.1.0.tar.gz
Size 43.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f57fd4ee8e8d896a0a5ffe5902e11de58fc3ef11dd4d27c84afcd39c925b59b3
BLAKE2b-256 checksum
How to use checksums
124aae8e9e6e2cb6026de16f1b54180e7891c213050558132dbc1d0fde131b26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.1.2 CPython/3.12.9 Darwin/25.3.0

Release files / pyallauth-0.1.0-py3-none-any.whl

Download URL pyallauth-0.1.0-py3-none-any.whl
Size 58.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
afae453558565f20bcd69c60a18756783c29a87236cc0f52d54414967653d3cf
BLAKE2b-256 checksum
How to use checksums
6e07236acc88c1a138ff7425cc1f8464b7e1f71657b185d2417e0f960430cc46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.1.2 CPython/3.12.9 Darwin/25.3.0

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page