fastapi-foundry
fastapi-foundry is a command-line tool that scaffolds new FastAPI projects in seconds.
One command gives you a ready-to-run FastAPI application with a clean app/ layout,
a modern uv-compatible pyproject.toml, environment-based
configuration and a sensible .gitignore, so you can skip the boilerplate and start
building your API.
uvx fastapi-foundry init myproject
Features
- One-command setup:
fastapi-foundry init <name>creates a complete project. - Runs immediately: the generated app starts with
uv syncanduvicorn, no edits needed. - Structured by default: routes in
app/routes.pydelegating to controller classes inapp/controller/. - Safe by default: never overwrites an existing directory and rejects unsafe project names.
- Same commands every time: the run command is
uvicorn app.routes:appin every generated project. - Database ready: a SQLAlchemy engine and a
get_dbsession dependency, connecting to MySQL through PyMySQL.
Requirements
- Python 3.12 or newer
- uv (recommended) or pip
Install uv if you don't have it yet:
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Installation
Option 1: Run without installing (recommended)
uvx downloads and runs the latest version in a temporary environment:
uvx fastapi-foundry init myproject
Option 2: Install as a global command
uv tool install fastapi-foundry
Then use it from any directory:
fastapi-foundry init myproject
Upgrade later with:
uv tool upgrade fastapi-foundry
Option 3: Install with pip
pip install fastapi-foundry
Quick start
1. Create a project
uvx fastapi-foundry init myproject
Created FastAPI project: myproject
Next steps:
cd myproject
uv sync
uv run uvicorn app.routes:app --reload
2. Install dependencies
cd myproject
uv sync
3. Run the application
uv run uvicorn app.routes:app --reload
4. Open it in your browser
| URL | Description |
|---|---|
| http://127.0.0.1:8000 | API root, returns {"message": "Hello from FastAPI"} |
| http://127.0.0.1:8000/docs | Interactive Swagger UI documentation |
| http://127.0.0.1:8000/redoc | ReDoc documentation |
Generated project structure
myproject/
├── pyproject.toml # Dependencies (FastAPI, Uvicorn, SQLAlchemy, PyMySQL)
├── .env # Environment variables
├── .gitignore # Python, uv and tooling ignores
├── README.md # How to install and run the project
└── app/
├── routes.py # FastAPI application and routes
├── config/
│ ├── app.py # APP_NAME and DEBUG
│ ├── database.py # DATABASE_URL
│ └── sqlalchemy_connection.py # SQLAlchemy engine, SessionLocal and get_db
├── controller/
│ └── home_controller.py # Handles the default route
└── database/
└── 20260922143022_create_users_table.py
Generated projects are applications, not libraries: there is no [build-system] and no
__init__.py. app/ is a namespace package that uvicorn imports from the project root.
Routes stay thin and hand the work to a controller. The generated app/routes.py:
from fastapi import FastAPI
from app.config.app import APP_NAME, DEBUG
from app.controller.home_controller import HomeController
app = FastAPI(title=APP_NAME, debug=DEBUG)
home_controller = HomeController()
@app.get("/")
def root() -> dict[str, str]:
return home_controller.index()
And app/controller/home_controller.py:
class HomeController:
"""Handles requests for the application root."""
def index(self) -> dict[str, str]:
return {"message": "Hello from fastapi-foundry"}
Add a controller class per resource in app/controller/, and give it a route in
app/routes.py.
Configuration
Generated projects read their settings from environment variables, with one module per
kind of configuration in app/config/:
| Variable | Module | Default | Description |
|---|---|---|---|
APP_NAME |
app/config/app.py |
project name | Title shown in the API docs |
DEBUG |
app/config/app.py |
false |
Enables FastAPI debug mode (true, 1 or yes) and SQL logging |
DATABASE_URL |
app/config/database.py |
mysql+pymysql://root:@127.0.0.1:3306/<project> |
SQLAlchemy URL used by app/config/sqlalchemy_connection.py |
Add new settings to the module they belong to, or create a new module in app/config/
for a new kind of configuration.
To load the values from the generated .env file, start the server with --env-file:
uv run uvicorn app.routes:app --reload --env-file .env
Database connection
app/config/sqlalchemy_connection.py creates the SQLAlchemy engine from DATABASE_URL and
provides get_db, a dependency that opens one session per request and closes it
afterwards. The default database name is the project name in snake_case
(my-fastapi-app → my_fastapi_app). Set your own credentials in .env:
DATABASE_URL=mysql+pymysql://<user>:<password>@<host>:3306/<database>
from typing import Annotated
from fastapi import Depends
from sqlalchemy.orm import Session
from app.config.sqlalchemy_connection import get_db
@app.get("/items")
def list_items(db: Annotated[Session, Depends(get_db)]) -> list[dict]:
...
The engine connects lazily, so the app starts even when the database is not reachable;
the first request that uses get_db is what opens a connection.
Project names
The project name is used for the folder and the distribution name, so it must:
- start with a letter
- contain only letters, digits, hyphens (
-) and underscores (_) - not be a Python keyword or clash with a standard library or FastAPI module (for example
jsonorfastapi)
uvx fastapi-foundry init my-fastapi-app
This creates the my-fastapi-app/ folder. The name does not appear inside the project, so
the run command is the same as for every other project:
uv run uvicorn app.routes:app --reload
If the target folder already exists, fastapi-foundry stops with an error instead of overwriting your files.
Command reference
fastapi-foundry --help # Show available commands
fastapi-foundry init --help # Show help for the init command
fastapi-foundry init <name> # Create a new project in the current directory
fastapi-foundry migration # Create a migration file in ./migrations
Migrations
Run fastapi-foundry migration from the project root to add a migration file:
uvx fastapi-foundry migration
It asks whether the migration targets an existing table or a new one. For a new table it asks for the table name; for an existing table it lists the tables earlier migrations already cover so you can pick one.
Is this migration for an existing table or a new table?
1) Existing table
2) New table
Select [1-2]: 2
What is the name of the table this migration should structure: users
Created migration: app/database/20260922143022_create_users_table.py
Migration files are written to app/database/, alongside the users migration that every
new project ships with:
app/database/
├── 20260922143022_create_users_table.py
└── 20260922143512_create_posts_table.py
Each file records its table in a TABLE constant, which is how the command
lists existing tables. No database connection is needed.
"""Create table 'users'."""
TABLE = "users"
def upgrade() -> None:
"""Apply this migration."""
def downgrade() -> None:
"""Revert this migration."""
The upgrade() and downgrade() bodies are yours to fill in; fastapi-foundry
does not run migrations yet.
Roadmap
fastapi-foundry is in early development. Planned features include:
- Running migrations with Alembic
- Settings management with Pydantic Settings
- Generators for models and routes
- Authentication scaffolding
- Docker support
Contributing
Issues and pull requests are welcome on GitHub.
To set up a development environment:
git clone https://github.com/udarakalpana/fastapi-foundry.git
cd fastapi-foundry
uv sync
uv run pytest
Run the CLI from your local checkout:
uv run fastapi-foundry init myproject
Tip: create test projects outside the repository folder so they don't get mixed into its Git history.
License
fastapi-foundry is released under the MIT License.
Metadata
Release files for fastapi-foundry 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastapi_foundry-0.4.1.tar.gz | 11.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastapi_foundry-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.1 kB
Release files / fastapi_foundry-0.4.1.tar.gz
| Download URL | fastapi_foundry-0.4.1.tar.gz |
|---|---|
| Size | 11.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b6a7449edb2c8eeba99520921619623b4e6d574174e56479e63ecfd2cb93e8bf
|
|
BLAKE2b-256 checksum How to use checksums |
f9272c86d6cdd10ac15604ab1031df8443920c6b37c061b625c80819b46e805a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / fastapi_foundry-0.4.1-py3-none-any.whl
| Download URL | fastapi_foundry-0.4.1-py3-none-any.whl |
|---|---|
| Size | 15.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
95562e35a7ab4b9eeb00ccd5903b0d13cac4b4e6a316a1f4b55a9dc23e2ba25d
|
|
BLAKE2b-256 checksum How to use checksums |
713efa48062d9dc3912e1fb435dda84e0e0b90d5bcb2e544033bff9d55c98229
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|