A FastAPI backend that provides login/registration, OAuth, OTP, email verification, and Stripe-based subscriptions. It runs async with PostgreSQL, Redis, and Celery so you can plug it into a SaaS dashboard or API-first product.
FastAPI SaaS kit/
|-- .github/
| `-- workflows/ci.yml
|-- alembic/
| |-- env.py
| |-- script.py.mako
| `-- versions/
|-- logs/
|-- requirements/
| |-- devlopment.txt
| `-- requirements.txt
|-- src/
| |-- auth/
| | |-- dependencies.py
| | |-- emails.py
| | |-- models.py
| | |-- repository.py
| | |-- router.py
| | |-- schemas.py
| | |-- service.py
| | `-- utils.py
| |-- billing/
| | |-- dependencies.py
| | |-- emails.py
| | |-- models.py
| | |-- repository.py
| | |-- router.py
| | |-- schemas.py
| | |-- service.py
| | `-- stripe_gateway.py
| |-- auth_bearer.py
| |-- celery_app.py
| |-- config.py
| |-- database.py
| |-- dependencies.py
| |-- logging.py
| |-- main.py
| |-- models.py
| |-- repository.py
| |-- tasks.py
| `-- utils.py
|-- templates/
| `-- email/
|-- tests/
| |-- auth/
| | |-- api_test.py
| | |-- conftest.py
| | `-- unit_test.py
| `-- billing/
| |-- api_test.py
| |-- conftest.py
| `-- unit_test.py
|-- docker-compose.yml
|-- Dockerfile
|-- alembic.ini
|-- docs.md
|-- features.md
|-- pytest.ini
`-- README.md
- FastAPI app with per-domain routers (
src/auth/router.py,src/billing/router.py), CORS, structured logging, and slowapi rate limiting. - Service/repository layers over async SQLAlchemy 2.0 + asyncpg; sync engine for Celery tasks.
- JWT access, refresh, and validation tokens with hashed refresh storage and rotation.
- Stripe Checkout + webhook handling for plans, subscriptions, renewals, and cancellations.
- SMTP email flows (verification, password reset, OTP, subscription notices) via FastAPI-Mail.
- Celery worker and beat for subscription emails and expiry sweeps.
- Local auth: register/login, email verification, password reset/change.
- OTP login (email-delivered, single-use, 15-minute expiry).
- Social auth: Google and GitHub with state validation and auto-provisioning.
- Refresh token rotation with DB-backed JTI tracking and httpOnly cookies.
- Plans: create/update/soft-delete, tiering, and Stripe product/price sync.
- Subscriptions: checkout, upgrade, cancel-at-period-end, and access window enforcement.
- Stripe webhooks: checkout completion, invoice success/failure, subscription deleted.
- Payments recorded on invoice success; subscription emails dispatched via Celery.
- Rate limiting (default 5/min) and request logging for observability.
- Python 3.12+, FastAPI, Starlette, Pydantic v2
- Async SQLAlchemy + asyncpg (PostgreSQL), Alembic migrations
- JWT via python-jose; Argon2 hashing (passlib)
- Stripe Python SDK
- Redis broker; Celery worker and beat
- FastAPI-Mail (SMTP + Jinja templates)
- slowapi for rate limiting; loguru for logging
- Python 3.12+
- PostgreSQL (DATABASE_URL) and a sync URL for Celery (SYNC_DATABASE_URL)
- Redis 7+ for rate limiting and Celery broker
- Stripe keys (public, secret, webhook signing)
- SMTP credentials for transactional emails
- Google and GitHub OAuth credentials
- Optional: Docker and docker-compose for local orchestration
- Create and activate a virtualenv:
python -m venv .venv .\.venv\Scripts\activate # on Windows # source .venv/bin/activate on Linux/macOS
- Install dependencies:
(For dev-only pins you can also use
pip install -r requirements/requirements.txt
requirements/devlopment.txt.) - Copy
.env.exampleto.envand fill in all values (see Environment Variables below). - Create the PostgreSQL databases referenced by
DATABASE_URL,SYNC_DATABASE_URL, andTEST_DATABASE_URL. - Run migrations:
alembic upgrade head
Key settings loaded via src/config.py:
- App:
APP_NAME,APP_ENV,APP_DEBUG,APP_URL - Database:
DATABASE_URL,SYNC_DATABASE_URL(used by Celery),TEST_DATABASE_URL - JWT:
ALGORITHM,ACCESS_SECRET_KEY,ACCESS_TOKEN_EXPIRE,REFRESH_SECRET_KEY,REFRESH_TOKEN_EXPIRE,VALIDATION_SECRET_KEY,VALIDATION_TOKEN_EXPIRE - Mail:
SMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASSWORD - OAuth (Google):
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GOOGLE_REDIRECT_URI,GOOGLE_AUTH_URL,GOOGLE_TOKEN_URL,GOOGLE_USERINFO_URL - OAuth (GitHub):
GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET,GITHUB_REDIRECT_URI,GITHUB_AUTHORIZE_URL,GITHUB_TOKEN_URL,GITHUB_USER_API,GITHUB_EMAILS - Infrastructure:
REDIS_URL,CELERY_WORKER_URL,CELERY_BEAT_URL - Stripe:
STRIPE_PUBLIC_KEY,STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET
- Ensure PostgreSQL and Redis are running.
- Start the API:
uvicorn src.main:app --reload
- Start Celery worker and beat (separate shells):
celery -A src.celery_app.celery_app worker --loglevel=info celery -A src.celery_app.beat_app beat --loglevel=info
- Configure your SMTP sandbox so email flows (verification/reset/OTP/subscription) can send.
- Set
APP_DEBUG=False, tighten CORS, and set cookiesecure=Truein the auth router. - Provide HTTPS termination (e.g., Nginx in front of Uvicorn/Gunicorn workers).
- Run workers with process managers (systemd/supervisor) or containers.
- Validate Stripe webhook signature with
STRIPE_WEBHOOK_SECRETand expose the webhook URL publicly. - Docker Compose option:
Services:
docker-compose up --build
api,db(Postgres),redis,celery,celery_beat, andpgadmin.
- Set
TEST_DATABASE_URLto a dedicated database. - Run all tests with:
Tests spin up schema automatically, disable the rate limiter, and use httpx ASGI client fixtures. Mock Stripe/email in new tests to avoid real calls.
pytest
- Auth:
/register,/login,/refresh-token,/verify,/request/verify,/forget-password,/new-password,/change-password,/request/login-code,/login/code,/google/login+ callback,/github/login+ callback,/deactivate. - Billing:
/billing/plans(list/create),/billing/plans/{id}(get/update/delete),/billing/subscriptions/me,/billing/subscriptions/subscribe,/billing/subscriptions/upgrade,/billing/subscriptions/cancel,/billing/payments/me,/billing/stripe/webhook.
- Fork/branch, keep PRs focused, and update docs when behaviors change.
- Add/adjust tests (pytest) for any new logic; mock external providers.
- Run
alembic upgrade headandpytestbefore pushing. - Use clear commit messages and reference relevant modules/paths.
MIT-style licensing (check repository for the full text).