Skip to content

Latest commit

 

History

History
122 lines (91 loc) · 4.16 KB

File metadata and controls

122 lines (91 loc) · 4.16 KB

Architecture

Overview

flowchart TB
    subgraph User["User Interaction"]
        CLI["uvx create-awesome-python-app\n--template <slug> --addons <ext>"]
    end

    subgraph Registry["Template Registry"]
        JSON["templates.json\n(categories, templates, extensions)"]
    end

    subgraph Merge["Merge Process"]
        Template["Base Template\n(template/type)"]
        Ext1["Extension 1\n(ext/type)"]
        Ext2["Extension 2\n(ext/type)"]
        Merged["Merged Project\nCopy-only semantics"]
    end

    subgraph Result["Generated Output"]
        Project["~/my-new-project\n(pyproject.toml, src/, tests/, docs/)"]
        Git["git init\n(skipped if CPA_SKIP_GIT=1)"]
        Install["uv sync\n(requires pyproject.toml,\n skipped with --no-install)"]
    end

    CLI --> JSON
    JSON --> Template
    Template --> Ext1
    Ext1 --> Ext2
    Ext2 --> Merged
    Merged --> Project
    Project --> Git
    Project --> Install

    style CLI fill:#e1f5fe
    style JSON fill:#f3e5f5
    style Merged fill:#e8f5e9
    style Project fill:#fff3e0
    style Git fill:#ffe0b2
    style Install fill:#ffe0b2
Loading

How the system works

A user runs:

uvx create-awesome-python-app --template <slug> --addons <ext1> <ext2>

CPA resolves each slug to a url in templates.json, downloads the directories, merges them with copy-only semantics, and writes the final project to disk. The merge order is: base template files → each extension in order (later layers overwrite).

templates.json structure

Three top-level keys: categories, templates, extensions.

Every template and extension requires: name, slug, description, url, type, category, labels.

Interactive options live in cpa.config.json inside the template directory (not in templates.json).

The type system

type connects templates to extensions. A template has a single string type. An extension has a string or array of strings. An extension is compatible with a template when the template's type appears in the extension's type list.

compatible = [ext.type].flat().includes(template.type)

Template types

Slug Type
fastapi-starter fastapi-backend
cli-starter cli-app
celery-worker celery-worker
django-api django-backend
uv-workspace-starter uv-workspace
mlops-sklearn-starter mlops-sklearn

Generation flow

  1. Resolve url for template and each selected extension from templates.json (or file:// / GitHub URL)
  2. Clone or open the source directory (cached under ~/.cache/cpa for remote repos)
  3. For each layer, copy files from template/ subdirectory when present, otherwise from the layer root
  4. Run uv sync when pyproject.toml exists (unless --no-install)
  5. Initialize a git repository (unless CPA_SKIP_GIT=1)

Current limitations (vs CNA)

Feature CNA CPA
EJS / Jinja .template files EJS Jinja2 in create-python-app-core (rolling out)
.append files Yes Rolling out in core
Manifest merge for extensions package/index.js pyproject.toml merge in core (rolling out)
Bracket [dir]/ renaming Yes Planned

Compose file naming matches CNA: prefer compose.yml, not docker-compose.yml.

Repository layout

cpa-templates/
├── templates.json          # Registry (served to CLI via raw GitHub URL)
├── templates.schema.json   # JSON Schema for templates.json
├── templates/              # Base project starters
├── extensions/             # Optional layers
├── scripts/                # CI helpers (validate-registry.py, generate-matrix.py)
├── ci/                     # Curated L3 profiles
├── .github/                # Workflows, issue templates, dependabot
└── docs/                   # Authoring and testing guides

Related repositories

  • create-python-app — CLI monorepo (create-awesome-python-app, create-python-app-core)
  • cpa-templates (this repo) — template and extension bank

Maintenance

Operational runbooks for CI, dependencies, security, releases, and template work live under docs/MAINTENANCE_RUNBOOK.md.