【FastAPI】1
安装
pip install "fastapi[standard]"
创建main.py
用 app = FastAPI() 命名,如果更改命名,后续运行命令需要指定
from typing import Union
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: Union[str, None] = None):
return {"item_id": item_id, "q": q}
运行
-
fastapi dev main.py运行
fastapi dev main.py命令后,服务器会在main.py模块中找名为 app 的变量,使用了fastapi dev,修改并保存main.py代码时,服务器会自动重启,不需要手动Ctrl+C再重新运行,
如果代码中变量命名为
web_api = FastAPI(),需要在运行时指定fastapi dev main.py --app web_api -
fastapi run main.py正式部署时要改用fastapi run,此模式下不会监控文件变化,更安全
类型声明
普通: def get_full_name(first_name, last_name)
添加类型提示: def get_full_name(first_name: str, last_name: str)
[!NOTE]
因为编辑器知道变量的类型,不仅能获得代码补全,还能得到错误检查
有些数据结构内部也可以有自己的类型,拥有内部类型的类型为通用类型:dict、list、set、tuple。要声明这些类型和内部类型,使用标准模块typing
[!NOTE]
内部类型用方括号表示
-
def process_items(items: list[str])变量items是list,而列表中的每个项都是str
-
def process_items(items_t: tuple[int, int, str], items_s: set[bytes])变量 items_t 是 tuple,包含3个元素:int、另一个 int 和 str
变量 items_s 是 set ,其每个项类型为 bytes
-
def process_items(items: dict[str, float])变量 items 是 dict,key 的类型是 str,value 的类型的float
-
def process_item(item: int | str)(python3.10+)def process_item(item: Union[int, str])(python3.9+)变量 item 可以是多种类型中的一种,int 或者 str
-
def say_hi(item: Optional[str] = None)def say_hi(item: Union[str, None] = None)def say_hi(item: str | None = None)变量 item 可以是 str,也可以是 None。
optional[somthing]是Union[Somthing,None]的捷径,他们是等价的[!Note]
没有默认值的参数,FastAPI会认为是必填项
声明后面需要有
= None,否则会报错:相当于只说可以是int也可以是str,但没有说如果不传就默认是None -
def get_person_name(one_person: Person)可以声明一个类作为变量的类型,one_person 是 Person 类的实例
-
Annotated在不改变变量类型的前提下,给变量捆绑额外的指令或说明-
格式: 变量名: Annotated[类型, 约束条件] = 默认值
def read_items(q: Annotated[str | None, Query(max_length=50)] = None) -
可以通过元数据(
Query、Path、Body)限制输入的数据-
字符串限制:长度、正则匹配
-
字数限制:大于(gt)、小于(lt)、大于等于(ge)、小于等于(le)
# 限制 item_id 必须在 1 到 1000 之间 @app.get("/items/{item_id}") async def read_items( item_id: Annotated[int, Path(title="商品的ID", ge=1, le=1000)] ): return {"item_id": item_id}
-
-
可预定义带有约束的类型,重复使用
# 定义一个通用的“用户名”类型:必须是字符串,长度 3-20; 之后更改用户名长度,只需修改一处 Username = Annotated[str, Query(min_length=3, max_length=20, pattern="^[a-zA-Z0-9_-]+$")] @app.get("/user") async def get_user(name: Username): ... @app.post("/user") async def create_user(name: Username): ... -
支持依赖注入。把复杂逻辑(如权限检查、数据库连接)封装。
# 定义一个获取当前用户的依赖 CurrentUser = Annotated[User, Depends(get_current_active_user)] @app.get("/items") async def read_items(user: CurrentUser): # 自动完成登录检查并获取用户对象 return {"user_email": user.email}
[!NOTE]
参数元数据:Query、Path、Body。作用是显式地告诉FastAPI去哪里获取数据并要遵守什么校验规则。
-
Query(查询参数)
位置:URL 问号后面,例如
/items/?q=iphone&page=1用途:用于过滤、排序、分页等可选操作
常用约束:min_length、max_length、alias(别名)
-
Path(路径参数)
位置:URL 路径之中,例如
/items/{item_id}用途:用于定位特定的资源
特点:参数名必须与路径大括号中的名字完全一致
常用约束:ge(>=)、gt(>)、le(<=)、lt(<)
-
Body(请求体)
位置:HTTP请求的Body中,通常以JSON格式发送。
用途:用于提交、创建或更新数据。通常配合Pydantic模型使用Body
-
并发与异步
如果想在函数内部使用await,这个函数必须被声明为 async def
只有被定义为 async def 的函数才能被 await 调用
- 想用
await,被调用的函数必须是async def - 被调用函数是
async def,调用它时必须加await - 函数里没有
await任何东西,通常不需要写成async def
异步函数不能直接调用: burger = get_burger(2) ,而是加上await,正确写法 burger = await get_burger(2)
[!NOTE]
如果直接调用
async def定义的函数,只是拿到了一个协程对象,相当于取餐凭证而不是汉堡本身,加上
await,才代表正在等待结果,最终才会拿到真实的数据也就是汉堡
操作
操作指HTTP方法,包括 GET、 PUT、POST、DELETE 以及 PATCH、OPTIONS、HEAD、TRACE
-
POST创建数据 -
GET读取数据 -
PUT更新数据 -
DELETE删除数据
from fastapi import FastAPI
app = FastAPI()
# '@app'指FastAPI实例,'.get'指HTTP方法,'("/")'指路径地址
@app.get("/") # 告诉FastAPI,通过GET方法访问'/'时,就由下面的函数来处理
async def root():
return {"message": "Hello World"}
[!NOTE]
FastAPI 是按照代码从上到下的顺序进行匹配的。 只要找到第一个匹配成功的路径,它就会停止寻找并执行。因此,静态路径(如
/me)永远要写在动态路径(如/{user_id})的前面。
查询参数
声明不属于路径参数的函数参数时,会被自动解释为查询参数
路径参数:如果参数名出现在了
@app.get("/items/{item_id}")的大括号里,它就是路径参数。查询参数:如果参数名没有出现在大括号里,它就被自动当成查询参数。
@app.get("/students/{student_id}")
def read_student(student_id: int, score: int = 0):
# URL:/students/101?score=95;大括号里有student_id,它是路径参数;而score是查询参数
# FastAPI 会自动去 URL 问号 ? 后面寻找 score=xxx
return {"id": student_id, "score": score}
[!NOTE]
自动转换类型:如果定义
score: int,用户传?score=abc,FastAPI 会报错,因为它知道查询参数也需要是数字。默认值支持:可以写
score: int = 20。如果用户没传?score,它就自动用 20。可选参数:可以写
q: str | None = None,这样?q=xxx传不传都行。

浙公网安备 33010602011771号