【python】fastapi使用

官方链接

github: https://github.com/fastapi/fastapi

官方文档: https://fastapi.tiangolo.com

安装

ps: 以下操作全程使用 conda,虚拟环境等操作不体现。

1
2
# 安装标准版
conda install "fastapi[standard]"

创建

1
2
3
4
5
6
7
8
9
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
return {"message": "Hello Fastapi"}

运行

1
2
3
4
# 以开发模式运行,会热重载代码
fastapi dev
# 以生产模式运行,不会热重载代码
fastapi run

实际上它也是在调用 uvicorn 来运行项目。

1
2
3
4
5
# main:main.py模块
# app:FastAPI创建的app对象

uvicorn main:app --reload
uvicorn main:app

http://127.0.0.1:8000 即可查看项目运行状态。

接口文档

fastapi 自带交互式API文档(swagger-ui),访问 http://127.0.0.1:8000/docs 即可查看接口文档。

path 参数

1
2
3
@app.get("/detail/{id}")
async def get_detail(id):
return {"detail_id": id}

访问: http://127.0.0.1:8000/detail/123

query 参数

1
2
3
@app.get("/list")
async def get_list(keyword):
return {"keyword": keyword}

body 参数

官方推荐:定义数据模型并且继承 pydanticBaseModel 类,用于接收请求体参数定义。

也可直接定义请求体参数为 dict ,只是这样文档种字段及类型不会体现。

接受类型可以强制转换时,内部会进行类型转换;例如: status 字段传入”123”会被转换为整数123;无法转换时会报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pydantic import BaseModel

# 官方推荐
class Item(BaseModel):
title: str
content: str
status: int
price: float

@app.post("/create")
async def create(item: Item):
return item

# 野路子
@app.post("/create2")
async def create2(item: dict):
return item

cookie 参数

cookie 中的 key 要和函数形参一致;”a-b” 可写成 “a_b”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from fastapi import Cookie, Request, Response

# 获取方式一:通过 `Cookie` 类,获取指定 cookie
@app.get("/cookie")
async def get_cookie(token: str | None = Cookie(None)):
return {"token": token}

# 获取方式二:通过 `Request` 类;可获取指定 cookie ,也可获取所有 cookie
@app.get("/cookie2")
async def get_cookie2(request: Request):
# 获取所有 cookie
return {"cookies": request.cookies}
# 获取指定 cookie
# return {"cookies": request.cookies.get("cookie_key")}

# 设置 cookie, 通过 Response 类设置
@app.post("/set-cookies")
async def set_cookies(response: Response):
response.set_cookie(key="username", value="rocyuan")
response.set_cookie(key="session_id", value="abc123")
return {"message": "cookie 设置成功"}

header 参数

与 cookie 一样。
header 中的 key 要和函数形参一致;”a-b” 可写成 “a_b”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from fastapi import Header, Request

# 方式一:使用 `Header` 类,获取指定 header
@app.get("/header")
async def get_header(user_agent: str | None = Header(None)):
return {"User-Agent": user_agent}

# 方式二:使用 `Request` 类;可获取指定 header ,也可获取所有 header
@app.get("/header2")
async def get_header2(request: Request):
# 获取所有 header
return {"headers": request.headers}
# 获取指定 header
# return {"headers": request.headers.get("User-Agent")}

form 表单数据

需要安装 python-multipart 解析 Form 表单数据。
ps:如果安装了 fastapi[standard],则无需单独安装 python-multipart。

1
conda install python-multipart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from fastapi import FastAPI, Form

@app.post("/login")
async def login(username: str = Form(), password: str = Form()):
return {"username": username, "password": password}


# 使用 pydantic 定义Form数据模型
from pydantic import BaseModel

class FormData(BaseModel):
username: str
password: str

@app.post("/login2")
async def login2(data: FormData = Form()):
return data

文件数据

需要安装 python-multipart 解析 Form 表单数据,文件上传是以表单形式上传的。
ps:如果安装了 fastapi[standard],则无需单独安装 python-multipart。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from fastapi import File, UploadFile

# 使用 File
@app.post("/files")
async def create_file(file: bytes = File()):
return {"file_size": len(file)}

# 使用 UploadFile (建议)
@app.post("/uploadfile")
async def create_upload_file(file: UploadFile):
return {
"filename": file.filename,
"content_type": file.content_type,
}

CORS 跨域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
"http://localhost:8000",
"http://127.0.0.1:8000",
]

app.add_middleware(
CORSMiddleware,
allow_origins=origins, # 允许跨域请求的源列表 ['*'] 表示允许所有源
allow_credentials=True, # 跨域请求支持 cookies (默认 False)
allow_methods=["*"], # 允许跨域请求的 HTTP 方法列表。默认为 ['GET']
allow_headers=["*"], # 允许跨域请求的 HTTP 请求头列表。默认为 []
)

@app.get("/")
async def main():
return {"message": "Hello Fastapi"}

静态文件

使用 StaticFiles 类,将静态文件挂载到 /static 路由下,以 /static 开头的路径都会处理,指定目录为 static,名称为 static

1
2
3
4
5
6
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

app = FastAPI()

app.mount("/static", StaticFiles(directory="static"), name="static")