Skip to main content

Plug-and-play authentication library for FastAPI — local + social OAuth2, JWT sessions, email verification, and more.

Project description

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.

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

pyallauth-0.1.0.tar.gz (43.9 kB view details)

Uploaded Source

Built Distribution

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

pyallauth-0.1.0-py3-none-any.whl (58.9 kB view details)

Uploaded Python 3

File details

Details for the file pyallauth-0.1.0.tar.gz.

File metadata

  • Download URL: pyallauth-0.1.0.tar.gz
  • Upload date:
  • Size: 43.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.2 CPython/3.12.9 Darwin/25.3.0

File hashes

Hashes for pyallauth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f57fd4ee8e8d896a0a5ffe5902e11de58fc3ef11dd4d27c84afcd39c925b59b3
MD5 7cfeab5d5211ca951e31c0040dc8a990
BLAKE2b-256 124aae8e9e6e2cb6026de16f1b54180e7891c213050558132dbc1d0fde131b26

See more details on using hashes here.

File details

Details for the file pyallauth-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyallauth-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 58.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.2 CPython/3.12.9 Darwin/25.3.0

File hashes

Hashes for pyallauth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 afae453558565f20bcd69c60a18756783c29a87236cc0f52d54414967653d3cf
MD5 faa03f4b0772bc89f847d81227b65bc0
BLAKE2b-256 6e07236acc88c1a138ff7425cc1f8464b7e1f71657b185d2417e0f960430cc46

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