29. FastAPI 创建工程级别的目录(示例)
从一个空目录创建能启动的工程
先把骨架跑通,再逐步加入数据库和认证。下面所有命令在一个新的练习目录执行,不会要求你立刻实现上一章每个文件。
powershell
uv init --bare --python 3.12 fastapi-project
Set-Location fastapi-project
uv python pin 3.12
uv add "fastapi[standard]" "pydantic>=2,<3" pydantic-settings
uv add --dev pytest httpx使用 Python 创建骨架,可在 Windows 与 Linux 上复用;保存为 scaffold.py 后执行 uv run python scaffold.py:
python
from pathlib import Path
for folder in ["app", "app/api", "app/core", "app/schemas", "app/services"]:
path = Path(folder)
path.mkdir(parents=True, exist_ok=True)
(path / "__init__.py").touch(exist_ok=True)
Path("tests").mkdir(exist_ok=True)写入三个必要文件
app/api/health.py:
python
from fastapi import APIRouter
router = APIRouter(tags=["健康检查"])
@router.get("/health")
def health():
return {"status": "ok"}app/api/router.py:
python
from fastapi import APIRouter
from app.api.health import router as health_router
router = APIRouter()
router.include_router(health_router)app/main.py:
python
from fastapi import FastAPI
from app.api.router import router
def create_app() -> FastAPI:
application = FastAPI(title="工程化学习项目")
application.include_router(router, prefix="/api/v1")
return application
app = create_app()启动:
powershell
uv run uvicorn app.main:app --reload
Invoke-RestMethod http://127.0.0.1:8000/api/v1/health预期返回 status=ok。应用工厂便于测试创建独立实例;普通部署可以直接用 app.main:app,也可以理解 --factory app.main:create_app 的另一种入口写法,不要把两者混用。
加一条有意义的冒烟测试
创建 tests/test_health.py:
python
from fastapi.testclient import TestClient
from app.main import create_app
def test_health():
with TestClient(create_app()) as client:
response = client.get("/api/v1/health")
assert response.status_code == 200
assert response.json() == {"status": "ok"}执行 uv run python -m pytest。使用上下文管理器可运行应用的 lifespan。测试验证公开行为,不绑定内部函数名或目录细节。
完成后再扩充
依次加入配置、业务路由、Schema、Service、数据库 Session 与迁移。每增加一项,就验证一次真实入口;不要先生成大量空目录后以为工程已完成。
本章不启动外部数据库,适合验证包导入与结构;数据库接入沿用第 20 篇配置,生产启动不使用开发重载。
练习:新增 /api/v1/version,返回版本号;从项目根目录运行测试,再故意在子目录启动,观察导入路径问题。