第一阶段:项目基础架构

| 文件 | 学习重点 |

|------|----------|

| `run.py` | Uvicorn启动入口,理解ASGI服务器 |

| `app/config.py` | Pydantic Settings配置管理,环境变量加载 |

| `app/database.py` | SQLAlchemy引擎创建、Session管理、依赖注入`get_db()` |

| `app/main.py:1-32` | FastAPI应用初始化、CORS中间件、路由注册 |

**核心知识点**:

- FastAPI生命周期:启动时`Base.metadata.create_all()`自动建表

- 依赖注入模式:`db: Session = Dep

环境变量管理:`.env`文件 → `pydantic-settings` → `settings`单例

1. run.py - 启动入口(9行)

逐行解析:

第1行:import uvicorn
  • uvicorn 是一个ASGI服务器(异步服务器网关接口)
  • 类比:如果FastAPI是"餐厅厨房",uvicorn就是"服务员",负责接收HTTP请求并转交给厨房处理
  • 安装来源:requirements.txt 中的 uvicorn==0.24.0
第3行:if __name__ == "__main__":

  • Python的标准写法,确保这段代码只在直接运行时执行,被import时不执行
  • __name__ 是Python内置变量:
    • 直接运行 python run.py → __name__ 等于 "__main__"
    • 被其他文件 import run → __name__ 等于 "run"

第4-8行:uvicorn.run(...)
  • "app.main:app" → 这是模块路径:变量名的格式
    • app.main = 找到 app/main.py 文件
    • :app = 找到该文件中的 app 变量(即FastAPI实例)
  • host="0.0.0.0" → 监听所有网络接口(局域网其他设备也能访问)
    • 如果写 127.0.0.1 则只能本机访问
  • port=8000 → 端口号8000
  • reload=True → 开发模式,代码修改后自动重启服务器
    • 生产环境应设为False(性能更好)

问题:为什么单独一个run.py?

  • 解耦:启动配置和应用逻辑分离
  • 灵活:可以有多个启动文件(如run_prod.py用不同配置)
  • 规范:这是FastAPI项目的标准做法

2. app/config.py - 配置管理(39行)

逐行解析:

第1行:from pathlib import Path

  • pathlib 是Python 3.4+的路径处理库,比os.path更优雅
  • 用于构建文件路径(跨平台兼容Windows/Mac/Linux)
第2行:from pydantic_settings import BaseSettings

  • pydantic-settings 是Pydantic的扩展,专门用于配置管理
  • 安装来源:pydantic-settings==2.1.0
  • 核心功能:自动从环境变量或**.env文件**读取配置
第4行:BASE_DIR = Path(__file__).resolve().parent.parent

  • __file__ = 当前文件路径,如 C:\Users\admin\Desktop\小程序\测试平台\app\config.py
  • .resolve() = 转为绝对路径
  • .parent = 上一级目录(第一次)→ app/
  • .parent = 上一级目录(第二次)→ 测试平台/
  • 结果:BASE_DIR 指向项目根目录
第7行:class Settings(BaseSettings):

  • 继承 BaseSettings,获得自动读取环境变量的能力
  • 所有属性都会自动尝试从环境变量加载
第9-13行:数据库配置(带默认值)

  • DB_HOST: str = "localhost" → 类型标注 + 默认值
  • 如果环境变量中没有 DB_HOST,则使用默认值 "localhost"
  • 注意:第12行的密码是硬编码的默认值,生产环境应通过.env覆盖
第16-18行:MIMO API配置

  • MIMO_API_KEY 和 MIMO_BASE_URL 默认为空字符串
  • 必须在 .env 中配置才能使用AI功能
  • MIMO_MODEL 有默认值 "mimo-v2.5-pro"
第30-32行:@property database_url

  • @property 装饰器:把方法变成属性访问
  • 使用时写 settings.database_url(不需要加括号)
  • 拼接MySQL连接字符串格式:
    mysql+pymysql://用户名:密码@主机:端口/数据库名?charset=utf8mb4
  • pymysql 是Python的MySQL驱动
第34-36行:class Config(嵌套类)

  • 这是 pydantic-settings 的特殊约定
  • env_file = 指定从哪个 .env 文件读取配置
  • env_file_encoding = 文件编码
  • Pydantic会自动解析 .env 文件中的键值对
第39行:settings = Settings()

  • 实例化 Settings 对象
  • 此时会立即读取 .env 文件和环境变量
  • 整个应用中通过 from app.config import settings 引用这个单例

配置加载优先级(从高到低):

  1. 系统环境变量
  2. .env 文件
  3. 代码中的默认值

3. app/database.py - 数据库配置(25行)

逐行解析:

第1-3行:SQLAlchemy三大核心导入

  • create_engine → 创建数据库引擎(连接池管理器)
  • declarative_base → 创建模型基类(所有表模型都继承它)
  • sessionmaker → 创建会话工厂(生成数据库操作的session)
第7-13行:创建引擎

  • settings.database_url → 从config获取连接字符串
  • echo=True → 打印SQL语句(开发调试用,生产应关掉)
  • pool_pre_ping=True → 使用前先ping一下连接,防止用到已断开的连接
  • pool_size=10 → 连接池保持10个空闲连接
  • max_overflow=20 → 最多溢出20个额外连接(高峰期用)
  • 总共最多 10+20=30 个并发连接

类比:连接池就像"共享单车停放点":

  • pool_size = 停放点常备的车
  • max_overflow = 高峰期临时多放的车
  • pool_pre_ping = 骑之前先检查车有没有坏
第15行:SessionLocal = sessionmaker(...)

  • 创建会话工厂(注意不是会话本身)
  • autocommit=False → 不自动提交事务(需要手动commit
  • autoflush=False → 不自动刷新到数据库
  • bind=engine → 绑定到上面创建的引擎
第17行:Base = declarative_base()

  • 创建模型基类
  • 所有表模型(如TestCase、User)都继承这个类
  • SQLAlchemy通过它来管理表结构映射
第20-25行:get_db() 依赖注入函数

  • 这是一个生成器函数(使用yield
  • db = SessionLocal() → 从工厂创建一个会话
  • yield db → 把会话交给FastAPI的路由函数使用
  • finally: db.close() → 无论是否出错,都关闭会话
  • 这是FastAPI的依赖注入模式

为什么用yield而不是return

  • yield是生成器,FastAPI会在请求处理完后自动执行yield后面的代码
  • 这样保证了db.close()一定会执行(类似try-finally的效果)

4. app/main.py - FastAPI应用入口(前32行)

逐行解析:

第1行:from fastapi import FastAPI

  • FastAPI框架的核心类,创建应用实例
第2行:from fastapi.middleware.cors import CORSMiddleware

  • CORS中间件(跨域资源共享)
  • 解决前后端分离时的跨域问题
  • 比如前端在 localhost:3000,后端在 localhost:8000,浏览器会阻止请求
第3行:from fastapi.responses import HTMLResponse

  • 用于返回HTML页面(后面首页路由用到)
第5-7行:导入配置和路由

  • settings → 全局配置单例
  • engine, Base → 数据库引擎和模型基类
  • testcase, ai, chat... → 7个路由模块
第9行:Base.metadata.create_all(bind=engine) ⭐ 重要

  • 自动建表:扫描所有继承Base的模型类,在数据库中创建对应的表
  • metadata = 存储所有表结构信息的容器
  • create_all = 如果表不存在就创建,已存在则跳过
  • 这行代码在应用启动时执行一次
第11-15行:创建FastAPI实例

  • title → API文档标题(Swagger UI中显示)
  • version → 版本号
  • description → API文档描述
  • 启动后访问 http://localhost:8000/docs 可看到自动生成的API文档
第17-23行:CORS中间件配置 ⭐ 重要

  • allow_origins=["*"] → 允许所有域名访问
  • allow_credentials=True → 允许携带Cookie
  • allow_methods=["*"] → 允许所有HTTP方法(GET/POST/PUT/DELETE...)
  • allow_headers=["*"] → 允许所有请求头

为什么要CORS? 浏览器的同源策略禁止网页向不同源的服务器发请求:

第25-31行:注册路由

  • include_router → 把每个模块的路由挂载到主应用
  • 类比:把各个部门的电话簿合并到总机

📁 补充:app/__init__.py

  • 空文件,但必须存在
  • Python的约定:有 __init__.py 的目录才是(package)
  • 没有它,from app.config import settings 会报错

📁 补充:.env.example 和 .env

.env 文件的作用:

  • 存储敏感配置(密码、API密钥等)
  • 不提交到Git(已在.gitignore中排除)
  • 格式:KEY=VALUE(每行一个)

配置加载流程:

.env文件 → pydantic-settings读取 → Settings实例 → settings对象
                                          ↑
                                    系统环境变量(优先级更高)


🔄 请求处理全流程

现在你已经理解了基础架构,让我画一个完整的请求处理流程

用户浏览器
    │
    ▼
http://localhost:8000/api/testcases?user_id=1
    │
    ▼
┌─────────────────────────────────────────┐
│  run.py                                 │
│  uvicorn.run("app.main:app", ...)       │
│  ↓                                      │
│  Uvicorn服务器接收HTTP请求               │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│  app/main.py                            │
│  app = FastAPI(...)                      │
│  ↓                                      │
│  CORS中间件处理跨域                      │
│  ↓                                      │
│  路由匹配:/api/testcases → testcase.py │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│  app/routers/testcase.py                │
│  @router.get("")                         │
│  def get_testcases(user_id, db=Depends(get_db)):  │
│      ↓                                  │
│      Depends(get_db) 触发 database.py   │
│      → 创建数据库Session                 │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│  app/services/testcase_service.py       │
│  testcase_service.get_testcases(db, ...) │
│      ↓                                  │
│  SQLAlchemy查询 → MySQL数据库            │
│      ↓                                  │
│  返回结果                               │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│  返回JSON响应                           │
│  {"total": 10, "items": [...]}          │
│  ↓                                      │
│  get_db() 的 finally 执行               │
│  → db.close() 关闭Session              │
└─────────────────────────────────────────┘

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐