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.py # Settings read from environment variables
├── controller/
│ └── home_controller.py # Handles the default route
└── database/
├── connection.py # SQLAlchemy engine, SessionLocal and get_db
└── 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 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 in config.py:
| Variable | Default | Description |
|---|---|---|
APP_NAME |
project name | Title shown in the API docs |
DEBUG |
false |
Enables FastAPI debug mode (true, 1 or yes) and SQL logging |
DATABASE_URL |
mysql+pymysql://root:@127.0.0.1:3306/<project> |
SQLAlchemy URL used by app/database/connection.py |
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/database/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.database.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/
├── connection.py
├── 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.0
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.0.tar.gz | 11.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastapi_foundry-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.7 kB
Release files / fastapi_foundry-0.4.0.tar.gz
| Download URL | fastapi_foundry-0.4.0.tar.gz |
|---|---|
| Size | 11.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9d5e0c77e0d07bb2acb80f2869ad7f98cc3f44f9511f4d171caa39de0713f81d
|
|
BLAKE2b-256 checksum How to use checksums |
330bb2e57ae7545bc016f4399475182efeb29c84831e6b81baebf5446d63b13b
|
| 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.0-py3-none-any.whl
| Download URL | fastapi_foundry-0.4.0-py3-none-any.whl |
|---|---|
| Size | 15.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
89ba3e6a2281e4568e8516aa0ed8e000c3ec402bbe1c4c5a399c219f9f9a7d43
|
|
BLAKE2b-256 checksum How to use checksums |
0cbc7f7916bd0ed4ac658085eed49e55c0bb61ece3edff853b8c53d83455bebf
|
| 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}
|