diff --git a/AGENTS.md b/AGENTS.md index 2d25e03..a579515 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,7 +22,7 @@ cd my-app && uv sync && uv run pytest # Add a local extension CI=true uv run create-awesome-python-app my-app \ --template "file://$PWD?subdir=templates/fastapi-starter" \ - --addons "file://$PWD?subdir=extensions/github-setup" \ + --addons "file://$PWD?subdir=extensions/all-github-setup" \ --no-interactive ``` diff --git a/README.md b/README.md index 92ad1c7..fc14644 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ uvx create-awesome-python-app # With template and extensions uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons github-setup python-docker + --addons github-setup fastapi-docker ``` For local development against this checkout: diff --git a/ci/profiles/celery-default.json b/ci/profiles/celery-default.json index cf9063f..4439fa1 100644 --- a/ci/profiles/celery-default.json +++ b/ci/profiles/celery-default.json @@ -2,5 +2,8 @@ "id": "celery-default", "description": "Celery worker with GitHub CI + Docker", "templateDir": "celery-worker", - "addons": ["github-setup", "python-docker"] + "addons": [ + "github-setup", + "celery-docker" + ] } diff --git a/ci/profiles/cli-default.json b/ci/profiles/cli-default.json index 3619ab4..5b6789d 100644 --- a/ci/profiles/cli-default.json +++ b/ci/profiles/cli-default.json @@ -2,5 +2,8 @@ "id": "cli-default", "description": "CLI tool with GitHub CI + Dev Container", "templateDir": "cli-starter", - "addons": ["github-setup", "python-devcontainer"] + "addons": [ + "github-setup", + "development-container" + ] } diff --git a/ci/profiles/django-default.json b/ci/profiles/django-default.json index c8d9729..d7ae5c1 100644 --- a/ci/profiles/django-default.json +++ b/ci/profiles/django-default.json @@ -1,6 +1,10 @@ { "id": "django-default", - "description": "Django API with GitHub CI + Dev Container", + "description": "Django API with GitHub CI + Docker + Dev Container", "templateDir": "django-api", - "addons": ["github-setup", "python-devcontainer"] + "addons": [ + "github-setup", + "development-container", + "django-docker" + ] } diff --git a/ci/profiles/fastapi-default.json b/ci/profiles/fastapi-default.json index 1bb87fe..43bb2d6 100644 --- a/ci/profiles/fastapi-default.json +++ b/ci/profiles/fastapi-default.json @@ -2,5 +2,9 @@ "id": "fastapi-default", "description": "Typical FastAPI API: GitHub CI + Docker + Postgres", "templateDir": "fastapi-starter", - "addons": ["github-setup", "python-docker", "python-postgres"] + "addons": [ + "github-setup", + "fastapi-docker", + "postgres" + ] } diff --git a/ci/profiles/fastapi-devcontainer.json b/ci/profiles/fastapi-devcontainer.json index f509eaf..036d4c3 100644 --- a/ci/profiles/fastapi-devcontainer.json +++ b/ci/profiles/fastapi-devcontainer.json @@ -2,5 +2,8 @@ "id": "fastapi-devcontainer", "description": "FastAPI with GitHub CI and VS Code Dev Container", "templateDir": "fastapi-starter", - "addons": ["github-setup", "python-devcontainer"] + "addons": [ + "github-setup", + "development-container" + ] } diff --git a/ci/profiles/uv-workspace-default.json b/ci/profiles/uv-workspace-default.json index d804b56..de7bd27 100644 --- a/ci/profiles/uv-workspace-default.json +++ b/ci/profiles/uv-workspace-default.json @@ -2,5 +2,7 @@ "id": "uv-workspace-default", "description": "uv workspace monorepo with GitHub CI", "templateDir": "uv-workspace-starter", - "addons": ["github-setup"] + "addons": [ + "github-setup" + ] } diff --git a/ci/profiles/uv-workspace-devcontainer.json b/ci/profiles/uv-workspace-devcontainer.json index 436f9e5..45e1e7a 100644 --- a/ci/profiles/uv-workspace-devcontainer.json +++ b/ci/profiles/uv-workspace-devcontainer.json @@ -2,5 +2,8 @@ "id": "uv-workspace-devcontainer", "description": "uv workspace monorepo with GitHub CI and VS Code Dev Container", "templateDir": "uv-workspace-starter", - "addons": ["github-setup", "python-devcontainer"] + "addons": [ + "github-setup", + "development-container" + ] } diff --git a/docs/AUTHORING.md b/docs/AUTHORING.md index f4e6719..c0de2dc 100644 --- a/docs/AUTHORING.md +++ b/docs/AUTHORING.md @@ -132,6 +132,17 @@ Examples: **Never** use a generic `python-*` folder/slug for overlays that write FastAPI `app/` paths or a FastAPI-only `CMD`. +CI enforces this in `scripts/ci/validate-registry.py`: folders must be `all-*`, or +`{stack}-*` matching the extension's single `type` (see `STACK_PREFIX_BY_TYPE`). + +### `incompatibleWith` (path collisions) + +Use symmetric `incompatibleWith` when two extensions would overwrite the same +generated paths (for example two Docker overlays that both ship `Dockerfile` / +`compose.yml` for the **same** template `type`). Today stack Docker extensions +are isolated by `type`; when a type gains a second packaging strategy, declare +mutual incompatibility like cna-templates does for Redux saga/thunk. + ### Template quality bar (every catalog template) Every template registered in `templates.json` must ship at least: diff --git a/docs/FUTURE_TEMPLATES.md b/docs/FUTURE_TEMPLATES.md index 96a7905..d3d019f 100644 --- a/docs/FUTURE_TEMPLATES.md +++ b/docs/FUTURE_TEMPLATES.md @@ -6,7 +6,7 @@ Planned templates and extensions not yet in `templates.json`. These are phased a | Slug | Type | Description | |------|------|-------------| -| `uv-workspace-starter` | `uv-workspace` | Python monorepo using uv workspaces: shared `packages/` libraries and `apps/` deployables with one lockfile, shared Ruff/Pyright/pytest, and a Typer CLI that consumes a local library. Compatible extensions: `github-setup`, `python-devcontainer`. | +| `uv-workspace-starter` | `uv-workspace` | Python monorepo using uv workspaces: shared `packages/` libraries and `apps/` deployables with one lockfile, shared Ruff/Pyright/pytest, and a Typer CLI that consumes a local library. Compatible extensions: `github-setup`, `development-container`. | ## Planned templates @@ -19,13 +19,13 @@ Planned templates and extensions not yet in `templates.json`. These are phased a - **When:** Command-line tools, internal utilities, or libraries shipped as console scripts. - **Stack:** `pyproject.toml` with `[project.scripts]`, Typer (or Click), pytest for CLI invocation tests. -- **Extensions:** `github-setup`, `python-devcontainer`; Docker extension optional for containerized CLI distribution. +- **Extensions:** `github-setup`, `development-container`; Docker extension optional for containerized CLI distribution. ### `celery-worker` - **When:** Background jobs, scheduled tasks, or async processing separate from an HTTP API. - **Stack:** Celery app module, worker/beat commands, health probe, example task. -- **Extensions:** `python-docker`, `python-postgres` (for result backend or ORM), message-broker compose under `docker/redis/` or similar. +- **Extensions:** `fastapi-docker`, `postgres` (for result backend or ORM), message-broker compose under `docker/redis/` or similar. ## Contributing diff --git a/docs/MAINTENANCE_CI.md b/docs/MAINTENANCE_CI.md index 303ff67..f26e424 100644 --- a/docs/MAINTENANCE_CI.md +++ b/docs/MAINTENANCE_CI.md @@ -104,7 +104,7 @@ Curated JSON under `ci/profiles/`. Validator enforces **one extension per catego REPO="$PWD" python scripts/ci/run-scaffold-check.py \ --template-url "file://$REPO?subdir=templates/fastapi-starter" \ - --addon-url "file://$REPO?subdir=extensions/python-docker" \ + --addon-url "file://$REPO?subdir=extensions/fastapi-docker" \ --workdir /tmp/cpa-check ``` diff --git a/docs/MAINTENANCE_TEMPLATES.md b/docs/MAINTENANCE_TEMPLATES.md index b4f0e5d..cd43b20 100644 --- a/docs/MAINTENANCE_TEMPLATES.md +++ b/docs/MAINTENANCE_TEMPLATES.md @@ -92,11 +92,11 @@ Key questions: ls extensions/ # Read the registry entry -grep -A 15 '"slug": "python-docker"' templates.json +grep -A 15 '"slug": "fastapi-docker"' templates.json # Read partial manifest and files -cat extensions/python-docker/pyproject.toml -ls -la extensions/python-docker +cat extensions/fastapi-docker/pyproject.toml +ls -la extensions/fastapi-docker ``` Key questions: diff --git a/docs/TESTING.md b/docs/TESTING.md index c75b06f..1fe8728 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -7,7 +7,7 @@ After entries are registered in `templates.json` and the CLI catalog points to t ```sh CI=true uvx create-awesome-python-app my-app \ --template fastapi-starter \ - --addons github-setup python-docker \ + --addons github-setup fastapi-docker \ --no-interactive cd my-app && uv sync && uv run ruff check . && uv run pytest ``` @@ -29,8 +29,8 @@ CI=true uvx create-awesome-python-app my-app \ CI=true uvx create-awesome-python-app my-app \ --template "file://$REPO?subdir=templates/fastapi-starter" \ --addons \ - "file://$REPO?subdir=extensions/github-setup" \ - "file://$REPO?subdir=extensions/python-docker" \ + "file://$REPO?subdir=extensions/all-github-setup" \ + "file://$REPO?subdir=extensions/fastapi-docker" \ --no-interactive cd my-app && uv sync && uv run pytest ``` diff --git a/extensions/python-devcontainer/README.md b/extensions/all-devcontainer/README.md similarity index 87% rename from extensions/python-devcontainer/README.md rename to extensions/all-devcontainer/README.md index 1cec78c..7acf2c3 100644 --- a/extensions/python-devcontainer/README.md +++ b/extensions/all-devcontainer/README.md @@ -1,6 +1,6 @@ # Dev Container (extension bank) -Maintainer-facing notes for the **python-devcontainer** extension in `cpa-templates`. +Maintainer-facing notes for the **development-container** extension in `cpa-templates`. Copied into generated projects (via `template/`): @@ -18,7 +18,7 @@ The bank `README.md` (this file) stays **outside** `template/` so it does not ov ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-devcontainer \ + --addons development-container \ --yes ``` diff --git a/extensions/python-devcontainer/template/.devcontainer/Dockerfile b/extensions/all-devcontainer/template/.devcontainer/Dockerfile similarity index 100% rename from extensions/python-devcontainer/template/.devcontainer/Dockerfile rename to extensions/all-devcontainer/template/.devcontainer/Dockerfile diff --git a/extensions/python-devcontainer/template/.devcontainer/devcontainer.json b/extensions/all-devcontainer/template/.devcontainer/devcontainer.json similarity index 100% rename from extensions/python-devcontainer/template/.devcontainer/devcontainer.json rename to extensions/all-devcontainer/template/.devcontainer/devcontainer.json diff --git a/extensions/python-devcontainer/template/docs/DEVCONTAINER_GUIDE.md b/extensions/all-devcontainer/template/docs/DEVCONTAINER_GUIDE.md similarity index 88% rename from extensions/python-devcontainer/template/docs/DEVCONTAINER_GUIDE.md rename to extensions/all-devcontainer/template/docs/DEVCONTAINER_GUIDE.md index d67d444..9054dde 100644 --- a/extensions/python-devcontainer/template/docs/DEVCONTAINER_GUIDE.md +++ b/extensions/all-devcontainer/template/docs/DEVCONTAINER_GUIDE.md @@ -2,7 +2,7 @@ ## Overview -The **python-devcontainer** extension opens the project in a [Dev Container](https://code.visualstudio.com/docs/devcontainers/containers) with Python 3.12 and [uv](https://docs.astral.sh/uv/). It is editor-focused and does not replace **python-docker** for deployment or CI image builds. You can use both: Dev Container for daily coding, Docker Compose for integration testing. +The **development-container** extension opens the project in a [Dev Container](https://code.visualstudio.com/docs/devcontainers/containers) with Python 3.12 and [uv](https://docs.astral.sh/uv/). It is editor-focused and does not replace **fastapi-docker** for deployment or CI image builds. You can use both: Dev Container for daily coding, Docker Compose for integration testing. ## What it adds @@ -37,7 +37,7 @@ uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 Port `8000` is forwarded — open http://localhost:8000/docs. -### With python-postgres +### With postgres The Dev Container does not start Postgres automatically. Options: diff --git a/extensions/python-devcontainer/template/docs/README.md.append b/extensions/all-devcontainer/template/docs/README.md.append similarity index 100% rename from extensions/python-devcontainer/template/docs/README.md.append rename to extensions/all-devcontainer/template/docs/README.md.append diff --git a/extensions/github-setup/README.md b/extensions/all-github-setup/README.md similarity index 100% rename from extensions/github-setup/README.md rename to extensions/all-github-setup/README.md diff --git a/extensions/github-setup/template/.github/CODE_OF_CONDUCT.md b/extensions/all-github-setup/template/.github/CODE_OF_CONDUCT.md similarity index 100% rename from extensions/github-setup/template/.github/CODE_OF_CONDUCT.md rename to extensions/all-github-setup/template/.github/CODE_OF_CONDUCT.md diff --git a/extensions/github-setup/template/.github/ISSUE_TEMPLATE/bug-report.yml b/extensions/all-github-setup/template/.github/ISSUE_TEMPLATE/bug-report.yml similarity index 100% rename from extensions/github-setup/template/.github/ISSUE_TEMPLATE/bug-report.yml rename to extensions/all-github-setup/template/.github/ISSUE_TEMPLATE/bug-report.yml diff --git a/extensions/github-setup/template/.github/ISSUE_TEMPLATE/config.yml b/extensions/all-github-setup/template/.github/ISSUE_TEMPLATE/config.yml similarity index 100% rename from extensions/github-setup/template/.github/ISSUE_TEMPLATE/config.yml rename to extensions/all-github-setup/template/.github/ISSUE_TEMPLATE/config.yml diff --git a/extensions/github-setup/template/.github/ISSUE_TEMPLATE/documentation.yml b/extensions/all-github-setup/template/.github/ISSUE_TEMPLATE/documentation.yml similarity index 100% rename from extensions/github-setup/template/.github/ISSUE_TEMPLATE/documentation.yml rename to extensions/all-github-setup/template/.github/ISSUE_TEMPLATE/documentation.yml diff --git a/extensions/github-setup/template/.github/ISSUE_TEMPLATE/feature-request.yml b/extensions/all-github-setup/template/.github/ISSUE_TEMPLATE/feature-request.yml similarity index 100% rename from extensions/github-setup/template/.github/ISSUE_TEMPLATE/feature-request.yml rename to extensions/all-github-setup/template/.github/ISSUE_TEMPLATE/feature-request.yml diff --git a/extensions/github-setup/template/.github/PULL_REQUEST_TEMPLATE.md b/extensions/all-github-setup/template/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from extensions/github-setup/template/.github/PULL_REQUEST_TEMPLATE.md rename to extensions/all-github-setup/template/.github/PULL_REQUEST_TEMPLATE.md diff --git a/extensions/github-setup/template/.github/dependabot.yml b/extensions/all-github-setup/template/.github/dependabot.yml similarity index 100% rename from extensions/github-setup/template/.github/dependabot.yml rename to extensions/all-github-setup/template/.github/dependabot.yml diff --git a/extensions/github-setup/template/.github/workflows/ci.yml b/extensions/all-github-setup/template/.github/workflows/ci.yml similarity index 100% rename from extensions/github-setup/template/.github/workflows/ci.yml rename to extensions/all-github-setup/template/.github/workflows/ci.yml diff --git a/extensions/github-setup/template/.github/workflows/mega-linter.yml b/extensions/all-github-setup/template/.github/workflows/mega-linter.yml similarity index 100% rename from extensions/github-setup/template/.github/workflows/mega-linter.yml rename to extensions/all-github-setup/template/.github/workflows/mega-linter.yml diff --git a/extensions/github-setup/template/.github/workflows/pr-review.yml b/extensions/all-github-setup/template/.github/workflows/pr-review.yml similarity index 100% rename from extensions/github-setup/template/.github/workflows/pr-review.yml rename to extensions/all-github-setup/template/.github/workflows/pr-review.yml diff --git a/extensions/github-setup/template/.github/workflows/todo.yml b/extensions/all-github-setup/template/.github/workflows/todo.yml similarity index 100% rename from extensions/github-setup/template/.github/workflows/todo.yml rename to extensions/all-github-setup/template/.github/workflows/todo.yml diff --git a/extensions/github-setup/template/.mega-linter.yml b/extensions/all-github-setup/template/.mega-linter.yml similarity index 100% rename from extensions/github-setup/template/.mega-linter.yml rename to extensions/all-github-setup/template/.mega-linter.yml diff --git a/extensions/github-setup/template/docs/GITHUB_SETUP_GUIDE.md b/extensions/all-github-setup/template/docs/GITHUB_SETUP_GUIDE.md similarity index 100% rename from extensions/github-setup/template/docs/GITHUB_SETUP_GUIDE.md rename to extensions/all-github-setup/template/docs/GITHUB_SETUP_GUIDE.md diff --git a/extensions/github-setup/template/docs/README.md.append b/extensions/all-github-setup/template/docs/README.md.append similarity index 100% rename from extensions/github-setup/template/docs/README.md.append rename to extensions/all-github-setup/template/docs/README.md.append diff --git a/extensions/github-setup/template/tools/danger/.gitignore b/extensions/all-github-setup/template/tools/danger/.gitignore similarity index 100% rename from extensions/github-setup/template/tools/danger/.gitignore rename to extensions/all-github-setup/template/tools/danger/.gitignore diff --git a/extensions/github-setup/template/tools/danger/dangerfile.ts b/extensions/all-github-setup/template/tools/danger/dangerfile.ts similarity index 100% rename from extensions/github-setup/template/tools/danger/dangerfile.ts rename to extensions/all-github-setup/template/tools/danger/dangerfile.ts diff --git a/extensions/github-setup/template/tools/danger/package.json b/extensions/all-github-setup/template/tools/danger/package.json similarity index 100% rename from extensions/github-setup/template/tools/danger/package.json rename to extensions/all-github-setup/template/tools/danger/package.json diff --git a/extensions/github-setup/template/tools/danger/tsconfig.json b/extensions/all-github-setup/template/tools/danger/tsconfig.json similarity index 100% rename from extensions/github-setup/template/tools/danger/tsconfig.json rename to extensions/all-github-setup/template/tools/danger/tsconfig.json diff --git a/extensions/python-postgres/README.md b/extensions/all-postgres/README.md similarity index 85% rename from extensions/python-postgres/README.md rename to extensions/all-postgres/README.md index 0b3232a..e607af9 100644 --- a/extensions/python-postgres/README.md +++ b/extensions/all-postgres/README.md @@ -1,6 +1,6 @@ # PostgreSQL (extension bank) -Maintainer-facing notes for the **python-postgres** extension in `cpa-templates`. +Maintainer-facing notes for the **postgres** extension in `cpa-templates`. Copied into generated projects (via `template/`): @@ -20,16 +20,16 @@ The bank `README.md` (this file) stays **outside** `template/` so it does not ov ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-postgres \ + --addons postgres \ --yes ``` -Often combined with `python-docker`: +Often combined with `fastapi-docker`: ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-docker python-postgres \ + --addons fastapi-docker postgres \ --yes ``` diff --git a/extensions/python-postgres/template/.env.example.append b/extensions/all-postgres/template/.env.example.append similarity index 78% rename from extensions/python-postgres/template/.env.example.append rename to extensions/all-postgres/template/.env.example.append index 63ff292..d8c2f90 100644 --- a/extensions/python-postgres/template/.env.example.append +++ b/extensions/all-postgres/template/.env.example.append @@ -1,5 +1,5 @@ -# PostgreSQL (python-postgres extension) +# PostgreSQL (postgres extension) # PostgreSQL (optional overlay) # DATABASE_URL=postgresql+psycopg://app:app@localhost:5432/app POSTGRES_USER=app diff --git a/extensions/python-postgres/template/docker/postgres/.env.example b/extensions/all-postgres/template/docker/postgres/.env.example similarity index 100% rename from extensions/python-postgres/template/docker/postgres/.env.example rename to extensions/all-postgres/template/docker/postgres/.env.example diff --git a/extensions/python-postgres/template/docker/postgres/compose.yml b/extensions/all-postgres/template/docker/postgres/compose.yml similarity index 100% rename from extensions/python-postgres/template/docker/postgres/compose.yml rename to extensions/all-postgres/template/docker/postgres/compose.yml diff --git a/extensions/python-postgres/template/docs/POSTGRES_GUIDE.md b/extensions/all-postgres/template/docs/POSTGRES_GUIDE.md similarity index 90% rename from extensions/python-postgres/template/docs/POSTGRES_GUIDE.md rename to extensions/all-postgres/template/docs/POSTGRES_GUIDE.md index ba5f1db..fe3f4af 100644 --- a/extensions/python-postgres/template/docs/POSTGRES_GUIDE.md +++ b/extensions/all-postgres/template/docs/POSTGRES_GUIDE.md @@ -2,7 +2,7 @@ ## Overview -The **python-postgres** extension adds a local Postgres 16 Compose service under `docker/postgres/`, merges the `psycopg[binary]` driver into `pyproject.toml`, and appends Postgres-related keys to `.env.example`. +The **postgres** extension adds a local Postgres 16 Compose service under `docker/postgres/`, merges the `psycopg[binary]` driver into `pyproject.toml`, and appends Postgres-related keys to `.env.example`. It ships the **database service and client library** — wire your ORM and migrations in application code after scaffold. @@ -29,7 +29,7 @@ Connect from the host: psql "postgresql://app:app@localhost:5432/app" ``` -### With python-docker +### With fastapi-docker ```sh docker compose -f compose.yml -f docker/postgres/compose.yml up --build @@ -59,7 +59,7 @@ Root `.env.example` gains these keys from `.env.example.append`: | `POSTGRES_DB` | `app` | Database name | | `DATABASE_URL` | (commented example) | e.g. `postgresql+psycopg://app:app@localhost:5432/app` | -When combined with **python-docker**, the postgres compose overlay sets: +When combined with **fastapi-docker**, the postgres compose overlay sets: ```env DATABASE_URL=postgresql+psycopg://app:app@db:5432/app diff --git a/extensions/python-postgres/template/docs/README.md.append b/extensions/all-postgres/template/docs/README.md.append similarity index 100% rename from extensions/python-postgres/template/docs/README.md.append rename to extensions/all-postgres/template/docs/README.md.append diff --git a/extensions/python-postgres/template/pyproject.toml b/extensions/all-postgres/template/pyproject.toml similarity index 100% rename from extensions/python-postgres/template/pyproject.toml rename to extensions/all-postgres/template/pyproject.toml diff --git a/extensions/celery-docker/README.md b/extensions/celery-docker/README.md new file mode 100644 index 0000000..8925d42 --- /dev/null +++ b/extensions/celery-docker/README.md @@ -0,0 +1,33 @@ +# Docker for Celery (extension bank) + +Maintainer-facing notes for the **celery-docker** extension. + +Copied into generated projects (via `template/`): + +| Path | Purpose | +|------|---------| +| `Dockerfile` | uv-based image; Celery worker CMD | +| `.dockerignore` | Excludes `.venv`, caches, git metadata | +| `compose.yml` | Dev worker compose (bind mount) | +| `compose.prod.yml` | Prod worker overlay | +| `docs/DOCKER_GUIDE.md` | Long-form guide | +| `docs/README.md.append` | Index bullet | + +Compose includes a Redis broker. Env vars are `BROKER_URL` / `RESULT_BACKEND` +(matching `worker/config.py`). Pair with `postgres` only when the worker also +needs a database. + +## Apply + +```sh +uvx create-awesome-python-app my-worker \ + --template celery-worker \ + --addons celery-docker \ + --yes +``` + +## Verify + +```sh +docker compose up --build +``` diff --git a/extensions/python-docker/template/.dockerignore b/extensions/celery-docker/template/.dockerignore similarity index 100% rename from extensions/python-docker/template/.dockerignore rename to extensions/celery-docker/template/.dockerignore diff --git a/extensions/celery-docker/template/Dockerfile b/extensions/celery-docker/template/Dockerfile new file mode 100644 index 0000000..197a70c --- /dev/null +++ b/extensions/celery-docker/template/Dockerfile @@ -0,0 +1,15 @@ +FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim + +WORKDIR /app + +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +COPY pyproject.toml README.md ./ +COPY worker ./worker + +RUN uv sync --no-dev + +CMD ["uv", "run", "celery", "-A", "worker.celery_app", "worker", "--loglevel=INFO"] diff --git a/extensions/celery-docker/template/compose.prod.yml b/extensions/celery-docker/template/compose.prod.yml new file mode 100644 index 0000000..6f93b03 --- /dev/null +++ b/extensions/celery-docker/template/compose.prod.yml @@ -0,0 +1,15 @@ +services: + redis: + image: redis:7-alpine + restart: always + worker: + build: . + env_file: + - .env + environment: + BROKER_URL: redis://redis:6379/0 + RESULT_BACKEND: redis://redis:6379/1 + restart: always + depends_on: + - redis + command: uv run celery -A worker.celery_app worker --loglevel=INFO --concurrency=2 diff --git a/extensions/celery-docker/template/compose.yml b/extensions/celery-docker/template/compose.yml new file mode 100644 index 0000000..bcbeadd --- /dev/null +++ b/extensions/celery-docker/template/compose.yml @@ -0,0 +1,17 @@ +services: + redis: + image: redis:7-alpine + ports: + - "6379:6379" + worker: + build: . + env_file: + - .env + environment: + BROKER_URL: redis://redis:6379/0 + RESULT_BACKEND: redis://redis:6379/1 + volumes: + - .:/app + depends_on: + - redis + command: uv run celery -A worker.celery_app worker --loglevel=INFO diff --git a/extensions/celery-docker/template/docs/DOCKER_GUIDE.md b/extensions/celery-docker/template/docs/DOCKER_GUIDE.md new file mode 100644 index 0000000..6b00b9d --- /dev/null +++ b/extensions/celery-docker/template/docs/DOCKER_GUIDE.md @@ -0,0 +1,46 @@ +# Docker guide (Celery) + +## Overview + +The **celery-docker** extension packages the Celery worker for local and +production-style containers, including a Redis broker service. + +## What it adds + +- `Dockerfile` — Python 3.12 + uv; copies `worker/`; runs Celery worker +- `compose.yml` / `compose.prod.yml` — `redis` + `worker` services +- Env overrides in Compose: `BROKER_URL` / `RESULT_BACKEND` point at the + `redis` service (not `localhost`) + +These names match `worker/config.py` (pydantic-settings fields `broker_url` / +`result_backend`). Do **not** use `CELERY_BROKER_URL` unless you also rename the +settings fields. + +## Usage + +```sh +docker compose up --build +``` + +## Verification + +1. `docker compose up --build` +2. Confirm Redis is healthy and the worker log shows it is ready +3. Enqueue a task (another shell / one-off container): + +```sh +docker compose exec worker uv run python -c \ + "from worker.tasks import ping; print(ping.delay().get(timeout=10))" +``` + +## Troubleshooting + +| Symptom | Fix | +|---------|-----| +| Cannot connect to Redis | Use `redis://redis:6379/0` inside Compose (service name), not `localhost` | +| Import errors for `worker` | Confirm `COPY worker` matches the template layout | +| Wrong env var name | Template reads `BROKER_URL` / `RESULT_BACKEND` | + +## Resources + +- [Celery first steps](https://docs.celeryq.dev/en/stable/getting-started/first-steps-with-celery.html) diff --git a/extensions/celery-docker/template/docs/README.md.append b/extensions/celery-docker/template/docs/README.md.append new file mode 100644 index 0000000..0734164 --- /dev/null +++ b/extensions/celery-docker/template/docs/README.md.append @@ -0,0 +1 @@ +- [Docker](./DOCKER_GUIDE.md) — container workflow for this worker diff --git a/extensions/django-docker/README.md b/extensions/django-docker/README.md new file mode 100644 index 0000000..0c4a61e --- /dev/null +++ b/extensions/django-docker/README.md @@ -0,0 +1,30 @@ +# Docker for Django (extension bank) + +Maintainer-facing notes for the **django-docker** extension. + +Copied into generated projects (via `template/`): + +| Path | Purpose | +|------|---------| +| `Dockerfile` | uv-based image; `gunicorn config.wsgi` | +| `.dockerignore` | Excludes `.venv`, caches, git metadata | +| `compose.yml` | Dev compose (`runserver` + bind mount) | +| `compose.prod.yml` | Prod overlay (`gunicorn`, restart always) | +| `docs/DOCKER_GUIDE.md` | Long-form guide | +| `docs/README.md.append` | Index bullet | + +## Apply + +```sh +uvx create-awesome-python-app my-api \ + --template django-api \ + --addons django-docker \ + --yes +``` + +## Verify + +```sh +docker compose up --build +curl -s http://localhost:8000/api/healthz/ +``` diff --git a/extensions/django-docker/template/.dockerignore b/extensions/django-docker/template/.dockerignore new file mode 100644 index 0000000..ac81cf1 --- /dev/null +++ b/extensions/django-docker/template/.dockerignore @@ -0,0 +1,11 @@ +.venv +__pycache__ +*.py[cod] +.pytest_cache +.ruff_cache +.git +.env +data +*.egg-info +dist +.mypy_cache diff --git a/extensions/django-docker/template/Dockerfile b/extensions/django-docker/template/Dockerfile new file mode 100644 index 0000000..cd76793 --- /dev/null +++ b/extensions/django-docker/template/Dockerfile @@ -0,0 +1,19 @@ +FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim + +WORKDIR /app + +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +COPY pyproject.toml README.md ./ +COPY manage.py ./ +COPY config ./config +COPY apps ./apps + +RUN uv sync --no-dev + +EXPOSE 8000 + +CMD ["uv", "run", "gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000"] diff --git a/extensions/django-docker/template/compose.prod.yml b/extensions/django-docker/template/compose.prod.yml new file mode 100644 index 0000000..03d33d9 --- /dev/null +++ b/extensions/django-docker/template/compose.prod.yml @@ -0,0 +1,9 @@ +services: + api: + build: . + ports: + - "8000:8000" + env_file: + - .env + restart: always + command: uv run gunicorn config.wsgi:application --bind 0.0.0.0:8000 diff --git a/extensions/django-docker/template/compose.yml b/extensions/django-docker/template/compose.yml new file mode 100644 index 0000000..1e4e31a --- /dev/null +++ b/extensions/django-docker/template/compose.yml @@ -0,0 +1,10 @@ +services: + api: + build: . + ports: + - "8000:8000" + env_file: + - .env + volumes: + - .:/app + command: uv run python manage.py runserver 0.0.0.0:8000 diff --git a/extensions/django-docker/template/docs/DOCKER_GUIDE.md b/extensions/django-docker/template/docs/DOCKER_GUIDE.md new file mode 100644 index 0000000..e0f698c --- /dev/null +++ b/extensions/django-docker/template/docs/DOCKER_GUIDE.md @@ -0,0 +1,49 @@ +# Docker guide (Django) + +## Overview + +The **django-docker** extension adds a reproducible container workflow for Django + DRF APIs. Compose files follow Create-Node-App naming: **`compose.yml`** / **`compose.prod.yml`**. + +## What it adds + +- `Dockerfile` — Python 3.12 + uv; copies `manage.py`, `config/`, `apps/`; runs `gunicorn config.wsgi` +- `compose.yml` — local `runserver` with bind mount +- `compose.prod.yml` — `gunicorn` without reload + +## Usage + +```sh +docker compose up --build +curl -s http://localhost:8000/api/healthz/ +``` + +Production-style: + +```sh +docker compose -f compose.prod.yml up --build -d +``` + +## Configuration + +| Variable | Purpose | +|----------|---------| +| `.env` | Loaded by Compose (`env_file`) | +| `DATABASE_URL` / Django `DATABASES` | Wire via settings; use hostname `db` when stacked with `postgres` | + +## Verification + +1. `docker compose up --build` +2. Hit `/api/healthz/` +3. `docker compose down` + +## Troubleshooting + +| Symptom | Fix | +|---------|-----| +| Module not found `apps` | Ensure Dockerfile `COPY apps` matches project layout | +| DB connection refused | Use Compose service hostname, not `localhost`, inside containers | + +## Resources + +- [Docker Compose](https://docs.docker.com/compose/) +- [Gunicorn](https://docs.gunicorn.org/) diff --git a/extensions/django-docker/template/docs/README.md.append b/extensions/django-docker/template/docs/README.md.append new file mode 100644 index 0000000..0daf9bd --- /dev/null +++ b/extensions/django-docker/template/docs/README.md.append @@ -0,0 +1 @@ +- [Docker](./DOCKER_GUIDE.md) — container workflow for this project diff --git a/extensions/python-auth-jwt/README.md b/extensions/fastapi-auth-jwt/README.md similarity index 89% rename from extensions/python-auth-jwt/README.md rename to extensions/fastapi-auth-jwt/README.md index 25c7065..4c989bc 100644 --- a/extensions/python-auth-jwt/README.md +++ b/extensions/fastapi-auth-jwt/README.md @@ -1,6 +1,6 @@ # Auth JWT (extension bank) -Maintainer-facing notes for the **python-auth-jwt** extension in `cpa-templates`. +Maintainer-facing notes for the **fastapi-auth-jwt** extension in `cpa-templates`. Copied into generated projects (via `template/`): @@ -19,7 +19,7 @@ The bank `README.md` (this file) stays **outside** `template/` so it does not ov ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-auth-jwt \ + --addons fastapi-auth-jwt \ --yes ``` diff --git a/extensions/python-auth-jwt/template/.env.example.append b/extensions/fastapi-auth-jwt/template/.env.example.append similarity index 61% rename from extensions/python-auth-jwt/template/.env.example.append rename to extensions/fastapi-auth-jwt/template/.env.example.append index cb09f00..a9ca938 100644 --- a/extensions/python-auth-jwt/template/.env.example.append +++ b/extensions/fastapi-auth-jwt/template/.env.example.append @@ -1,5 +1,5 @@ -# Auth JWT (python-auth-jwt extension) +# Auth JWT (fastapi-auth-jwt extension) JWT_SECRET=change-me JWT_ALGORITHM=HS256 JWT_EXPIRE_MINUTES=60 diff --git a/extensions/fastapi-auth-jwt/template/app/features/auth/__init__.py b/extensions/fastapi-auth-jwt/template/app/features/auth/__init__.py new file mode 100644 index 0000000..d3c26b9 --- /dev/null +++ b/extensions/fastapi-auth-jwt/template/app/features/auth/__init__.py @@ -0,0 +1 @@ +"""JWT auth feature skeleton (fastapi-auth-jwt extension).""" diff --git a/extensions/python-auth-jwt/template/app/features/auth/router.py b/extensions/fastapi-auth-jwt/template/app/features/auth/router.py similarity index 100% rename from extensions/python-auth-jwt/template/app/features/auth/router.py rename to extensions/fastapi-auth-jwt/template/app/features/auth/router.py diff --git a/extensions/python-auth-jwt/template/app/features/auth/schemas.py b/extensions/fastapi-auth-jwt/template/app/features/auth/schemas.py similarity index 100% rename from extensions/python-auth-jwt/template/app/features/auth/schemas.py rename to extensions/fastapi-auth-jwt/template/app/features/auth/schemas.py diff --git a/extensions/python-auth-jwt/template/app/features/auth/service.py b/extensions/fastapi-auth-jwt/template/app/features/auth/service.py similarity index 100% rename from extensions/python-auth-jwt/template/app/features/auth/service.py rename to extensions/fastapi-auth-jwt/template/app/features/auth/service.py diff --git a/extensions/python-auth-jwt/template/docs/AUTH_JWT_GUIDE.md b/extensions/fastapi-auth-jwt/template/docs/AUTH_JWT_GUIDE.md similarity index 92% rename from extensions/python-auth-jwt/template/docs/AUTH_JWT_GUIDE.md rename to extensions/fastapi-auth-jwt/template/docs/AUTH_JWT_GUIDE.md index 9e04dd0..935f095 100644 --- a/extensions/python-auth-jwt/template/docs/AUTH_JWT_GUIDE.md +++ b/extensions/fastapi-auth-jwt/template/docs/AUTH_JWT_GUIDE.md @@ -2,7 +2,7 @@ ## Overview -The **python-auth-jwt** extension adds a JWT + password-hashing skeleton for FastAPI starters: Pydantic schemas, `pwdlib` (Argon2) helpers, PyJWT encode/decode, and a demo `/auth` router with an in-memory user. +The **fastapi-auth-jwt** extension adds a JWT + password-hashing skeleton for FastAPI starters: Pydantic schemas, `pwdlib` (Argon2) helpers, PyJWT encode/decode, and a demo `/auth` router with an in-memory user. Replace the demo user and secret before any production use. diff --git a/extensions/python-auth-jwt/template/docs/README.md.append b/extensions/fastapi-auth-jwt/template/docs/README.md.append similarity index 100% rename from extensions/python-auth-jwt/template/docs/README.md.append rename to extensions/fastapi-auth-jwt/template/docs/README.md.append diff --git a/extensions/python-auth-jwt/template/pyproject.toml b/extensions/fastapi-auth-jwt/template/pyproject.toml similarity index 100% rename from extensions/python-auth-jwt/template/pyproject.toml rename to extensions/fastapi-auth-jwt/template/pyproject.toml diff --git a/extensions/python-docker/README.md b/extensions/fastapi-docker/README.md similarity index 89% rename from extensions/python-docker/README.md rename to extensions/fastapi-docker/README.md index 1aa8163..a62a471 100644 --- a/extensions/python-docker/README.md +++ b/extensions/fastapi-docker/README.md @@ -1,6 +1,6 @@ # Docker (extension bank) -Maintainer-facing notes for the **python-docker** extension in `cpa-templates`. +Maintainer-facing notes for the **fastapi-docker** extension in `cpa-templates`. Copied into generated projects (via `template/`): @@ -20,7 +20,7 @@ The bank `README.md` (this file) stays **outside** `template/` so it does not ov ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-docker \ + --addons fastapi-docker \ --yes ``` diff --git a/extensions/fastapi-docker/template/.dockerignore b/extensions/fastapi-docker/template/.dockerignore new file mode 100644 index 0000000..ac81cf1 --- /dev/null +++ b/extensions/fastapi-docker/template/.dockerignore @@ -0,0 +1,11 @@ +.venv +__pycache__ +*.py[cod] +.pytest_cache +.ruff_cache +.git +.env +data +*.egg-info +dist +.mypy_cache diff --git a/extensions/python-docker/template/Dockerfile b/extensions/fastapi-docker/template/Dockerfile similarity index 100% rename from extensions/python-docker/template/Dockerfile rename to extensions/fastapi-docker/template/Dockerfile diff --git a/extensions/python-docker/template/compose.prod.yml b/extensions/fastapi-docker/template/compose.prod.yml similarity index 100% rename from extensions/python-docker/template/compose.prod.yml rename to extensions/fastapi-docker/template/compose.prod.yml diff --git a/extensions/python-docker/template/compose.yml b/extensions/fastapi-docker/template/compose.yml similarity index 100% rename from extensions/python-docker/template/compose.yml rename to extensions/fastapi-docker/template/compose.yml diff --git a/extensions/python-docker/template/docs/DOCKER_GUIDE.md b/extensions/fastapi-docker/template/docs/DOCKER_GUIDE.md similarity index 88% rename from extensions/python-docker/template/docs/DOCKER_GUIDE.md rename to extensions/fastapi-docker/template/docs/DOCKER_GUIDE.md index bfea746..61d016e 100644 --- a/extensions/python-docker/template/docs/DOCKER_GUIDE.md +++ b/extensions/fastapi-docker/template/docs/DOCKER_GUIDE.md @@ -2,9 +2,9 @@ ## Overview -The **python-docker** extension adds a reproducible container workflow for FastAPI (or other uv-based Python API) projects. Compose files follow Create-Node-App naming: **`compose.yml`** / **`compose.prod.yml`** (not `docker-compose.yml`). +The **fastapi-docker** extension adds a reproducible container workflow for FastAPI (or other uv-based Python API) projects. Compose files follow Create-Node-App naming: **`compose.yml`** / **`compose.prod.yml`** (not `docker-compose.yml`). -Use it when you want local containers without installing Python on the host, or when you ship the API as an image. Pair with **python-postgres** when you need a database service. +Use it when you want local containers without installing Python on the host, or when you ship the API as an image. Pair with **postgres** when you need a database service. ## What it adds @@ -36,7 +36,7 @@ docker compose -f compose.yml -f compose.prod.yml up --build -d The prod overlay removes the source bind mount and `--reload`, and sets `restart: always`. -### With python-postgres +### With postgres ```sh docker compose -f compose.yml -f docker/postgres/compose.yml up --build @@ -72,7 +72,7 @@ For production-style runs, set `DEBUG=false` in `.env`. Pin base image tags in ` | Module not found inside container | Image built without latest `pyproject.toml` | Rebuild: `docker compose build --no-cache` | | Health 404 | Wrong prefix | Check `API_PREFIX` / scaffold `apiPrefix` (default `/api/v1/healthz`) | | Env vars missing | No `.env` | Copy `.env.example` → `.env` | -| Postgres hostname errors | Using `localhost` inside compose | Use service name `db` when stacked with `python-postgres` | +| Postgres hostname errors | Using `localhost` inside compose | Use service name `db` when stacked with `postgres` | ## Resources diff --git a/extensions/python-docker/template/docs/README.md.append b/extensions/fastapi-docker/template/docs/README.md.append similarity index 100% rename from extensions/python-docker/template/docs/README.md.append rename to extensions/fastapi-docker/template/docs/README.md.append diff --git a/extensions/python-redis/README.md b/extensions/fastapi-redis/README.md similarity index 84% rename from extensions/python-redis/README.md rename to extensions/fastapi-redis/README.md index 75f20a8..57fb9a9 100644 --- a/extensions/python-redis/README.md +++ b/extensions/fastapi-redis/README.md @@ -1,6 +1,6 @@ # Redis (extension bank) -Maintainer-facing notes for the **python-redis** extension in `cpa-templates`. +Maintainer-facing notes for the **fastapi-redis** extension in `cpa-templates`. Copied into generated projects (via `template/`): @@ -20,16 +20,16 @@ The bank `README.md` (this file) stays **outside** `template/` so it does not ov ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-redis \ + --addons fastapi-redis \ --yes ``` -Often combined with `python-docker`: +Often combined with `fastapi-docker`: ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-docker python-redis \ + --addons fastapi-docker fastapi-redis \ --yes ``` diff --git a/extensions/python-redis/template/.env.example.append b/extensions/fastapi-redis/template/.env.example.append similarity index 51% rename from extensions/python-redis/template/.env.example.append rename to extensions/fastapi-redis/template/.env.example.append index d29aa39..c9aa352 100644 --- a/extensions/python-redis/template/.env.example.append +++ b/extensions/fastapi-redis/template/.env.example.append @@ -1,3 +1,3 @@ -# Redis (python-redis extension) +# Redis (fastapi-redis extension) REDIS_URL=redis://localhost:6379/0 diff --git a/extensions/python-redis/template/app/core/redis_client.py b/extensions/fastapi-redis/template/app/core/redis_client.py similarity index 83% rename from extensions/python-redis/template/app/core/redis_client.py rename to extensions/fastapi-redis/template/app/core/redis_client.py index 02446f2..73dcfe2 100644 --- a/extensions/python-redis/template/app/core/redis_client.py +++ b/extensions/fastapi-redis/template/app/core/redis_client.py @@ -1,4 +1,4 @@ -"""Redis client helper (python-redis extension).""" +"""Redis client helper (fastapi-redis extension).""" from __future__ import annotations diff --git a/extensions/python-redis/template/docker/redis/compose.yml b/extensions/fastapi-redis/template/docker/redis/compose.yml similarity index 100% rename from extensions/python-redis/template/docker/redis/compose.yml rename to extensions/fastapi-redis/template/docker/redis/compose.yml diff --git a/extensions/python-redis/template/docs/README.md.append b/extensions/fastapi-redis/template/docs/README.md.append similarity index 100% rename from extensions/python-redis/template/docs/README.md.append rename to extensions/fastapi-redis/template/docs/README.md.append diff --git a/extensions/python-redis/template/docs/REDIS_GUIDE.md b/extensions/fastapi-redis/template/docs/REDIS_GUIDE.md similarity index 92% rename from extensions/python-redis/template/docs/REDIS_GUIDE.md rename to extensions/fastapi-redis/template/docs/REDIS_GUIDE.md index d8c3328..05602c4 100644 --- a/extensions/python-redis/template/docs/REDIS_GUIDE.md +++ b/extensions/fastapi-redis/template/docs/REDIS_GUIDE.md @@ -2,7 +2,7 @@ ## Overview -The **python-redis** extension adds a Redis client dependency, a small `get_redis()` helper, env docs, and a local Redis 7 Compose service under `docker/redis/`. +The **fastapi-redis** extension adds a Redis client dependency, a small `get_redis()` helper, env docs, and a local Redis 7 Compose service under `docker/redis/`. Use it for cache, sessions, rate limits, or as a broker when pairing with Celery later. @@ -25,7 +25,7 @@ uv sync uv run python -c "from app.core.redis_client import get_redis; print(get_redis().ping())" ``` -### With python-docker +### With fastapi-docker ```sh docker compose -f compose.yml -f docker/redis/compose.yml up --build diff --git a/extensions/python-redis/template/pyproject.toml b/extensions/fastapi-redis/template/pyproject.toml similarity index 100% rename from extensions/python-redis/template/pyproject.toml rename to extensions/fastapi-redis/template/pyproject.toml diff --git a/extensions/python-sentry/README.md b/extensions/fastapi-sentry/README.md similarity index 89% rename from extensions/python-sentry/README.md rename to extensions/fastapi-sentry/README.md index f0c4b85..8aacab6 100644 --- a/extensions/python-sentry/README.md +++ b/extensions/fastapi-sentry/README.md @@ -1,6 +1,6 @@ # Sentry (extension bank) -Maintainer-facing notes for the **python-sentry** extension in `cpa-templates`. +Maintainer-facing notes for the **fastapi-sentry** extension in `cpa-templates`. Copied into generated projects (via `template/`): @@ -19,7 +19,7 @@ The bank `README.md` (this file) stays **outside** `template/` so it does not ov ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-sentry \ + --addons fastapi-sentry \ --yes ``` diff --git a/extensions/python-sentry/template/.env.example.append b/extensions/fastapi-sentry/template/.env.example.append similarity index 67% rename from extensions/python-sentry/template/.env.example.append rename to extensions/fastapi-sentry/template/.env.example.append index 40d2c60..6fbc5bc 100644 --- a/extensions/python-sentry/template/.env.example.append +++ b/extensions/fastapi-sentry/template/.env.example.append @@ -1,5 +1,5 @@ -# Sentry (python-sentry extension) +# Sentry (fastapi-sentry extension) SENTRY_DSN= SENTRY_TRACES_SAMPLE_RATE=0.0 SENTRY_ENVIRONMENT=development diff --git a/extensions/python-sentry/template/app/core/sentry.py b/extensions/fastapi-sentry/template/app/core/sentry.py similarity index 91% rename from extensions/python-sentry/template/app/core/sentry.py rename to extensions/fastapi-sentry/template/app/core/sentry.py index 9570700..72718d6 100644 --- a/extensions/python-sentry/template/app/core/sentry.py +++ b/extensions/fastapi-sentry/template/app/core/sentry.py @@ -1,4 +1,4 @@ -"""Sentry initialization helper (python-sentry extension).""" +"""Sentry initialization helper (fastapi-sentry extension).""" from __future__ import annotations diff --git a/extensions/python-sentry/template/docs/README.md.append b/extensions/fastapi-sentry/template/docs/README.md.append similarity index 100% rename from extensions/python-sentry/template/docs/README.md.append rename to extensions/fastapi-sentry/template/docs/README.md.append diff --git a/extensions/python-sentry/template/docs/SENTRY_GUIDE.md b/extensions/fastapi-sentry/template/docs/SENTRY_GUIDE.md similarity index 90% rename from extensions/python-sentry/template/docs/SENTRY_GUIDE.md rename to extensions/fastapi-sentry/template/docs/SENTRY_GUIDE.md index 789fda9..5aa243a 100644 --- a/extensions/python-sentry/template/docs/SENTRY_GUIDE.md +++ b/extensions/fastapi-sentry/template/docs/SENTRY_GUIDE.md @@ -2,7 +2,7 @@ ## Overview -The **python-sentry** extension adds `sentry-sdk[fastapi]` and a small `init_sentry()` helper. Initialization is a **no-op** when `SENTRY_DSN` is empty, so local development stays quiet until you opt in. +The **fastapi-sentry** extension adds `sentry-sdk[fastapi]` and a small `init_sentry()` helper. Initialization is a **no-op** when `SENTRY_DSN` is empty, so local development stays quiet until you opt in. ## What it adds diff --git a/extensions/python-sentry/template/pyproject.toml b/extensions/fastapi-sentry/template/pyproject.toml similarity index 100% rename from extensions/python-sentry/template/pyproject.toml rename to extensions/fastapi-sentry/template/pyproject.toml diff --git a/extensions/python-sqlalchemy/README.md b/extensions/fastapi-sqlalchemy/README.md similarity index 84% rename from extensions/python-sqlalchemy/README.md rename to extensions/fastapi-sqlalchemy/README.md index db31eae..deb6cd2 100644 --- a/extensions/python-sqlalchemy/README.md +++ b/extensions/fastapi-sqlalchemy/README.md @@ -1,6 +1,6 @@ # SQLAlchemy + Alembic (extension bank) -Maintainer-facing notes for the **python-sqlalchemy** extension in `cpa-templates`. +Maintainer-facing notes for the **fastapi-sqlalchemy** extension in `cpa-templates`. Copied into generated projects (via `template/`): @@ -20,16 +20,16 @@ The bank `README.md` (this file) stays **outside** `template/` so it does not ov ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-sqlalchemy \ + --addons fastapi-sqlalchemy \ --yes ``` -Often combined with `python-postgres`: +Often combined with `postgres`: ```sh uvx create-awesome-python-app my-api \ --template fastapi-starter \ - --addons python-postgres python-sqlalchemy \ + --addons postgres fastapi-sqlalchemy \ --yes ``` diff --git a/extensions/python-sqlalchemy/template/.env.example.append b/extensions/fastapi-sqlalchemy/template/.env.example.append similarity index 72% rename from extensions/python-sqlalchemy/template/.env.example.append rename to extensions/fastapi-sqlalchemy/template/.env.example.append index 34a6155..b1f59b9 100644 --- a/extensions/python-sqlalchemy/template/.env.example.append +++ b/extensions/fastapi-sqlalchemy/template/.env.example.append @@ -1,5 +1,5 @@ -# SQLAlchemy / Alembic (python-sqlalchemy extension) +# SQLAlchemy / Alembic (fastapi-sqlalchemy extension) # DATABASE_URL=postgresql+psycopg://app:app@localhost:5432/app # For SQLite local smoke without Postgres: # DATABASE_URL=sqlite:///./app.db diff --git a/extensions/python-sqlalchemy/template/alembic.ini b/extensions/fastapi-sqlalchemy/template/alembic.ini similarity index 100% rename from extensions/python-sqlalchemy/template/alembic.ini rename to extensions/fastapi-sqlalchemy/template/alembic.ini diff --git a/extensions/python-sqlalchemy/template/alembic/env.py b/extensions/fastapi-sqlalchemy/template/alembic/env.py similarity index 100% rename from extensions/python-sqlalchemy/template/alembic/env.py rename to extensions/fastapi-sqlalchemy/template/alembic/env.py diff --git a/extensions/python-sqlalchemy/template/alembic/script.py.mako b/extensions/fastapi-sqlalchemy/template/alembic/script.py.mako similarity index 100% rename from extensions/python-sqlalchemy/template/alembic/script.py.mako rename to extensions/fastapi-sqlalchemy/template/alembic/script.py.mako diff --git a/extensions/python-sqlalchemy/template/alembic/versions/.gitkeep b/extensions/fastapi-sqlalchemy/template/alembic/versions/.gitkeep similarity index 100% rename from extensions/python-sqlalchemy/template/alembic/versions/.gitkeep rename to extensions/fastapi-sqlalchemy/template/alembic/versions/.gitkeep diff --git a/extensions/python-sqlalchemy/template/app/db/__init__.py b/extensions/fastapi-sqlalchemy/template/app/db/__init__.py similarity index 59% rename from extensions/python-sqlalchemy/template/app/db/__init__.py rename to extensions/fastapi-sqlalchemy/template/app/db/__init__.py index f4b307a..ff53ea7 100644 --- a/extensions/python-sqlalchemy/template/app/db/__init__.py +++ b/extensions/fastapi-sqlalchemy/template/app/db/__init__.py @@ -1,4 +1,4 @@ -"""Database session helpers (python-sqlalchemy extension).""" +"""Database session helpers (fastapi-sqlalchemy extension).""" from app.db.session import get_db, session_factory diff --git a/extensions/python-sqlalchemy/template/app/db/base.py b/extensions/fastapi-sqlalchemy/template/app/db/base.py similarity index 100% rename from extensions/python-sqlalchemy/template/app/db/base.py rename to extensions/fastapi-sqlalchemy/template/app/db/base.py diff --git a/extensions/python-sqlalchemy/template/app/db/session.py b/extensions/fastapi-sqlalchemy/template/app/db/session.py similarity index 100% rename from extensions/python-sqlalchemy/template/app/db/session.py rename to extensions/fastapi-sqlalchemy/template/app/db/session.py diff --git a/extensions/python-sqlalchemy/template/docs/README.md.append b/extensions/fastapi-sqlalchemy/template/docs/README.md.append similarity index 100% rename from extensions/python-sqlalchemy/template/docs/README.md.append rename to extensions/fastapi-sqlalchemy/template/docs/README.md.append diff --git a/extensions/python-sqlalchemy/template/docs/SQLALCHEMY_GUIDE.md b/extensions/fastapi-sqlalchemy/template/docs/SQLALCHEMY_GUIDE.md similarity index 87% rename from extensions/python-sqlalchemy/template/docs/SQLALCHEMY_GUIDE.md rename to extensions/fastapi-sqlalchemy/template/docs/SQLALCHEMY_GUIDE.md index 983fa9b..d64e930 100644 --- a/extensions/python-sqlalchemy/template/docs/SQLALCHEMY_GUIDE.md +++ b/extensions/fastapi-sqlalchemy/template/docs/SQLALCHEMY_GUIDE.md @@ -2,9 +2,9 @@ ## Overview -The **python-sqlalchemy** extension adds SQLAlchemy 2.x session helpers and an Alembic migration layout for FastAPI starters. It merges `sqlalchemy` and `alembic` into `pyproject.toml` and documents `DATABASE_URL` in `.env.example`. +The **fastapi-sqlalchemy** extension adds SQLAlchemy 2.x session helpers and an Alembic migration layout for FastAPI starters. It merges `sqlalchemy` and `alembic` into `pyproject.toml` and documents `DATABASE_URL` in `.env.example`. -Pair with **python-postgres** when you want a local Postgres Compose service and the `psycopg` driver; the default URL is SQLite for smoke tests without Docker. +Pair with **postgres** when you want a local Postgres Compose service and the `psycopg` driver; the default URL is SQLite for smoke tests without Docker. ## What it adds @@ -42,7 +42,7 @@ def list_items(db: Session = Depends(get_db)) -> list[dict]: ... ``` -### With python-postgres +### With postgres ```sh docker compose -f docker/postgres/compose.yml up -d diff --git a/extensions/python-sqlalchemy/template/pyproject.toml b/extensions/fastapi-sqlalchemy/template/pyproject.toml similarity index 100% rename from extensions/python-sqlalchemy/template/pyproject.toml rename to extensions/fastapi-sqlalchemy/template/pyproject.toml diff --git a/extensions/python-auth-jwt/template/app/features/auth/__init__.py b/extensions/python-auth-jwt/template/app/features/auth/__init__.py deleted file mode 100644 index 18b0211..0000000 --- a/extensions/python-auth-jwt/template/app/features/auth/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""JWT auth feature skeleton (python-auth-jwt extension).""" diff --git a/scripts/ci/validate-registry.py b/scripts/ci/validate-registry.py index e7afd0f..56b702e 100755 --- a/scripts/ci/validate-registry.py +++ b/scripts/ci/validate-registry.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""L0 integrity: registry paths on disk + schema shape.""" +"""L0 integrity: registry paths on disk + schema shape + extension naming law.""" from __future__ import annotations @@ -19,6 +19,50 @@ template_dir, ) +# Folder prefix required for stack-bound extensions (single type). +STACK_PREFIX_BY_TYPE: dict[str, str] = { + "fastapi-backend": "fastapi", + "django-backend": "django", + "celery-worker": "celery", + "cli-app": "cli", + "uv-workspace": "uv-workspace", +} + + +def validate_extension_folder_name(directory: str, types: list[str], slug: str) -> list[str]: + errors: list[str] = [] + if directory.startswith("python-"): + errors.append( + f"extension {slug}: folder `{directory}` must not use deprecated python-* prefix" + ) + return errors + + if directory.startswith("all-"): + return errors + + if len(types) != 1: + errors.append( + f"extension {slug}: multi-type overlays must use all-* folder " + f"(got `{directory}` for types={types})" + ) + return errors + + prefix = STACK_PREFIX_BY_TYPE.get(types[0]) + if prefix is None: + errors.append( + f"extension {slug}: unknown type {types[0]!r} for stack folder check " + f"(update STACK_PREFIX_BY_TYPE)" + ) + return errors + + expected = f"{prefix}-" + if not directory.startswith(expected): + errors.append( + f"extension {slug}: folder `{directory}` must be `all-*` or start with " + f"`{expected}` for type {types[0]}" + ) + return errors + def main() -> None: registry = load_registry() @@ -35,30 +79,37 @@ def main() -> None: category_slugs = {c["slug"] for c in registry.get("categories", [])} for template in registry.get("templates", []): + slug = template.get("slug", "") directory = template_dir(template) if not directory: - errors.append(f"template {template.get('slug')}: cannot parse url") + errors.append(f"template {slug}: cannot parse url") continue path = on_disk_path_for_entry("template", template) if path is None or not path.is_dir(): - errors.append(f"template {template.get('slug')}: missing on-disk path {path}") + errors.append(f"template {slug}: missing on-disk path {path}") + continue category = template.get("category") if category not in category_slugs: - errors.append(f"template {template.get('slug')}: unknown category {category}") + errors.append(f"template {slug}: unknown category {category}") for extension in registry.get("extensions", []): + slug = extension.get("slug", "") directory = extension_dir(extension) if not directory: - errors.append(f"extension {extension.get('slug')}: cannot parse url") + errors.append(f"extension {slug}: cannot parse url") continue path = on_disk_path_for_entry("extension", extension) if path is None or not path.is_dir(): - errors.append(f"extension {extension.get('slug')}: missing on-disk path {path}") + errors.append(f"extension {slug}: missing on-disk path {path}") + continue category = extension.get("category") if category not in category_slugs: - errors.append(f"extension {extension.get('slug')}: unknown category {category}") - if not as_types(extension.get("type")): - errors.append(f"extension {extension.get('slug')}: empty type") + errors.append(f"extension {slug}: unknown category {category}") + types = as_types(extension.get("type")) + if not types: + errors.append(f"extension {slug}: empty type") + else: + errors.extend(validate_extension_folder_name(directory, types, slug)) # Bidirectional incompatibleWith when declared for other_slug in extension.get("incompatibleWith") or []: @@ -67,11 +118,11 @@ def main() -> None: ) if other is None: errors.append( - f"extension {extension['slug']}: incompatibleWith unknown slug {other_slug}" + f"extension {slug}: incompatibleWith unknown slug {other_slug}" ) - elif extension["slug"] not in (other.get("incompatibleWith") or []): + elif slug not in (other.get("incompatibleWith") or []): errors.append( - f"extension {extension['slug']}: incompatibleWith {other_slug} " + f"extension {slug}: incompatibleWith {other_slug} " "is not symmetric" ) diff --git a/templates.json b/templates.json index c3b390c..7d0c87e 100644 --- a/templates.json +++ b/templates.json @@ -105,7 +105,7 @@ { "name": "FastAPI Starter", "slug": "fastapi-starter", - "description": "Production-ready FastAPI API with uv, Ruff, pytest, mypy, pyright, and pydantic-settings", + "description": "Production-ready FastAPI API with feature-based layout, uv, Ruff, pytest, mypy, pyright, and pydantic-settings. The reference CPA backend template.", "url": "https://github.com/Create-Python-App/cpa-templates?subdir=templates/fastapi-starter", "type": "fastapi-backend", "category": "backend-applications", @@ -123,7 +123,7 @@ { "name": "CLI Starter", "slug": "cli-starter", - "description": "Typer CLI with uv, Ruff, pytest, and a console script entry point", + "description": "Typer CLI with multi-command layout, uv, Ruff, pytest, and a console script entry point. Best for internal tools and shippable CLIs.", "url": "https://github.com/Create-Python-App/cpa-templates?subdir=templates/cli-starter", "type": "cli-app", "category": "cli-applications", @@ -137,7 +137,7 @@ { "name": "Celery Worker", "slug": "celery-worker", - "description": "Celery worker with Redis defaults, pydantic-settings, and eager-mode tests", + "description": "Celery worker with modular tasks, Redis defaults, pydantic-settings, and eager-mode tests. Choose it for background jobs outside the HTTP process.", "url": "https://github.com/Create-Python-App/cpa-templates?subdir=templates/celery-worker", "type": "celery-worker", "category": "backend-applications", @@ -152,7 +152,7 @@ { "name": "Django API", "slug": "django-api", - "description": "Django + DRF API starter with uv, Ruff, pytest-django, and health probes", + "description": "Django + DRF API with feature apps, OpenAPI-friendly health probes, uv, Ruff, and pytest-django. Use when you want Django's ORM and admin with a clean API layout.", "url": "https://github.com/Create-Python-App/cpa-templates?subdir=templates/django-api", "type": "django-backend", "category": "backend-applications", @@ -167,7 +167,7 @@ { "name": "uv Workspace Starter", "slug": "uv-workspace-starter", - "description": "Python monorepo using uv workspaces: shared packages/ libraries and apps/ deployables with one lockfile, Ruff, Pyright, and pytest", + "description": "Python monorepo using uv workspaces: shared packages/ libraries and apps/ deployables with one lockfile, Ruff, Pyright, and pytest.", "url": "https://github.com/Create-Python-App/cpa-templates?subdir=templates/uv-workspace-starter", "type": "uv-workspace", "category": "monorepo", @@ -184,8 +184,8 @@ { "name": "GitHub Setup", "slug": "github-setup", - "description": "GitHub Actions CI, MegaLinter, Danger PR review, todo-to-issue, Dependabot, and issue/PR templates", - "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/github-setup", + "description": "GitHub Actions CI, MegaLinter, Danger PR review, todo-to-issue, Dependabot, and issue/PR templates. Use for any CPA template that lives on GitHub.", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/all-github-setup", "type": [ "celery-worker", "cli-app", @@ -203,27 +203,29 @@ ] }, { - "name": "Python Docker", - "slug": "python-docker", - "description": "Dockerfile, compose.yml, and compose.prod.yml for local and containerized runs", - "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/python-docker", + "name": "Development Container", + "slug": "development-container", + "description": "VS Code Dev Container with Python 3.12 and uv for consistent editor environments across stacks.", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/all-devcontainer", "type": [ "celery-worker", "cli-app", - "fastapi-backend" + "django-backend", + "fastapi-backend", + "uv-workspace" ], - "category": "containers", + "category": "editor", "labels": [ - "Docker", - "DevOps", - "Container" + "DevContainer", + "VS Code", + "uv" ] }, { - "name": "Python Postgres", - "slug": "python-postgres", - "description": "PostgreSQL service under docker/postgres/compose.yml plus env examples", - "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/python-postgres", + "name": "Postgres", + "slug": "postgres", + "description": "PostgreSQL 16 Compose service under docker/postgres/ plus env examples. Infra-only \u2014 does not write application ORM code.", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/all-postgres", "type": [ "celery-worker", "django-backend", @@ -237,29 +239,55 @@ ] }, { - "name": "Python Dev Container", - "slug": "python-devcontainer", - "description": "VS Code Dev Container with Python 3.12 and uv", - "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/python-devcontainer", + "name": "FastAPI Docker", + "slug": "fastapi-docker", + "description": "Dockerfile and Compose for FastAPI (uvicorn app.main:app). Reach for it when containerizing the FastAPI starter.", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/fastapi-docker", "type": [ - "celery-worker", - "cli-app", - "django-backend", - "fastapi-backend", - "uv-workspace" + "fastapi-backend" ], - "category": "editor", + "category": "containers", "labels": [ - "DevContainer", - "VS Code", - "uv" + "Docker", + "FastAPI", + "Container" ] }, { - "name": "Python SQLAlchemy", - "slug": "python-sqlalchemy", - "description": "SQLAlchemy 2.x session helpers and Alembic migrations for FastAPI", - "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/python-sqlalchemy", + "name": "Django Docker", + "slug": "django-docker", + "description": "Dockerfile and Compose for Django (runserver / gunicorn config.wsgi). Use with django-api.", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/django-docker", + "type": [ + "django-backend" + ], + "category": "containers", + "labels": [ + "Docker", + "Django", + "Container" + ] + }, + { + "name": "Celery Docker", + "slug": "celery-docker", + "description": "Dockerfile and Compose for a Celery worker plus Redis broker. Pair with a reachable BROKER_URL (Compose sets redis://redis:6379/0).", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/celery-docker", + "type": [ + "celery-worker" + ], + "category": "containers", + "labels": [ + "Docker", + "Celery", + "Container" + ] + }, + { + "name": "FastAPI SQLAlchemy", + "slug": "fastapi-sqlalchemy", + "description": "SQLAlchemy 2.x session helpers and Alembic migrations for FastAPI (writes app/db/).", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/fastapi-sqlalchemy", "type": [ "fastapi-backend" ], @@ -268,14 +296,14 @@ "SQLAlchemy", "Alembic", "ORM", - "Database" + "FastAPI" ] }, { - "name": "Python Redis", - "slug": "python-redis", - "description": "Redis client helper and local Compose service", - "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/python-redis", + "name": "FastAPI Redis", + "slug": "fastapi-redis", + "description": "Redis client helper under app/core plus a local Redis Compose service for FastAPI apps.", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/fastapi-redis", "type": [ "fastapi-backend" ], @@ -283,14 +311,14 @@ "labels": [ "Redis", "Cache", - "Queue" + "FastAPI" ] }, { - "name": "Python Sentry", - "slug": "python-sentry", - "description": "Sentry SDK for FastAPI with env-driven init helper", - "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/python-sentry", + "name": "FastAPI Sentry", + "slug": "fastapi-sentry", + "description": "Sentry SDK helper for FastAPI with env-driven init (no-op without SENTRY_DSN).", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/fastapi-sentry", "type": [ "fastapi-backend" ], @@ -298,14 +326,14 @@ "labels": [ "Sentry", "Observability", - "Errors" + "FastAPI" ] }, { - "name": "Python Auth JWT", - "slug": "python-auth-jwt", - "description": "JWT auth feature skeleton with password hashing helpers", - "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/python-auth-jwt", + "name": "FastAPI Auth JWT", + "slug": "fastapi-auth-jwt", + "description": "JWT auth feature skeleton under app/features/auth for FastAPI starters.", + "url": "https://github.com/Create-Python-App/cpa-templates?subdir=extensions/fastapi-auth-jwt", "type": [ "fastapi-backend" ], @@ -313,6 +341,7 @@ "labels": [ "Auth", "JWT", + "FastAPI", "Security" ] } diff --git a/templates/fastapi-starter/CONTRIBUTING.md b/templates/fastapi-starter/CONTRIBUTING.md index 061fd56..46fb333 100644 --- a/templates/fastapi-starter/CONTRIBUTING.md +++ b/templates/fastapi-starter/CONTRIBUTING.md @@ -20,7 +20,7 @@ Thanks for your interest in contributing to this project! This document is the h - Python matching `requires-python` in `pyproject.toml` (3.12+) - [uv](https://docs.astral.sh/uv/) installed -- Optional: Docker if using `python-docker` / `python-postgres` extensions +- Optional: Docker if using `fastapi-docker` / `postgres` extensions ## Project Bootstrap diff --git a/templates/fastapi-starter/QUALITY.md b/templates/fastapi-starter/QUALITY.md index d1c434c..7fdbecc 100644 --- a/templates/fastapi-starter/QUALITY.md +++ b/templates/fastapi-starter/QUALITY.md @@ -20,20 +20,20 @@ Use this checklist before calling a FastAPI starter "mature" for CPA. ## Migrations -This starter does not ship an ORM by default. When using the `python-sqlalchemy` -and/or `python-postgres` extensions: +This starter does not ship an ORM by default. When using the `fastapi-sqlalchemy` +and/or `postgres` extensions: ```sh -uv run alembic upgrade head # after adding python-sqlalchemy +uv run alembic upgrade head # after adding fastapi-sqlalchemy ``` ## Extension slots (catalog slugs) | Slug | Role | |------|------| -| `python-docker` | Dockerfile + Compose | -| `python-postgres` | Postgres Compose + `psycopg` | -| `python-devcontainer` | VS Code Dev Container | +| `fastapi-docker` | Dockerfile + Compose | +| `postgres` | Postgres Compose + `psycopg` | +| `development-container` | VS Code Dev Container | | `github-setup` | GitHub Actions / Dependabot / templates | Example: @@ -41,9 +41,9 @@ Example: ```sh uvx create-awesome-python-app@latest my-api \ --template fastapi-starter \ - --addons python-docker \ - --addons python-postgres \ - --addons python-devcontainer \ + --addons fastapi-docker \ + --addons postgres \ + --addons development-container \ --no-interactive ``` diff --git a/templates/fastapi-starter/README.md b/templates/fastapi-starter/README.md index 7fe4f36..af83a91 100644 --- a/templates/fastapi-starter/README.md +++ b/templates/fastapi-starter/README.md @@ -86,7 +86,7 @@ Scripts and notes for shipping: | `uv run uvicorn app.main:app --host 0.0.0.0 --port 8000` | Production-style ASGI process | | Health probe | `GET {API_PREFIX}/healthz` → `dev_code: HEALTH_OK` | -Full guidance: [Deployment](./docs/DEPLOYMENT.md). Pair with the `python-docker` / `python-postgres` extensions when you need containers or a database. +Full guidance: [Deployment](./docs/DEPLOYMENT.md). Pair with the `fastapi-docker` / `postgres` extensions when you need containers or a database. ## Configuration @@ -117,13 +117,13 @@ Use catalog slugs (not informal names like `docker` / `vscode`): | Slug | Adds | |------|------| -| `python-docker` | Dockerfile + Compose | -| `python-postgres` | Postgres Compose + driver | -| `python-devcontainer` | VS Code Dev Container | +| `fastapi-docker` | Dockerfile + Compose | +| `postgres` | Postgres Compose + driver | +| `development-container` | VS Code Dev Container | | `github-setup` | CI / Dependabot / issue templates | -Migrations are not bundled in the base starter. Add `python-sqlalchemy` (and usually -`python-postgres`) when you need Alembic/`DATABASE_URL` workflows. +Migrations are not bundled in the base starter. Add `fastapi-sqlalchemy` (and usually +`postgres`) when you need Alembic/`DATABASE_URL` workflows. ## Quality bar diff --git a/templates/fastapi-starter/docs/DEPLOYMENT.md b/templates/fastapi-starter/docs/DEPLOYMENT.md index 598360f..8dd5694 100644 --- a/templates/fastapi-starter/docs/DEPLOYMENT.md +++ b/templates/fastapi-starter/docs/DEPLOYMENT.md @@ -62,7 +62,7 @@ Expect HTTP `200` and `"dev_code": "HEALTH_OK"`. ### Docker Compose -Pair this API with the `python-docker` / `python-postgres` extensions when you +Pair this API with the `fastapi-docker` / `postgres` extensions when you need local containers or a database. Keep the API service dependent on DB health before accepting traffic.