4. FastAPI 框架入门:核心特性、项目结构与数据校验

本章是构建信用评分 API 的技术起点。FastAPI 凭借异步原生、自动生成 OpenAPI 文档和基于 Pydantic 的强类型校验,成为金融级低延迟接口的首选框架。我们将从核心特性、项目骨架搭建到数据模型定义,完成第一个可运行的评分端点。

4.1 FastAPI 核心特性

FastAPI 的设计围绕三个关键能力展开,直接决定了信用评分 API 的开发效率与运行时性能。

特性 说明 对信用评分 API 的价值
异步原生 基于 Starlette 的 async/await 支持,不阻塞 I/O 高并发下保持低延迟,适合同时处理多笔评分请求
自动文档 集成 Swagger UI 和 ReDoc,从代码生成交互式 API 文档 前端、测试、风控团队可即时查看请求/响应结构
Pydantic 校验 基于 Python 类型注解的声明式数据验证与序列化 确保入参格式正确,避免脏数据进入评分引擎
性能提示: FastAPI 在基准测试中与 Node.js 和 Go 的 HTTP 框架处于同一梯队。对于信用评分这种计算密集型任务,异步 I/O 让 API 层在等待数据库或缓存时能处理其他请求,显著提升吞吐量。
FastAPI 核心特性架构 FastAPI 应用 异步原生 async/await 非阻塞 自动文档 Swagger UI + ReDoc Pydantic 校验 类型注解 + 验证 三者结合:类型安全 + 高性能 + 零额外文档成本 适合金融级 API 的快速迭代与严格校验

4.2 项目结构搭建

一个可维护的信用评分 API 项目需要清晰的目录分层。我们采用模块化结构,将路由、模型、服务、配置分离,便于团队协作与单元测试。

credit_score_api/
├── app/
│   ├── __init__.py
│   ├── main.py              # FastAPI 应用入口
│   ├── config.py            # 配置管理(数据库、缓存、密钥)
│   ├── routers/
│   │   ├── __init__.py
│   │   └── score.py         # 评分相关路由
│   ├── models/
│   │   ├── __init__.py
│   │   └── schemas.py       # Pydantic 请求/响应模型
│   ├── services/
│   │   ├── __init__.py
│   │   └── scoring.py       # 评分业务逻辑
│   └── dependencies.py      # 依赖注入(数据库会话、认证)
├── tests/
│   ├── __init__.py
│   └── test_score.py
├── requirements.txt
└── Dockerfile
结构要点:
  • routers/ 只负责路由分发,不包含业务逻辑。
  • services/ 封装评分引擎调用、特征计算等核心逻辑。
  • models/schemas.py 集中管理所有 Pydantic 模型,一处修改全局生效。
  • dependencies.py 管理可复用的依赖,如数据库连接、认证令牌。

在 main.py 中创建应用实例并注册路由:

from fastapi import FastAPI
from app.routers import score

app = FastAPI(
    title="信用评分 API",
    description="低延迟信用评分接口,支持异步批量评分",
    version="1.0.0"
)

app.include_router(score.router, prefix="/api/v1", tags=["评分"])

4.3 Pydantic 模型定义与数据校验

Pydantic 是 FastAPI 的数据校验基石。通过 Python 类型注解,我们声明请求体、响应体和查询参数的结构,FastAPI 自动完成解析、校验和文档生成。

4.3.1 基础模型定义

以下是一个信用评分请求的 Pydantic 模型:

from pydantic import BaseModel, Field, field_validator
from typing import Optional
from datetime import date

class CreditScoreRequest(BaseModel):
    user_id: str = Field(..., description="用户唯一标识")
    income: float = Field(..., gt=0, description="年收入(元)")
    age: int = Field(..., ge=18, le=100, description="年龄")
    existing_loans: int = Field(0, ge=0, description="现有贷款笔数")
    credit_history_months: int = Field(..., ge=0, description="信用历史月数")
    request_date: Optional[date] = Field(None, description="请求日期")

    @field_validator("income")
    @classmethod
    def income_must_be_reasonable(cls, v: float) -> float:
        if v > 1_000_000_000:
            raise ValueError("收入金额异常,请核实")
        return v
字段 类型 校验规则 说明
user_id str 必填 用户唯一标识
income float 大于 0,不超过 10 亿 年收入,自定义校验
age int 18 ≤ age ≤ 100 年龄范围限制
existing_loans int ≥ 0,默认 0 现有贷款笔数
credit_history_months int ≥ 0 信用历史长度
request_date Optional[date] 可选 请求日期,默认当天

4.3.2 响应模型与嵌套模型

响应模型同样使用 Pydantic 定义,确保返回数据格式一致:

class CreditScoreResponse(BaseModel):
    user_id: str
    score: int = Field(..., ge=300, le=850, description="信用评分")
    level: str = Field(..., description="信用等级:A/B/C/D")
    processing_time_ms: float = Field(..., description="处理耗时(毫秒)")

class BatchScoreRequest(BaseModel):
    requests: list[CreditScoreRequest] = Field(..., max_length=100)

class BatchScoreResponse(BaseModel):
    results: list[CreditScoreResponse]
    total_processing_time_ms: float
注意: 嵌套模型 BatchScoreRequest 中的 max_length=100 限制了批量请求的最大数量,防止恶意大请求导致内存溢出。这是金融 API 的常见防护手段。

4.3.3 在路由中使用模型

FastAPI 自动将请求体解析为 Pydantic 模型实例,并执行所有校验:

from fastapi import APIRouter, Depends
from app.models.schemas import CreditScoreRequest, CreditScoreResponse
from app.services.scoring import calculate_score

router = APIRouter()

@router.post("/score", response_model=CreditScoreResponse)
async def get_credit_score(request: CreditScoreRequest):
    """
    获取单个用户的信用评分
    """
    score, level, elapsed = await calculate_score(request)
    return CreditScoreResponse(
        user_id=request.user_id,
        score=score,
        level=level,
        processing_time_ms=elapsed
    )
Pydantic 数据校验流程 HTTP 请求 类型解析 字段校验 自定义校验 Pydantic 模型 422 校验错误 校验通过 → 生成干净的模型实例,直接用于业务逻辑 校验失败 → 自动返回 422 错误,包含具体字段和原因

4.4 启动与验证

完成模型和路由定义后,通过以下命令启动服务:

uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

访问 http://localhost:8000/docs 即可看到自动生成的 Swagger UI 文档,所有请求/响应模型、校验规则、示例值一目了然。发送一个测试请求验证校验效果:

curl -X POST "http://localhost:8000/api/v1/score" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "U001",
    "income": 500000,
    "age": 30,
    "existing_loans": 2,
    "credit_history_months": 60
  }'
开发效率: 使用 --reload 模式,修改代码后自动重启服务。配合 Swagger UI 的 "Try it out" 功能,无需额外工具即可完成接口调试。