Skip to main content

A powerful CLI tool to scaffold production-ready FastAPI projects with flexible database, auth, broker, and deployment options.

Project description

⚡ fastapi-spawn

The most complete FastAPI project scaffolding CLI — built for modern Python development.

PyPI version Python License: MIT CI

Generate production-ready FastAPI projects in seconds — with exactly the stack you need.


Installation

pip install fastapi-spawn
# or
uv pip install fastapi-spawn

Quick Start

# Interactive TUI — guided step-by-step
fastapi-spawn new my-api

# Or use a preset template (New in 0.4.24!)
fastapi-spawn start basic my-api
fastapi-spawn start full-local my-api
fastapi-spawn start full my-api
fastapi-spawn start custom my-api

# Full stack one-liner
fastapi-spawn new my-api \
  --db postgresql \
  --orm sqlalchemy \
  --migration alembic \
  --auth jwt \
  --broker redis \
  --storage s3 \
  --ai openai \
  --monitoring sentry \
  --email sendgrid \
  --notify slack \
  --log-lib loguru \
  --log-dest local \
  --vector-db qdrant \
  --api-extra both \
  --stack full \
  --ci github

# Preview file tree without writing
fastapi-spawn new my-api --dry-run

# Add a feature to an existing project
fastapi-spawn add openai
fastapi-spawn add alembic
fastapi-spawn add sentry

💡 Pro-Tip: Starting in an Empty Folder

To avoid confusion with nested projects (e.g., having a pyproject.toml in both the root and subfolder):

Option A: Let it create the folder (Recommended)

  1. Go to your projects directory.
  2. Run fastapi-spawn start (Do not run uv init first!).
  3. It will create a folder with everything inside.
  4. Open that folder in VS Code and run uv sync!

Option B: Generate directly in the CURRENT folder

If you already created a folder and opened it in VS Code:

  1. Run fastapi-spawn start.
  2. When it asks "Do you want to generate files directly in the current directory?", select Yes.
  3. It will generate all files directly in your current folder without creating a subfolder! (New in 0.4.29!)

🆘 Built-in Help & Auto-Suggestions

fastapi-spawn comes with an integrated global help menu and intelligent typo correction:

# Display the interactive global help menu
fastapi-spawn help

# Or use the standard flag
fastapi-spawn --help

Auto-Typo Correction (Did you mean?)

If you accidentally misspell a command, the CLI will catch it and suggest the right one automatically to save you time.

$ fastapi-spawn nw my_app

Error: No such command 'nw'. Did you mean 'new'?

Generated Project Structure

my-api/
├── app/
│   ├── api/
│   │   ├── graphql.py           # Strawberry GraphQL schema + IDE (if graphql)
│   │   └── v1/
│   │       ├── router.py        # Central API router aggregating sub-routers
│   │       ├── health/
│   │       │   └── router.py    # GET /health  /readiness  /liveness
│   │       ├── auth/
│   │       │   └── router.py    # POST /auth/login  /auth/refresh (if auth)
│   │       └── ws/
│   │           └── router.py    # WebSocket /ws/connect (if websockets)
│   ├── core/
│   │   ├── config.py            # Pydantic Settings v2 — individual env fields + @property URLs
│   │   ├── logger.py            # Context-var logger — request ID, client IP, file rotation
│   │   ├── exceptions.py        # Custom exception hierarchy + handlers
│   │   ├── security.py          # JWT / bcrypt
│   │   ├── ws_manager.py        # WebSocket connection manager — broadcast, rooms
│   │   ├── storage.py           # AWS S3/MinIO | GCS | Cloudinary
│   │   ├── ai.py                # OpenAI | Anthropic | Gemini | Ollama | LangChain | LlamaIndex
│   │   ├── monitoring.py        # Sentry | Prometheus | OpenTelemetry
│   │   ├── email.py             # SendGrid | SMTP | AWS SES
│   │   ├── notifications.py     # Slack | Discord webhooks
│   │   └── vector_db.py         # Qdrant | ChromaDB | Pinecone | Supabase | Elasticsearch
│   ├── middleware/
│   │   ├── request_logger.py    # X-Request-ID, response time, structured logs
│   │   └── rate_limit.py        # slowapi — 200/min default, 429 + Retry-After
│   ├── db/
│   │   └── session.py           # Async SQLAlchemy / SQLModel / Tortoise / Beanie
│   ├── models/
│   ├── schemas/
│   ├── services/
│   └── repositories/
├── tasks/
│   ├── celery_app.py            # Celery (Redis / RabbitMQ)
│   ├── sample_tasks.py
│   └── arq_worker.py            # Arq async task queue (if arq)
├── migrations/                  # Alembic async
│   ├── env.py
│   └── versions/
├── infra/
│   ├── docker/
│   ├── helm/
│   └── terraform/
├── tests/
├── logs/                        # Local rotating logs
├── main.py                      # uv run main.py
├── alembic.ini
├── Dockerfile
├── docker-compose.yml
├── Makefile
├── .env                         # gitignored
├── .env.example                 # full reference of every supported variable
├── .gitignore
├── .pre-commit-config.yaml
└── pyproject.toml               # [tool.uv.scripts] pre-wired

All Options

fastapi-spawn new [OPTIONS] PROJECT_NAME

Database & ORM
  --db           postgresql | mysql | mongodb | sqlite | supabase | duckdb | none
  --orm          sqlalchemy | sqlmodel | tortoise | beanie | none
  --migration    alembic | aerich | none

Auth & Security
  --auth         jwt | oauth2 | api-key | auth0 | none

Messaging & Cache
  --broker       redis | rabbitmq | kafka | arq | none
  --cache        redis | memcached | none

Storage
  --storage      s3 | gcs | cloudinary | local | none

AI / LLM
  --ai           openai | anthropic | gemini | ollama | langchain | llamaindex | none

API Extras
  --api-extra    websockets | graphql | both | none

Monitoring
  --monitoring   sentry | prometheus | opentelemetry | both | none

Email
  --email        sendgrid | smtp | ses | none

Notifications
  --notify       slack | discord | none

Logging
  --log-lib      loguru | structlog | standard
  --log-dest     local | cloudwatch | datadog | none

Vector Database
  --vector-db    qdrant | chroma | pinecone | supabase | elasticsearch | none

Deployment
  --stack        minimal | standard | full
  --ci           github | gitlab | both | none

Flags
  --no-docker    Skip Docker files
  --no-tests     Skip test suite
  --dry-run      Preview file tree without writing
  --force / -f   Overwrite existing directory
  --output / -o  Output directory (default: .)

uv run Scripts

Every generated project has [tool.uv.scripts] pre-wired:

uv run dev        # uvicorn --reload
uv run start      # python main.py
uv run test       # pytest --cov
uv run lint       # ruff check
uv run format     # ruff format
uv run typecheck  # mypy
uv run migrate    # alembic upgrade head    (if alembic)
uv run rollback   # alembic downgrade -1    (if alembic)
uv run makemig    # alembic revision --autogenerate (if alembic)
uv run worker     # celery worker           (if celery)
uv run beat       # celery beat             (if celery)

Environment Variables

Individual fields per service — no URL strings. All connection URLs are assembled via @property in app/core/config.py. Your .env.example includes every supported variable:

# ── Application ──────────────────────────────────────────────────────────────
APP_NAME=my-api
ENVIRONMENT=dev                      # dev | staging | production
SECRET_KEY=CHANGE_ME                 # openssl rand -hex 32
CORS_ORIGINS=http://localhost:3000,http://localhost:8000

# ── Logging ───────────────────────────────────────────────────────────────────
LOG_LEVEL=INFO
LOG_DIR=logs
LOG_BACKUP_DAYS=30

# ── PostgreSQL ─────────────────────────────────────────────────────────────
POSTGRES_USER=postgres
POSTGRES_PASSWORD=CHANGE_ME
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=my_api_db
# → assembled as: postgresql+asyncpg://USER:PASS@HOST:PORT/DB

# ── MySQL ─────────────────────────────────────────────────────────────────
MYSQL_USER=root
MYSQL_PASSWORD=CHANGE_ME
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_DB=my_api_db
# → assembled as: mysql+aiomysql://USER:PASS@HOST:PORT/DB

# ── MongoDB ───────────────────────────────────────────────────────────────
MONGODB_USER=mongo
MONGODB_PASSWORD=CHANGE_ME
MONGODB_HOST=localhost
MONGODB_PORT=27017
MONGODB_DB=my_api_db
# → assembled as: mongodb://USER:PASS@HOST:PORT

# ── Supabase ──────────────────────────────────────────────────────────────
SUPABASE_URL=https://xxxx.supabase.co
SUPABASE_KEY=CHANGE_ME               # anon or service role key

# ── DuckDB ────────────────────────────────────────────────────────────────
DUCKDB_FILE=my_api.duckdb

# ── Redis ─────────────────────────────────────────────────────────────────
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
# → assembled as: redis://:PASS@HOST:PORT/DB

# ── RabbitMQ ─────────────────────────────────────────────────────────────
RABBITMQ_USER=guest
RABBITMQ_PASSWORD=CHANGE_ME
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_VHOST=/
# → assembled as: amqp://USER:PASS@HOST:PORT/VHOST

# ── Kafka ────────────────────────────────────────────────────────────────
KAFKA_HOST=localhost
KAFKA_PORT=9092
# → assembled as: HOST:PORT

# ── Auth / JWT ───────────────────────────────────────────────────────────
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
ALGORITHM=HS256

# ── Auth0 ────────────────────────────────────────────────────────────────
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=CHANGE_ME
AUTH0_CLIENT_SECRET=CHANGE_ME
AUTH0_AUDIENCE=https://your-api.example.com

# ── AWS (S3 / SES / CloudWatch) ──────────────────────────────────────────
AWS_ACCESS_KEY_ID=CHANGE_ME
AWS_SECRET_ACCESS_KEY=CHANGE_ME
AWS_REGION=us-east-1
AWS_S3_BUCKET=my-api-bucket
AWS_S3_ENDPOINT_URL=               # http://localhost:9000 for MinIO

# ── Google Cloud Storage ─────────────────────────────────────────────────
GCS_PROJECT_ID=CHANGE_ME
GCS_BUCKET=my-api-bucket
GOOGLE_APPLICATION_CREDENTIALS=./service-account.json

# ── Cloudinary ───────────────────────────────────────────────────────────
CLOUDINARY_CLOUD_NAME=CHANGE_ME
CLOUDINARY_API_KEY=CHANGE_ME
CLOUDINARY_API_SECRET=CHANGE_ME

# ── OpenAI ───────────────────────────────────────────────────────────────
OPENAI_API_KEY=sk-placeholder
OPENAI_MODEL=gpt-4o
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
OPENAI_BASE_URL=                   # blank = api.openai.com
                                   # Azure: https://<resource>.openai.azure.com/
                                   # LM Studio: http://localhost:1234/v1

# ── Anthropic ────────────────────────────────────────────────────────────
ANTHROPIC_API_KEY=sk-ant-placeholder
ANTHROPIC_MODEL=claude-3-5-sonnet-20241022

# ── Google Gemini ────────────────────────────────────────────────────────
GEMINI_API_KEY=CHANGE_ME
GEMINI_MODEL=gemini-1.5-pro

# ── Ollama (local LLM — no API key) ─────────────────────────────────────
OLLAMA_HOST=localhost
OLLAMA_PORT=11434
OLLAMA_MODEL=llama3
# → assembled as: http://HOST:PORT

# ── Sentry ───────────────────────────────────────────────────────────────
SENTRY_DSN=https://xxx@sentry.io/yyy

# ── Datadog ──────────────────────────────────────────────────────────────
DD_API_KEY=CHANGE_ME
DD_SITE=datadoghq.com

# ── SendGrid ─────────────────────────────────────────────────────────────
SENDGRID_API_KEY=SG.placeholder
SENDGRID_FROM_EMAIL=noreply@example.com

# ── SMTP ─────────────────────────────────────────────────────────────────
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=CHANGE_ME
SMTP_PASSWORD=CHANGE_ME
SMTP_FROM_EMAIL=noreply@example.com
SMTP_STARTTLS=true
SMTP_SSL=false

# ── AWS SES ──────────────────────────────────────────────────────────────
SES_FROM_EMAIL=noreply@example.com  # uses AWS_* credentials above

# ── Resend ───────────────────────────────────────────────────────────────
RESEND_API_KEY=re_placeholder
RESEND_FROM_EMAIL=noreply@example.com

# ── Slack ────────────────────────────────────────────────────────────────
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/CHANGE_ME

# ── Discord ──────────────────────────────────────────────────────────────
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/CHANGE_ME

# ── Qdrant ───────────────────────────────────────────────────────────────
QDRANT_HOST=localhost
QDRANT_PORT=6333
QDRANT_API_KEY=                    # blank for local Docker Qdrant
# → assembled as: http://HOST:PORT

# ── Pinecone ─────────────────────────────────────────────────────────────
PINECONE_API_KEY=CHANGE_ME
PINECONE_INDEX_NAME=my-api-index

# ── Elasticsearch ────────────────────────────────────────────────────────
ELASTICSEARCH_HOST=localhost
ELASTICSEARCH_PORT=9200
ELASTICSEARCH_API_KEY=
# → assembled as: http://HOST:PORT

# ── OpenSearch ───────────────────────────────────────────────────────────
OPENSEARCH_HOST=localhost
OPENSEARCH_PORT=9200
OPENSEARCH_USER=admin
OPENSEARCH_PASSWORD=admin

# ── Vespa ────────────────────────────────────────────────────────────────
VESPA_ENDPOINT=http://localhost:8080

# ── Extras (Stripe, SSO, Meilisearch) ────────────────────────────────────
STRIPE_API_KEY=sk_test_placeholder
STRIPE_WEBHOOK_SECRET=whsec_placeholder

GOOGLE_CLIENT_ID=placeholder
GOOGLE_CLIENT_SECRET=placeholder

GITHUB_CLIENT_ID=placeholder
GITHUB_CLIENT_SECRET=placeholder

MICROSOFT_CLIENT_ID=placeholder
MICROSOFT_CLIENT_SECRET=placeholder

MEILISEARCH_HOST=http://localhost:7700
MEILISEARCH_API_KEY=masterKey

All variables are assembled into connection URLs inside app/core/config.py via @property. Your code always reads from structured fields — never a fragile connection string.


Middleware (always included)

Middleware Behaviour
RequestLoggingMiddleware Assigns X-Request-ID, logs → METHOD /path + ✓ status Xms with client IP
RateLimitMiddleware 200 req/min default via slowapi, returns 429 + Retry-After: 60
CORSMiddleware Configurable origins via CORS_ORIGINS env var

Every response carries X-Request-ID and X-Response-Time headers automatically.


WebSockets

# Connect: ws://host/api/v1/ws/connect
# Room:    ws://host/api/v1/ws/connect/{room_id}

# Client protocol
{"type": "broadcast", "data": "hello everyone"}
{"type": "ping"}   # → {"type": "pong"}

GraphQL

Strawberry schema with Query + Mutation + Subscription is mounted at /graphql.
GraphiQL IDE is enabled in dev mode. Subscriptions use graphql-transport-ws.


🧩 Add Features to Existing Projects (Incremental Scaffolding)

Did you generate a minimal project and now realize you need WebSockets, AWS S3, or OpenAI? No problem.

fastapi-spawn add allows you to incrementally scale your project. Instead of re-generating your entire project or copying boilerplate manually, you can inject production-ready modules into your existing codebase.

fastapi-spawn add [FEATURE]

Or you can add them at creation time with the --extra flag:

fastapi-spawn new my_app --extra stripe --extra sso --extra seed

All Possibilities you can add or --extra:

You can run any of the following commands inside an existing project:

# Infrastructure & Deployment
fastapi-spawn add docker       # Dockerfile and docker-compose.yml
fastapi-spawn add helm         # Helm chart in infra/helm/
fastapi-spawn add terraform    # Terraform in infra/terraform/
fastapi-spawn add github-actions # CI/CD pipeline (.github/workflows/tests.yml)

# AI & Vector DBs
fastapi-spawn add openai       # OpenAI async client
fastapi-spawn add anthropic    # Anthropic Claude async client
fastapi-spawn add gemini       # Google Generative AI client
fastapi-spawn add qdrant       # Qdrant vector DB
fastapi-spawn add chroma       # ChromaDB local vector DB
fastapi-spawn add pinecone     # Pinecone cloud vector DB
fastapi-spawn add meilisearch  # Meilisearch typo-tolerant search
fastapi-spawn add opensearch   # OpenSearch vector & text search
fastapi-spawn add vespa        # Vespa big data serving engine
fastapi-spawn add ocr          # PDF & OCR data extraction pipeline

# Payments & Identity
fastapi-spawn add stripe       # Stripe payments & webhooks
fastapi-spawn add sso          # FastAPI SSO (Google, GitHub, Microsoft)
fastapi-spawn add sso-google   # FastAPI SSO (Google only)
fastapi-spawn add sso-github   # FastAPI SSO (GitHub only)
fastapi-spawn add sso-microsoft # FastAPI SSO (Microsoft only)

# Messaging & Async Workers
fastapi-spawn add celery       # Celery worker + tasks/
fastapi-spawn add arq          # Arq async job queues using Redis
fastapi-spawn add websockets   # WebSocket connection manager
fastapi-spawn add sse          # Server-Sent Events streaming

# Storage, APIs, Seeding & Monitoring
fastapi-spawn add s3           # AWS S3 / MinIO storage
fastapi-spawn add graphql      # Strawberry GraphQL schema
fastapi-spawn add alembic      # Alembic async migrations
fastapi-spawn add seed         # Faker database seeding script (Users, Posts, Comments)
fastapi-spawn add resend       # Resend modern email client
fastapi-spawn add sentry       # Sentry APM integration
fastapi-spawn add prometheus   # Prometheus metrics

# Advanced API Features
fastapi-spawn add rbac             # Role-Based Access Control (@RequireRole decorator)
fastapi-spawn add caching          # Redis API Response Caching (@cache decorator)
fastapi-spawn add response-format  # Global formatted JSON response middleware
fastapi-spawn add admin            # Internal CRUD Admin Dashboard (sqladmin)
fastapi-spawn add pagination       # Automatic endpoint pagination logic
fastapi-spawn add uploads          # File upload router (Multipart Form)

Example:

$ fastapi-spawn add websockets

✓ Created app/core/ws_manager.py
✓ Created app/api/v1/ws/router.py

👉 Next Steps:
1. Mount the router in app/api/v1/router.py:
   from app.api.v1.ws.router import router as ws_router
   router.include_router(ws_router)

ORM ↔ Database Compatibility

ORM Compatible Databases
sqlalchemy postgresql, mysql, sqlite, supabase
sqlmodel postgresql, mysql, sqlite, supabase
tortoise postgresql, mysql, sqlite
beanie mongodb
none any

Contributing

git clone https://github.com/Bishwajitgarai/fastapi-spawn
cd fastapi-spawn
uv sync --all-extras
uv run pytest

License

MIT © Bishwajit Garai

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

fastapi_spawn-0.4.37.tar.gz (67.8 kB view details)

Uploaded Source

Built Distribution

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

fastapi_spawn-0.4.37-py3-none-any.whl (93.9 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_spawn-0.4.37.tar.gz.

File metadata

  • Download URL: fastapi_spawn-0.4.37.tar.gz
  • Upload date:
  • Size: 67.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.0

File hashes

Hashes for fastapi_spawn-0.4.37.tar.gz
Algorithm Hash digest
SHA256 f6f9c05f10c4c4170dad58ae5ab697ab57b2edf3bafbc9a597872bfda76f7511
MD5 29fb7bd34d1a8bc992ddb2fb0409302c
BLAKE2b-256 bfe0cf39c7d92cff6aa974f66ad23c41cbf5e8233515bada9fdf238cd2bdf78e

See more details on using hashes here.

File details

Details for the file fastapi_spawn-0.4.37-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_spawn-0.4.37-py3-none-any.whl
Algorithm Hash digest
SHA256 88dd1c0eca4f2b3c3fd4e0a2c3f0a05e7cde06cbc8ce0bbfcb6470a25f6d5790
MD5 38a8a6ca0603b6053031f80410a6d9d0
BLAKE2b-256 fef61d707554dec5ef7c22ddc78b415c386790d2b9c177016254ae3c447293b6

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