配置API
多个装饰器装饰一个视图函数
如果一个视图函数需要同时支持多个请求地址的访问,可以使用多个装饰器装饰同一个视图函数。示例:
@app.get("/")
@app.get("/index")
def root():
return {"msg": "hello world"}
一个URL配置多个HTTP请求方法
通过@app.api_route
支持配置视图函数使用不同的HTTP请求方法
@app.get("/",
tags=["test"],
summary="root url",
description="fastapi quickstart",
response_class=JSONResponse)
@app.api_route("/index", methods=["GET", "POST"])
def index():
return {"msg": "Hello World"}
处理路径参数
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id):
return {"item_id": item_id}
- 声明路径参数的类型
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
如果存在@app.get("/items/item_id")
和@app.get("/items/{item_id}")
两条路由,一个静态,一个动态。同时访问时"/items/item_id"
时 ,会按照谁先定义就优先访问谁的顺序来访问。如果先定义静态路由,就先访问静态路由。
处理含有文件路径的路径参数
如果要求传入的路径参数是一种文件路径,需要将路径参数声明为path
@app.get("/{filepath:path}")
async def filepath_param(filepath: str):
return {"filepath": filepath}
枚举路径参数
假设路径参数有几个预设值,则可以通过引入枚举类定义路径参数。
from enum import Enum
class CityEnum(str, Enum):
beijing = "beijing"
shanghai = "shanghai"
guangzhou = "guangzhou"
shenzhen = "shenzhen"
@router.get("/city/{cityname}", summary="枚举城市名称")
async def get_city_info(cityname: CityEnum):
if cityname == CityEnum.beijing:
return {"city": "北京", "country": "中国"}
elif cityname == CityEnum.shanghai:
return {"city": "上海", "country": "中国"}
elif cityname == CityEnum.guangzhou:
return {"city": "广州", "country": "中国"}
elif cityname == CityEnum.shenzhen:
return {"city": "深圳", "country": "中国"}
else:
return {"city": "未知", "country": "未知"}
处理查询参数
以下示例中为api设置两个查询参数,并指定默认值。如果不指定默认值,参数将为必需。
from fastapi import FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return fake_items_db[skip : skip + limit]
请求示例
curl http://127.0.0.1:8000/items/?skip=0&limit=10
除了设置默认值,还可以设置参数为可选。
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
处理JSON请求体参数
这里使用路由组来组织代码,myfastapi/main.py
内容如下。
from fastapi import FastAPI
app = FastAPI(
title="Hello FastAPI",
description="Quickstart of FastAPI",
version="0.1.0",
)
# 注册路由组
from routes import jsonbody
app.include_router(jsonbody.router)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app="main:app", host="127.0.0.1", port=8000)
然后创建myfastapi/models
和myfastapi/routes
文件夹,在两个文件下创建内容空白的__init__.py
文件。
简单键值请求体
请求体示例:
{
"username": "string",
"password": "string",
"age": 0,
"address": "string"
}
编辑myfastapi/models/reqresp.py
from pydantic import BaseModel
from typing import Optional
class ReqBody1(BaseModel):
username: str
password: str
age: int
address: Optional[str] = None
编辑myfastapi/routes/jsonbody.py
from fastapi import APIRouter
from models import reqresp
from starlette.responses import JSONResponse
router = APIRouter(prefix="/jsonbody", tags=["解析json请求体"])
@router.post("/test1", summary="测试解析json请求1")
def jtest1(req: reqresp.ReqBody1):
return JSONResponse({
"code": 200,
"data": {
"username": req.username,
"age": req.age,
}
})
测试响应结果
{
"code": 200,
"data": {
"username": "string",
"age": 0
}
}
也可以使用fastapi.Body
类
from fastapi import Body
@router.post("/test2", summary="测试解析json请求2")
def jtest2(
username: str = Body(...), # 必填
password: str = Body(...), # 必填
age: int = Body(..., ge=0), # 大于等于0
address: str = Body(default=None), # 可选字段
):
return {
"username": username,
"age": age,
}