Python基础:FastAPI 接口开发入门
面向有 Java/Spring 背景的开发者,结合本项目(mystu)的实际代码,快速理解 Python 基础与 REST API 编写方式。
1. 为什么选 Python 写 API?
如果你熟悉 Spring Boot + Controller + DTO,那么 FastAPI + Router + Pydantic Model 会非常接近:
| Java (Spring) | Python (FastAPI) |
|---|---|
@RestController |
APIRouter / 路由函数 |
@RequestBody UserDTO |
函数参数 + Pydantic 模型 |
@GetMapping / @PostMapping |
@router.get / @router.post |
| Jackson 序列化 JSON | Pydantic 自动校验与序列化 |
application.yml 端口配置 |
uvicorn.run(host, port) |
| Maven/Gradle 依赖 | pyproject.toml / pip |
包名 com.example.service |
模块路径 mystu.controller |
Python 的优势在于语法简洁、AI/数据分析生态丰富;FastAPI 则提供了类型提示、自动文档(Swagger UI)和高性能异步能力。
2. Python 基础:Java 开发者速查
2.1 缩进代替大括号
Python 用 缩进(通常 4 空格) 表示代码块,没有 {}。
# Java
if (x > 0) {
doSomething();
}
# Python
if x > 0:
do_something()
2.2 命名习惯
| 场景 | Java | Python(惯例) |
|---|---|---|
| 类名 | UserService |
UserService |
| 变量/函数 | getUserName |
get_user_name |
| 常量 | MAX_SIZE |
MAX_SIZE |
| 私有成员 | private field |
_field(约定) |
Python 没有真正的 private,单下划线 _ 表示「内部使用」,双下划线 __ 会触发名称改写,日常很少用。
2.3 类型注解(Type Hints)
Python 3 支持可选类型注解,FastAPI heavily 依赖它:
# Java
public String hello(String name) { ... }
# Python
def hello(name: str) -> str:
return f"Hello, {name}"
str、int、list[str]类似 Java 泛型-> str表示返回值类型- 注解 不会强制运行时检查(除非用 Pydantic / 静态工具),但 FastAPI 会用来生成文档和校验
2.4 模块与包(对比 Java package)
mystu/ # 项目根目录
├── main.py # 入口,类似 Application.main
├── pyproject.toml # 依赖配置,类似 pom.xml
└── mystu/ # 包根目录(与项目名同名很常见)
├── controller/
│ ├── __init__.py # 包标识文件,类似 package-info
│ └── api.py # 路由,类似 Controller
└── entity/
├── apireq.py # 请求 DTO
└── apirsp.py # 响应 DTO
导入方式:
# 绝对导入(推荐)
from mystu.entity import apireq, apirsp
# 相对导入(包内部)
from .api import router
注意:entity 目录下每个 .py 文件是一个 模块,apireq 是模块名,apireq.Request 才是类名。
这是 Java 开发者常见的第一个坑——不要把模块名当成类型用。
2.5 虚拟环境
类似 Java 里每个项目独立的 JDK + 本地 Maven 仓库:
# 创建虚拟环境
python -m venv .venv
# Windows 激活
.venv\Scripts\activate
# 安装依赖(本项目用 pyproject.toml)
pip install fastapi uvicorn
# 或使用 uv
uv sync
依赖写在 pyproject.toml:
[project]
name = "mystu"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.136.3",
"uvicorn>=0.48.0",
]
3. 核心概念:Pydantic 模型 ≈ Java DTO
3.1 请求体
Java:
public class Request {
@NotBlank
private String keyword;
}
Python(本项目 mystu/entity/apireq.py):
from pydantic import BaseModel, Field
class Request(BaseModel):
keyword: str = Field(..., description="请用户输入关键字")
BaseModel:类似 Lombok@Data+ Bean Validation 合体Field(...):...表示必填,类似@NotNull- FastAPI 收到 JSON 后会 自动反序列化 + 校验,失败则返回 422
3.2 响应体
mystu/entity/apirsp.py:
from pydantic import BaseModel
class Response(BaseModel):
data: str
返回时构造模型实例,FastAPI 自动转成 JSON:
return apirsp.Response(data="你好")
不要直接 return "你好"——类型注解是 Response 时,应返回对应结构(或 dict 字段匹配)。
4. 编写 API:Router ≈ Controller
4.1 创建 FastAPI 应用
mystu/controller/__init__.py:
from fastapi import FastAPI
from .api import router
myApp = FastAPI(
title="mytest",
version="1.0",
)
myApp.include_router(router)
对比 Spring:
@SpringBootApplication
public class Application { ... }
// 或在配置类里注册路由前缀
4.2 定义路由
mystu/controller/api.py:
from fastapi import APIRouter
from mystu.entity import apireq, apirsp
router = APIRouter(prefix="/agent/api", tags=["test"])
@router.post("/test")
async def test(request: apireq.Request) -> apirsp.Response:
return apirsp.Response(data="你好")
逐行对照 Java:
| 代码 | 含义 |
|---|---|
APIRouter(prefix=...) |
类级别 @RequestMapping("/agent/api") |
@router.post("/test") |
@PostMapping("/test") |
async def |
异步方法;简单 CRUD 也可写普通 def |
request: apireq.Request |
@RequestBody Request request |
-> apirsp.Response |
方法返回类型 / ResponseEntity 泛型 |
完整 URL:POST http://localhost:5000/agent/api/test
4.3 常见错误:类型注解写错
❌ 错误写法(会启动失败):
async def test(request: apireq) -> apirsp: # apireq/apirsp 是模块,不是类型
return "你好"
报错类似:
FastAPIError: Invalid args for response field! ...
Hint: check that <module 'mystu.entity.apirsp'> is a valid Pydantic field type.
✅ 正确写法:
async def test(request: apireq.Request) -> apirsp.Response:
return apirsp.Response(data="你好")
5. 启动服务:uvicorn ≈ 内嵌 Tomcat
5.1 推荐写法
main.py:
import uvicorn
from mystu.controller import myApp
if __name__ == "__main__":
uvicorn.run(
myApp, # 直接传入 FastAPI 实例
host="0.0.0.0",
port=5000,
reload=True, # 开发热重载,类似 spring-boot-devtools
)
或使用字符串形式(便于 reload 子进程加载):
uvicorn.run("mystu.controller:myApp", host="0.0.0.0", port=5000, reload=True)
5.2 async 入口的坑
若写成:
async def _serve():
config = uvicorn.Config(myApp, host="0.0.0.0", port=5000)
await uvicorn.Server(config).serve()
if __name__ == "__main__":
_serve() # ❌ 协程未被 await
会警告 coroutine '_serve' was never awaited,进程立刻退出。
需要:
import asyncio
asyncio.run(_serve())
对 Java 开发者来说:Python 的 async def 类似 CompletableFuture,调用 async 函数不会自动执行,必须用事件循环驱动。
5.3 命令行启动
uvicorn mystu.controller:myApp --host 0.0.0.0 --port 5000 --reload
6. 自动 API 文档
启动后访问:
- Swagger UI:
http://localhost:5000/docs - ReDoc:
http://localhost:5000/redoc
相当于 Spring 集成 springdoc-openapi,但 零配置。
Pydantic 模型的 Field(description=...) 会直接出现在文档里。
7. 测试接口
7.1 curl
curl -X POST "http://localhost:5000/agent/api/test" \
-H "Content-Type: application/json" \
-d "{\"keyword\": \"铁矿石\"}"
期望响应:
{"data": "你好"}
7.2 Python requests
import requests
resp = requests.post(
"http://localhost:5000/agent/api/test",
json={"keyword": "铁矿石"},
)
print(resp.status_code, resp.json())
8. 异常处理(对比 Spring)
Java:
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<?> handle(...) { ... }
// 或
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "not found");
FastAPI:
from fastapi import HTTPException
@router.get("/items/{item_id}")
async def get_item(item_id: int):
if item_id <= 0:
raise HTTPException(status_code=400, detail="item_id 必须大于 0")
return {"item_id": item_id}
全局异常处理器:
from fastapi import Request
from fastapi.responses import JSONResponse
@myApp.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
return JSONResponse(status_code=400, content={"message": str(exc)})
9. 依赖注入(进阶预览)
FastAPI 内置 Depends,概念接近 Spring 的 @Autowired / 构造器注入:
from fastapi import Depends
def get_db():
db = connect()
try:
yield db
finally:
db.close()
@router.get("/users")
async def list_users(db=Depends(get_db)):
return db.query_users()
初学阶段可先写简单函数,等项目变大再引入分层(service / repository)。
10. Java vs Python Web 思维对照小结
| 话题 | Java 习惯 | Python/FastAPI 习惯 |
|---|---|---|
| 分层 | Controller → Service → Repository | Router → 函数/Service 模块 |
| DTO | Java Bean + Validation | Pydantic BaseModel |
| 配置 | application.yml | 环境变量 / pydantic-settings / 直接代码 |
| 运行 | mvn spring-boot:run |
python main.py 或 uvicorn ... |
| 测试 | JUnit + MockMvc | pytest + httpx.AsyncClient |
| 并发 | 线程池 / WebFlux 响应式 | async/await + ASGI |
| 接口文档 | 常需额外配置 | 内置 /docs |
11. 本项目最小闭环回顾
- 定义模型:
entity/apireq.py、entity/apirsp.py - 写路由:
controller/api.py - 组装应用:
controller/__init__.py创建myApp并include_router - 启动:
main.py里uvicorn.run(myApp, ...) - 调试:浏览器打开
/docs或 curl 发 POST
目录结构清晰后,后续加业务只需:
- 在
entity/增加请求/响应模型 - 在
controller/增加路由函数 - 复杂逻辑抽到
service/(可按 Java 分层习惯新建)
12. 学习建议(给 Java 背景的你)
- 先接受「动态 + 简洁」:少写样板代码,但类型注解仍要写好,方便 IDE 和 FastAPI。
- 分清模块与类:
import apireq导入的是文件模块,类型用apireq.Request。 - 善用
/docs:比 Postman 更快验证接口。 - 异步不必强求:CPU 简单逻辑用
def即可;IO 密集(大量 HTTP/DB)再学async。 - 下一步:学习
pytest测 API、SQLAlchemy连数据库、pydantic-settings读配置——都和你熟悉的 Spring 生态一一对应。
参考
更多推荐



所有评论(0)