CLI tool to put teams in pole position when starting enterprise FastAPI projects
Project description
PolePosition
A CLI tool that puts teams in pole position when starting enterprise FastAPI projects.
PolePosition helps you keep FastAPI's speed while avoiding the usual setup drag of enterprise backend work. It gives you a structured, production-minded starting point from day one.
Create a new project:
polepos start myapp --install
If you prefer not to generate Python bytecode while developing locally:
polepos start myapp --no-bytecode
Example Output
$ polepos start myapp --install
Created project: myapp
Installing project dependencies with uv...
Dependencies installed successfully.
Next steps:
cd myapp
cp .env.example .env
alembic upgrade head
uv run python -m myapp.run
Why PolePosition?
PolePosition is named for the same reason teams use it: to start enterprise FastAPI development from pole position.
FastAPI projects should start fast, clean, and predictable, even when the target is a larger production system.
PolePosition provides:
- A scalable project structure
- Environment-based configuration
- Alembic-based database migrations
- Built-in logging
- Testing setup
- Module-oriented organization for growing codebases
- A ready-to-run FastAPI application
No boilerplate. No setup friction.
Why not just FastAPI?
FastAPI is excellent, but starting a new project often involves:
- Recreating the same structure
- Setting up logging and configuration
- Defining module boundaries
- Wiring database foundations
- Organizing modules manually
PolePosition removes that overhead by providing a clean, production-ready starting point out of the box.
Installation
PolePosition follows a uv-first workflow for installation, dependency sync, migrations, and local development.
uv tool install poleposition
or
pip install poleposition
Quick Start
polepos start myapp --install
cd myapp
cp .env.example .env
alembic upgrade head
uv run python -m myapp.run
Or start the generated app with Docker and PostgreSQL:
docker compose up --build
docker compose run --rm app uv run alembic upgrade head
Create and run migrations:
alembic upgrade head
alembic revision --autogenerate -m "add garage table"
Open your API documentation:
http://127.0.0.1:8000/docs
Usage
Create a project
polepos start myapp --install
--install runs uv sync inside the generated project for you.
--no-bytecode configures the generated runner, Alembic entrypoint, and test
fixture setup to disable Python bytecode writes during common local workflows.
Project names:
- Must not be empty
- Must not contain whitespace
- May use hyphens like
my-app - Are normalized to a Python package name like
my_app
Manual setup
polepos start myapp
cd myapp
cp .env.example .env
uv sync
alembic upgrade head
uv run python -m myapp.run
Add modules
polepos add module garage
Database commands
polepos db upgrade
polepos db revision -m "add garage table"
polepos db downgrade -1
Docker workflow
Generated projects include a Dockerfile, .dockerignore, and compose.yaml
so you can start the app with PostgreSQL in containers.
cp .env.example .env
docker compose up --build
docker compose run --rm app uv run alembic upgrade head
The compose setup uses the generated run.py entrypoint and overrides
DATABASE_URL so the app talks to the bundled PostgreSQL service. If you
already have PostgreSQL on 5432, change POSTGRES_PORT in .env before
starting the compose stack.
Logging
Generated projects use get_logger(__name__) from bootstrap.logging as the preferred logging entrypoint.
from shop_api.bootstrap.logging import get_logger
logger = get_logger(__name__)
Runtime configuration
Generated projects include src/<package>/run.py as the preferred local and production-friendly entrypoint.
Use:
uv run python -m shop_api.run
The runner is configured from settings.py and .env, including:
APP_HOSTAPP_PORTAPP_RELOADLOG_LEVELUVICORN_WORKERSUVICORN_ACCESS_LOGUVICORN_PROXY_HEADERSUVICORN_FORWARDED_ALLOW_IPSUVICORN_SERVER_HEADERUVICORN_DATE_HEADERUVICORN_TIMEOUT_KEEP_ALIVEUVICORN_TIMEOUT_GRACEFUL_SHUTDOWNUVICORN_TIMEOUT_WORKER_HEALTHCHECKUVICORN_LIMIT_CONCURRENCYUVICORN_LIMIT_MAX_REQUESTSUVICORN_LIMIT_MAX_REQUESTS_JITTERUVICORN_BACKLOG
When the generated runner starts, it prints a compact startup table with the current service name, environment, API prefix, database backend, host, port, worker count, and docs URL.
CORS
Generated projects include settings-driven CORS support with development defaults for common localhost frontend origins.
You can control it from .env with:
CORS_ENABLEDCORS_ALLOW_ORIGINSCORS_ALLOW_ORIGIN_REGEXCORS_ALLOW_CREDENTIALSCORS_ALLOW_METHODSCORS_ALLOW_HEADERSCORS_EXPOSE_HEADERSCORS_MAX_AGE
The list-style fields accept JSON arrays in .env.
When to use which command
polepos startwhen you want to create a new FastAPI project with the PolePosition structurepolepos add modulewhen you want to add a new REST/domain module to an existing projectpolepos db upgradewhen you want to apply migrations to the databasepolepos db revision -m "..."when you changed models and need a new migrationpolepos db downgradewhen you need to roll back a migration
Help and version
polepos help
polepos version
CLI
polepos help
polepos start <name> [--install] [--no-bytecode]
polepos startproject <name> [--install] [--no-bytecode]
polepos add module <name>
polepos db upgrade [target]
polepos db revision -m "<message>"
polepos db downgrade <target>
polepos version
Project Structure
myapp/
├─ Dockerfile
├─ compose.yaml
├─ alembic.ini
├─ migrations/
│ └─ versions/
├─ pyproject.toml
├─ .dockerignore
├─ .env.example
├─ src/
│ └─ myapp/
│ ├─ run.py
│ ├─ main.py
│ ├─ app.py
│ ├─ settings.py
│ ├─ bootstrap/
│ ├─ api/
│ ├─ db/
│ ├─ domain/
│ └─ modules/
│ ├─ status/
│ └─ races/
└─ tests/
├─ integration/
└─ unit/
Status Endpoint
Check if your service is running:
GET /api/v1/status
{
"status": "ok",
"service": "myapp",
"environment": "development",
"version": "0.1.0",
"uptime_seconds": 12,
"timestamp": "2026-04-26T12:00:00Z"
}
Philosophy
PolePosition is built around a few principles:
- Minimal: no unnecessary abstractions
- Opinionated: sensible defaults
- Extensible: easy to grow into larger systems
The CLI is intentionally lightweight and avoids heavy templating engines.
Roadmap
- Project name validation
-
polepos add module - Alembic and database migrations
- Docker support
-
polepos db ...commands - JSON logging support
- Auth foundation
- Production-ready presets
Example Workflow
Here is a concrete example for a new PostgreSQL-backed FastAPI REST API project.
Create the project and install dependencies:
uv tool install poleposition
polepos start shop-api
cd shop-api
cp .env.example .env
uv sync
Or use the generated Docker workflow:
docker compose up --build
docker compose run --rm app uv run alembic upgrade head
Point the project to PostgreSQL in .env:
DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/shop_api
Apply the initial migration and start the API:
polepos db upgrade
uv run python -m shop_api.run
Add a new REST module:
polepos add module customers
Extend src/shop_api/modules/customers/model.py and schemas.py for your domain, then generate and apply a migration:
polepos db revision -m "add customers table"
polepos db upgrade
At that point, your project has:
- FastAPI app structure
- PostgreSQL-ready SQLAlchemy setup
- Alembic migration workflow
- A generated REST module with router, schemas, service, repository, and tests
That is the core PolePosition flow: start fast, add modules as the API grows, and evolve the database schema through the CLI.
Example: build a users REST API
If you want a REST API that returns users, the flow is:
Generate the module:
polepos add module users
Update src/shop_api/modules/users/model.py with user fields such as:
class Users(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
email: Mapped[str] = mapped_column(String(255), unique=True)
full_name: Mapped[str] = mapped_column(String(120))
is_active: Mapped[bool] = mapped_column(default=True)
Update schemas.py so the API returns those fields, then create and apply a migration:
polepos db revision -m "create users table"
polepos db upgrade
At that point, you already have the generated router shape for:
GET /api/v1/users/
POST /api/v1/users/
From there, you refine the generated module for your actual domain instead of starting from an empty project structure.
Contributing
Contributions are welcome. Feel free to open an issue or submit a pull request.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file poleposition-0.0.21.tar.gz.
File metadata
- Download URL: poleposition-0.0.21.tar.gz
- Upload date:
- Size: 37.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ab457465b2461b319ad495d7713b24ce4441500d67db8bb34c1a76b9c52d6f0
|
|
| MD5 |
c081611a3404dc55fef103f4cb88d3be
|
|
| BLAKE2b-256 |
c3889b04d00257b4ac4cdf128583ea430d59e568758d890ee9b255f36ece81de
|
File details
Details for the file poleposition-0.0.21-py3-none-any.whl.
File metadata
- Download URL: poleposition-0.0.21-py3-none-any.whl
- Upload date:
- Size: 54.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
734f413ecb855a000ffa7eb7689be1ce42c9b9bd8aaefe490be403bb5d0c242b
|
|
| MD5 |
c91b62802ee7a749a35bcf4e5ce8ac3d
|
|
| BLAKE2b-256 |
4c60431b4f31f1f4bb7c2bb89906d352810b54aef01efdd0ab6d2004dbcb4dac
|