Skip to main content

Project lifecycle CLI for starting and growing enterprise FastAPI projects

Project description

PolePosition

PolePosition logo

A project lifecycle CLI that puts teams in pole position when starting, growing, and maintaining enterprise FastAPI projects.

PolePosition helps you keep FastAPI's speed while avoiding the usual setup drag of enterprise backend work. It does more than render a project template: it gives teams commands for project creation, module growth, project checks, and migration workflows as the codebase evolves.

Start a new project lifecycle:

polepos start myapp --install

If you prefer not to generate Python bytecode while developing locally:

polepos start myapp --no-bytecode

PyPI version Python License


Example Output

$ polepos start myapp --install
Created project: myapp

Installing project dependencies...
Dependencies installed successfully with uv.

Next steps:
  cd myapp
  cp .env.example .env
  uv run 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 and keep it there as the project grows.

FastAPI projects should start fast, clean, and predictable, then stay easy to extend when the target is a larger production system.

PolePosition provides:

  • A scalable project structure
  • Environment-based configuration
  • Alembic-based database migrations
  • Lifecycle commands for project creation, module growth, project checks, and database migrations
  • Built-in logging
  • JWT-based endpoint authentication foundations
  • Testing setup
  • Module-oriented organization for growing codebases
  • A ready-to-run FastAPI application

Less boilerplate at project creation. Less lifecycle friction as the app grows.


Why not just FastAPI?

FastAPI is excellent, but turning it into a team-ready backend lifecycle often involves:

  • Recreating the same structure
  • Setting up logging and configuration
  • Defining module boundaries
  • Wiring database foundations
  • Organizing modules manually
  • Adding new modules without drifting from conventions
  • Keeping database migrations and model imports aligned

PolePosition removes that overhead with CLI workflows that create the project, grow the codebase, validate the project contract, and keep migrations first-class.


Documentation Map

Use these files to understand the repo quickly:


Installation

PolePosition recommends a uv-first workflow for installation, dependency sync, migrations, and local development. It also works with pip and a normal Python virtual environment.

uv tool install poleposition

or

pip install poleposition

Quick Start

Recommended uv workflow:

polepos start myapp --install
cd myapp
cp .env.example .env
uv run alembic upgrade head

uv run python -m myapp.run

Equivalent pip workflow:

pip install poleposition
polepos start myapp
cd myapp
cp .env.example .env
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
python -m alembic upgrade head

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:

uv run alembic upgrade head
uv run 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 when uv is available. If uv is not available, it creates .venv and installs the generated project with pip. --no-bytecode configures generated migration and runtime commands to start with PYTHONDONTWRITEBYTECODE=1, preventing bytecode cache writes from interpreter startup 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

With uv:

polepos start myapp
cd myapp

cp .env.example .env
uv sync
uv run alembic upgrade head

uv run python -m myapp.run

With pip:

polepos start myapp
cd myapp

cp .env.example .env
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
python -m alembic upgrade head

python -m myapp.run

Add modules

polepos add module garage
polepos add module assistant --template ai-prompt

standard is the default template for REST and domain modules. ai-prompt adds a provider-agnostic LLM endpoint skeleton with module-local prompt orchestration and shared integrations/llm adapters.

Add integrations

polepos add integration kafka
polepos add integration rabbitmq

Messaging integrations add helper modules for JSON message publishing, consumer construction, test doubles, settings, .env.example values, and transport dependencies. Kafka uses aiokafka; RabbitMQ uses aio-pika. Consumers are intentionally left as explicit worker/runtime code instead of being started inside the API process.

Project checks

polepos check

check runs the core project health checks for the current PolePosition project. It validates project identity, generated structure, Alembic config, managed markers, added module lifecycle wiring, and opt-in integration wiring used by commands such as polepos add module and polepos add integration.

Use it after adding modules or integrations, after resolving merge conflicts in managed files, and before handing a project to another teammate or coding agent. The command is read-only: it reports drift but does not rewrite files, install dependencies, run migrations, or contact external services.

The checks are organized into three layers:

  • Core checks for project identity, generated structure, Alembic files, and managed markers
  • Lifecycle checks for added module router/model/test wiring
  • Integration checks for Kafka, RabbitMQ, and LLM files, settings, env values, and dependencies

See Project Checks for detailed user guidance and the agent-facing check contract.

Database commands

polepos db upgrade
polepos db revision -m "add garage table"
polepos db downgrade -1

Database commands prefer uv run alembic ... when uv is available. Without uv, they run Alembic through the active virtualenv, the project .venv, or the first python on PATH.

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_HOST
  • APP_PORT
  • APP_RELOAD
  • LOG_LEVEL
  • UVICORN_WORKERS
  • UVICORN_ACCESS_LOG
  • UVICORN_PROXY_HEADERS
  • UVICORN_FORWARDED_ALLOW_IPS
  • UVICORN_SERVER_HEADER
  • UVICORN_DATE_HEADER
  • UVICORN_TIMEOUT_KEEP_ALIVE
  • UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN
  • UVICORN_TIMEOUT_WORKER_HEALTHCHECK
  • UVICORN_LIMIT_CONCURRENCY
  • UVICORN_LIMIT_MAX_REQUESTS
  • UVICORN_LIMIT_MAX_REQUESTS_JITTER
  • UVICORN_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_ENABLED
  • CORS_ALLOW_ORIGINS
  • CORS_ALLOW_ORIGIN_REGEX
  • CORS_ALLOW_CREDENTIALS
  • CORS_ALLOW_METHODS
  • CORS_ALLOW_HEADERS
  • CORS_EXPOSE_HEADERS
  • CORS_MAX_AGE

The list-style fields accept JSON arrays in .env.

Authentication

Generated projects include a minimal JWT-based authentication foundation with:

  • a public GET /api/v1/status endpoint
  • a protected GET /api/v1/profile/me endpoint
  • a role-gated GET /api/v1/profile/admin-preview endpoint
  • get_current_user and require_roles(...) helpers

Relevant auth settings:

  • AUTH_SECRET_KEY
  • AUTH_ALGORITHM
  • AUTH_ACCESS_TOKEN_EXPIRE_MINUTES
  • AUTH_ISSUER

JSON logging

Generated projects support both text and JSON logging formats.

Use:

  • LOG_FORMAT=text for local development
  • LOG_FORMAT=json for structured production logging

The JSON formatter includes:

  • timestamp
  • level
  • logger
  • message
  • app_name
  • environment
  • request_id

When to use which command

PolePosition is a lifecycle CLI, so the commands are meant to be used over time, not only on day one:

  • polepos start when you want to create a new FastAPI project with the PolePosition structure
  • polepos add module when you want to add a new REST/domain module or an AI prompt module to an existing project
  • polepos add integration kafka when you want Kafka producer and consumer wiring in an existing project
  • polepos add integration rabbitmq when you want RabbitMQ publisher and consumer wiring in an existing project
  • polepos check when you want to validate generated structure, Alembic config, managed markers, module wiring, and integration wiring
  • polepos db upgrade when you want to apply migrations to the database
  • polepos db revision -m "..." when you changed models and need a new migration
  • polepos db downgrade when you need to roll back a migration

Examples

Concrete scenarios live under examples/README.md:

  • auth foundation workflow
  • PostgreSQL-backed HTML swap workflow

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 add integration kafka
polepos add integration rabbitmq
polepos check
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:

  • Lifecycle-oriented: supports project creation, growth, checks, and migrations
  • Minimal: no unnecessary abstractions
  • Opinionated: sensible defaults
  • Extensible: easy to grow into larger systems

The CLI is intentionally lightweight and avoids heavy templating engines. Templates are an implementation detail; the product surface is the project lifecycle.


Roadmap

Completed Foundations

  • Project name validation
  • Enterprise FastAPI project lifecycle foundation
  • polepos add module for standard modules
  • polepos add module --template ai-prompt
  • polepos add integration kafka
  • polepos add integration rabbitmq
  • Alembic and database migrations
  • Docker and PostgreSQL local runtime support
  • polepos db ... commands
  • polepos check
  • Settings-driven CORS support
  • JWT-based endpoint authentication foundation
  • Structured JSON logging support
  • Example scenarios and architecture docs

Next Up

  • Stronger request-context logging path, method, status code, duration, and deeper request correlation
  • Full auth workflow login, password hashing, refresh tokens, and database-backed users
  • Production-ready presets stronger env defaults, deployment guidance, and safer runtime conventions
  • add module ergonomics better success output, more archetypes, and options like --api-only

Later Expansion

  • ai-openapi module template provider-agnostic prompt orchestration plus external API tool patterns
  • Richer AI provider adapters stronger out-of-the-box integrations beyond scaffold-level provider stubs
  • CI and quality presets starter workflows for linting, tests, and release automation
  • Broader deployment presets reverse proxy, worker/process guidance, and observability-friendly defaults

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

License

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

poleposition-0.0.23.tar.gz (67.7 kB view details)

Uploaded Source

Built Distribution

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

poleposition-0.0.23-py3-none-any.whl (99.9 kB view details)

Uploaded Python 3

File details

Details for the file poleposition-0.0.23.tar.gz.

File metadata

  • Download URL: poleposition-0.0.23.tar.gz
  • Upload date:
  • Size: 67.7 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

Hashes for poleposition-0.0.23.tar.gz
Algorithm Hash digest
SHA256 aab329d63baedb881a391d34ea8ac0e98d8d1dcf6dc661d8b5523b29b6453112
MD5 0ea2b4451dca4b4490dae2147d1df9af
BLAKE2b-256 25544d0b6c7f0122e6c091aee5e8261fc3b8c94e8ef69f1688d12c1014fe8f5b

See more details on using hashes here.

File details

Details for the file poleposition-0.0.23-py3-none-any.whl.

File metadata

  • Download URL: poleposition-0.0.23-py3-none-any.whl
  • Upload date:
  • Size: 99.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

Hashes for poleposition-0.0.23-py3-none-any.whl
Algorithm Hash digest
SHA256 ae1dafeadf1443eec8355da1f97a1ca080e94f92ddfeb4fd6d3f0dd372c02d89
MD5 eb34569bfbbe8b5f2dcb25fa22215cc4
BLAKE2b-256 533e21d2864948ce9840eb44443e3d49a2c8581b069c44c407df1714b2e80f4e

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