Loading...
Loading...
Use when scaffolding production-ready FastAPI services with uv, SQLAlchemy, Alembic, Postgres, Docker, and CI gates.
npx skill4agent add ajrlewis/ai-skills architect-python-uv-fastapi-sqlalchemyuvNO_DOCKER=yesPROJECT_NAMEMODULE_NAMEPYTHON_VERSION3.12DATABASE_URLNO_DOCKERnoyesuvastral-sh/setup-uv3.12postgres:16-alpinecommand -v uv >/dev/null && uv --version || echo "uv-missing"
python3 --version
command -v docker >/dev/null && docker --version || echo "docker-missing"production-defaultNO_DOCKER=nolocal-no-dockerNO_DOCKER=yesoffline-smokeDockerfile.dockerignoredocker-compose.ymluv init --package {{PROJECT_NAME}}
cd {{PROJECT_NAME}}uv add fastapi "uvicorn[standard]" sqlalchemy asyncpg alembic pydantic-settings
uv add -d pytest pytest-asyncio httpx ruff mypysrc/{{MODULE_NAME}}/
api/routes/health.py
core/config.py
db/base.py
db/session.py
main.py
tests/uv run alembic init alembicalembic.inisqlalchemy.url${DATABASE_URL}alembic/env.pyBase.metadatasrc/{{MODULE_NAME}}/db/base.pyNO_DOCKER=noDockerfile.dockerignoredocker-compose.yml.github/workflows/ci.ymlNO_DOCKER=yessrc/{{MODULE_NAME}}/core/config.pyfrom pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
app_name: str = "api"
environment: str = "development"
database_url: str = "postgresql+asyncpg://app:app@localhost:5432/app"
settings = Settings()src/{{MODULE_NAME}}/db/base.pyfrom sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
passsrc/{{MODULE_NAME}}/db/session.pyfrom sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from {{MODULE_NAME}}.core.config import settings
engine = create_async_engine(settings.database_url, pool_pre_ping=True)
SessionLocal = async_sessionmaker(bind=engine, expire_on_commit=False)src/{{MODULE_NAME}}/api/routes/health.pyfrom fastapi import APIRouter
router = APIRouter()
@router.get("/healthz", tags=["health"])
async def healthcheck() -> dict[str, str]:
return {"status": "ok"}src/{{MODULE_NAME}}/main.pyfrom fastapi import FastAPI
from {{MODULE_NAME}}.api.routes.health import router as health_router
app = FastAPI(title="{{PROJECT_NAME}}")
app.include_router(health_router)DockerfileFROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS build
WORKDIR /app
COPY pyproject.toml uv.lock ./
COPY src ./src
RUN uv sync --frozen --no-dev
FROM python:3.12-slim AS run
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
RUN useradd --create-home --shell /bin/bash app
COPY /app/.venv /app/.venv
COPY src ./src
COPY alembic ./alembic
COPY alembic.ini ./
ENV PATH="/app/.venv/bin:$PATH"
USER app
EXPOSE 8000
CMD ["uvicorn", "{{MODULE_NAME}}.main:app", "--host", "0.0.0.0", "--port", "8000"].dockerignore.git
.venv
__pycache__
.pytest_cache
.mypy_cache
.ruff_cache
*.pyc
dist
builddocker-compose.ymlservices:
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: app
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 5s
timeout: 5s
retries: 20
volumes:
- pg_data:/var/lib/postgresql/data
api:
build: .
environment:
DATABASE_URL: postgresql+asyncpg://app:app@db:5432/app
depends_on:
db:
condition: service_healthy
ports:
- "8000:8000"
volumes:
pg_data:ports: - "8000:8000"apidocker run-p 8000:8000DATABASE_URLdocker compose.github/workflows/ci.ymlname: ci
on:
push:
pull_request:
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: astral-sh/setup-uv@v5
- name: Install deps
run: uv sync --frozen --dev
- name: Ruff
run: uv run ruff check .
- name: Ruff Docstrings
run: uv run ruff check . --select D
- name: Mypy
run: uv run mypy src
- name: Pytest
run: uv run pytest -q
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
push: false
tags: {{PROJECT_NAME}}:ci
cache-from: type=gha
cache-to: type=gha,mode=maxsqlalchemy.ext.asyncioasyncpg.envdocker composeNO_DOCKER=yesuv.lockuv sync --frozenuv run ruff check .
uv run ruff check . --select D
uv run mypy src
uv run pytest -q
uv run alembic upgrade head
test -f uv.lock
docker build -t {{PROJECT_NAME}}:local .
docker compose up -d --build
docker compose ps
curl http://localhost:8000/healthzlocal-no-dockerNO_DOCKER=yesuv run ruff check .
uv run ruff check . --select D
uv run mypy src
uv run pytest -q
uv run alembic upgrade headoffline-smokepython3 -m compileall src
test -f Dockerfile || echo "docker-artifacts-missing-in-offline-smoke"