‹ 博客列表

FastAPI & SQLAlchemy 实战(五):第一个接口、自动文档与同步/异步函数

从 main.py 到 uvicorn,跑通第一个接口,理解 /docs 和同步/异步函数的区别。

「FastAPI & SQLAlchemy 实战」系列共 10 篇,从协程基础讲到数据库接口。这是第 5 篇。

结论:FastAPI 的最小程序只有三部分:FastAPI() 实例、路径装饰器、处理函数。启动后访问 /docs 就能看到自动生成的接口文档。

一、安装与最小程序

pip install fastapi uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

启动:

uvicorn main:app --reload
# main = main.py,app = FastAPI() 实例,--reload 仅开发用

访问 http://127.0.0.1:8000/items/5?q=iphone,返回 {"item_id":5,"q":"iphone"};访问 /docs 是 Swagger UI,/openapi.json 是机器可读的接口描述。

二、路径、操作、函数

  • 路径:/items/{item_id},{item_id} 是路径参数;
  • 操作:@app.get、@app.post、@app.put、@app.delete 等,对应 HTTP 方法;
  • 函数:装饰器下方的函数,返回值会自动转成 JSON。

路由顺序有影响:/users/me 必须写在 /users/{user_id} 前面,否则 me 会被当成 user_id。

三、同步函数 vs 异步函数

def async def
执行位置 线程池 事件循环
适合 纯计算、同步库 异步 I/O、异步库
注意 线程池满会排队 同步调用会阻塞整个循环

只有同步库时,用 def 让 FastAPI 放进线程池;有异步库(asyncpg、httpx、aiohttp)时,用 async def 并配合 await。

四、也可以代码内启动

import uvicorn

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

五、验证

curl -s http://127.0.0.1:8000/
curl -s http://127.0.0.1:8000/items/5?q=iphone
curl -s http://127.0.0.1:8000/items/foo   # item_id 不是 int,返回 422

六、常见错误

  • 启动路径写错:uvicorn app.main:app 对应 app/main.py;
  • 生产环境保留 --reload:会反复重启,性能也差;
  • 在 async def 里调用 requests.get:事件循环被阻塞;
  • 把路径参数和查询参数搞混:不在路径里的参数默认是查询参数。

下一篇

下一篇讲路径参数和查询参数:类型注解不只是提示,FastAPI 会用它做转换和校验。

上一篇:WSGI 与 ASGI | 下一篇:路径参数与查询参数

本文来自 https://aimock.cn/blog,站内重新编排。
内容仅供学习交流,转载请注明出处。