Skip to content

Repository files navigation

FastAPI Copier Scaffold

本仓库维护一份固定 FastAPI 工程基线的 Copier 模板。template/ 是唯一生成源;仓库根目录的 copier.yml、维护环境、设计文档等不会进入生成项目。

首版只收集五个项目身份字段:project_nameproject_titleproject_descriptionproject_versionredis_prefix。它不会按答案增删功能,也不会改变 appconfigmain:app 的既有结构。

项目来源

本项目基于 Narotoconan/fastapi-template 改造,并在原有 FastAPI 工程模板基础上封装为 Copier 脚手架。

上游同步维护

仓库使用 inspect → prepare → apply → verify → accept 流程同步 Narotoconan/fastapi-template 的指定 tag。

通过 Codex 使用(推荐)

在本仓库的 Codex 任务中,正常情况下只需依次发送以下三条消息,无需自己运行脚本:

  1. 发起只读分析:

    同步上游 tag v0.2.6
    

    Codex 会自动执行 inspect 和 prepare,报告版本身份、文件分类、风险与冲突,然后停在 apply 审批点; 此时不会修改 template/ 或正式 baseline。

  2. prepare 状态为 ready 后,复制 Codex 提供的完整摘要进行批准:

    批准 apply prepare SHA256 <Codex 提供的 prepare-report SHA-256>
    

    Codex 只会应用该报告绑定的候选,并自动执行 verify。验证失败时会停止,不会推进 baseline。

  3. verify 全部必要门禁通过后,再复制 Codex 提供的完整摘要:

    批准 accept verify SHA256 <Codex 提供的 verify-report SHA-256>
    

    Codex 会再次确认上游身份,并只更新 upstream-sync.toml 中的 baseline tag、commit 和 tree。

摘要必须使用 Codex 本次报告提供的完整值,不能省略、猜测或复用旧摘要。如果 prepare 报告存在冲突或其他 阻断项,不要发送 apply 批准;可以继续发送:

请处理 prepare 报告中允许人工解决的文本冲突并重新 prepare;遇到其他阻断项时停止。

Codex 只会为已登记 Jinja 输出路径的 README 或普通文本内容冲突使用可审计的 resolutions/ 文件;未知路径、 review-required、对象 guard、结构冲突和未登记路径仍会停止。accept 完成后也不会自动 commit、打 tag、 push 或发布。

底层命令与维护边界

Codex 实际编排仓库中的 scripts/upstream_sync.py,不会自行重新实现同步算法。需要排查或手工运行时,对应 命令如下:

# 只读分析
uv run --locked python scripts/upstream_sync.py inspect --target <upstream-tag>
uv run --locked python scripts/upstream_sync.py prepare --target <upstream-tag>

# 仅用于 prepare 报告允许人工解决的文本冲突
uv run --locked python scripts/upstream_sync.py prepare \
  --target <upstream-tag> \
  --resolution-dir tmp/upstream-sync/<blocked-run>/resolutions

# 写入获批候选并自动验证
uv run --locked python scripts/upstream_sync.py apply \
  --prepare-report tmp/upstream-sync/<run-id>/prepare-report.json \
  --approve-prepare-sha256 <prepare-report-sha256>

# 独立复核或安全复用验证结果
uv run --locked python scripts/upstream_sync.py verify \
  --apply-report tmp/upstream-sync/<run-id>/apply-report.json

# 验证通过后推进正式 baseline
uv run --locked python scripts/upstream_sync.py accept \
  --verify-report tmp/upstream-sync/<run-id>/verify-report.json \
  --approve-verify-sha256 <verify-report-sha256>

报告和临时视图只写入已忽略的 tmp/upstream-sync/<run-id>/。完整契约见 docs/adr/0002-upstream-sync-contract.md;当前上游身份、路径政策和 Jinja 映射以 upstream-sync.toml 为准。目标上游测试作为不可信分析材料保留,未执行的验证会在报告中明确列为风险。

正式同步前,同步实现、测试、template/copier.ymltemplate-contract.jsonupstream-sync.toml 必须已经受 Git 跟踪并满足对应阶段的 clean 检查,不能从尚未提交或被替换的脚本执行 正式同步。

前置条件与安装

需要 Git、Python 3.12 和 uv。建议把锁定版本的 Copier 安装为独立工具:

uv tool install "copier==9.17.0"
copier --version

模板维护者也可以在仓库根目录使用锁定的维护环境:

uv sync --locked
uv run copier --version

下文默认使用独立的 copier 命令;若使用维护环境,请将其替换为 uv run copier

生成项目

从本地未发布版本生成

开发或评估尚未发布的模板改动时,先确认模板仓库工作区干净,再从仓库根目录生成到一个不存在或 为空的同级目录:

copier copy --vcs-ref=HEAD . ../my-service

Copier 会依次询问五个身份字段,并把目标目录本身作为项目根,不会再套一层 project_name 目录。 生成结果会保存 .copier-answers.yml,其中包含模板来源、版本和非敏感答案;应将它提交到生成项目的 Git 历史中。

从正式版本生成

正式使用应通过稳定远端 URL 和不可变 tag 生成。先从项目的 版本标签中选择所需版本,再将 <version-tag> 替换为对应 tag:

copier copy --vcs-ref=<version-tag> https://github.com/Narotoconan/fastapi-seed.git ../my-service

<version-tag> 替换为实际存在的不可变 tag,并将 ../my-service 替换为实际目标目录。生成长期 维护的项目时不要使用分支或其他浮动引用;本地 HEAD 方式只用于当前仓库尚未发布改动的开发与评估。

生成后启动

进入生成目录,先检查静态 lock 是否仍与项目身份一致:

cd ../my-service
uv lock --check

默认身份会直接通过。若自定义了 project_nameproject_version,uv 可能要求刷新根项目元数据; 确认组织采用的包索引后执行:

uv lock
uv lock --check

随后安装锁定依赖:

uv sync --locked

复制环境变量示例并填写实际值:

Copy-Item .env.example .env.local

Linux / macOS:

cp .env.example .env.local

至少配置 DB_PASSWORDJWT_SECRET_KEY;数据库或 Redis 不在本机时还需配置对应主机和端口。 启动开发服务:

uv run --env-file .env.local uvicorn main:app --reload

更多运行、Docker 和应用边界说明见生成项目自身的 README.md

更新已生成项目

日常模板升级使用 update。执行前必须满足:

  • .copier-answers.yml 已提交;
  • 生成项目是 Git 仓库且工作区干净;
  • answers 中记录的模板源和目标 tag 可访问;
  • 更新在独立分支进行。

在生成项目根目录执行,并把占位符替换为真实的新 tag:

git switch -c chore/copier-update
copier update --vcs-ref=<new-template-tag>
git status --short
git diff --check

检查所有 diff、冲突标记和 .rej 文件,确认 .copier-answers.yml 中的 _commit 已更新,再运行该项目 实际具备的质量检查。若 pyproject.toml 发生身份或依赖变化,还应重新执行 uv lock --check

同版本重放

recopy 忽略生成后形成的差异,按同一模板版本重新渲染模板管理文件。需要诊断漂移或恢复这些文件时, 先提交或备份用户修改,再在生成项目根目录执行:

copier recopy --vcs-ref=:current:

该命令可能覆盖模板管理文件中的用户改动。日常升级应优先使用 copier update,不要把 recopy 当作 常规升级命令。

Secrets 与交付边界

Copier 只收集项目身份,不询问或保存数据库密码、Redis 密码、JWT secret、Token 等运行期配置。 secret: true 也不等于加密,因此首版没有 secret 问题。运行期值继续通过 .env.example.env.docker.example 或部署环境注入;不要提交含真实凭据的环境文件。

生成项目不包含:

  • tests/ 测试套件;
  • .github/workflows/ 或其他 CI workflow;
  • Alembic 及数据库迁移脚本。

这些能力需由下游项目按实际需求自行接入。模板也不配置 tasks、migrations 或自定义扩展,因此 copyupdaterecopy 默认都不需要 --trust,且不会自动安装依赖、初始化 Git、启动容器或 执行其他命令。

uv.lock 索引策略

生成项目的 uv.lock 是静态文件,不经过 Jinja,也不由 Copier task 联网重建。当前 lock 绑定清华 PyPI 镜像,适合明确采用该索引的环境:

  • 不通过 Copier 问题动态选择包索引;
  • 不手工替换 lock 内 URL;
  • 不维护多份条件化 lock;
  • 面向其他索引或通用受众发布前,应在目标索引环境重新生成一份静态 lock;
  • 每个发布候选生成结果都应通过 uv lock --checkuv sync --locked

自定义项目名或版本导致 lock 根项目元数据过期时,应在生成项目内确认索引后运行 uv lock,并将更新后的 uv.lock.copier-answers.yml 一并提交;模板生成过程本身不会执行这一步。

About

基于 Copier 的 FastAPI 项目模板,支持可复现的项目生成、安全更新和受审计的上游同步流程。 | A Copier-powered FastAPI project template with reproducible scaffolding, safe updates, and an audited upstream-sync workflow.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages