helloworld
from fastapi import FastAPI # 导入包
import uvicorn
app = FastAPI() # 实例化
@app.get("/") # 创建路径操作 常见操作:POST、GET、PUT、DELETE;少见:OPTIONS、HEAD、PATCH、TRACE
async def root():
return {"message": "Hello World"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
路径参数
from fastapi import FastAPI # 导入包
import uvicorn
app = FastAPI() # 实例化
@app.get("/items/{item_id}") # 路径参数
async def read_item(item_id: str): # 路径参数进行类型限定,具有数据校验的效果
return {"item_id": item_id}
# 有相对顺序
@app.get("/users/me")
async def read_user_me():
return {"user_id": "the current user"}
@app.get("/users/{user_id}")
async def read_user(user_id: str):
return {"user_id": user_id}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
接收路径参数限定
from fastapi import FastAPI # 导入包
import uvicorn
app = FastAPI() # 实例化
# 接收路径操作,预先设定可能的有效参数值
from enum import Enum
class ModelName(str, Enum): # 创建具有固定值的雷属性,固定值为可用的有效值
alexnet = "alexnet"
resnet = "resnet"
lenet = "lenet"
@app.get("/models/{model_name}")
async def get_model(model_name: ModelName): # 创建一个带有类型标注的路径参数
if model_name == ModelName.alexnet: # 与枚举类成员进行比较
return {"model_name": model_name, "message": "Deep Learning FTW!"}
if model_name.value == "lenet": # 获取实际的值比较 或ModelName.lenet.Value
return {"model_name": model_name, "message": "LeCNN all the images"}
return {"model_name": model_name, "message": "Have some residuals"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
带路径的路径参数
from fastapi import FastAPI # 导入包
import uvicorn
app = FastAPI() # 实例化
@app.get("/files/{file_path:path}") # 路径转换器
async def read_file(file_path: str):
return {"file_path": file_path}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
查询参数 结构
from fastapi import FastAPI
import uvicorn
from typing import Optional
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]
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
路径参数 vs 查询参数,声明中无须区分,且无特定顺序
from fastapi import FastAPI
import uvicorn
from typing import Optional
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/{item_id}")
# item_id是路径参数、q为可选的查询参数 默认值为None
async def read_item_1(item_id: str, q: Optional[str] = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
# 路径参数 查询参数无特定声明顺序
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
user_id: int, item_id: str, q: Optional[str] = None, short: bool = False
):
item = {"item_id": item_id, "owner_id": user_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
查询参数类型自动转换 如short
from fastapi import FastAPI
import uvicorn
from typing import Optional
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/{item_id}")
async def read_item_2(item_id: str, q: Optional[str] = None, short: bool = False):
# 查询参数类型转换
item = {"item_id": item_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
非路径参数声明了默认值,表明该参数可选;没有特定的默认值,可以使用None
查询参数必选时,不给定默认值
Optional的使用 Optional[int] = None
from fastapi import FastAPI
import uvicorn
from typing import Optional
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
# 非路径参数声明了默认值,则该值不是必须
# 不想添加特定值,使用None
# 一个查询参数必选时,不给定默认值
@app.get("/items/{item_id}")
async def read_user_item(
item_id: str, needy: str, skip: int = 0, limit: Optional[int] = None
):
# Optional[int] = None ✔️ int = None ×
item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
return item
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
请求体
数据模型作为请求时方式、是否必需、默认值设置等,与查询参数一致;可以理解为对查询参数的一层封装
from typing import Optional
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
# 导入Pydantic的BaseModel
class Item(BaseModel):
# 创建数据模型,模型属性具有默认值是,不是必须;反之,是必选项。不用特定默认值是,可设置为None
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
# 声明请求体
# return item
item_dict = item.dict()
# 访问模型对象的属性 item.***
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
# @app.put("/items/{item_id}")
# async def create_item(item_id: int, item: Item):
# # 请求体+路径参数
# return {"item_id": item_id, **item.dict()}
@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: Optional[str] = None):
# 请求体 + 路径参数 + 查询参数
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
在docs文档中查看相应的接口
查询参数Query
用于特定字符串校验
from typing import List, Optional
import uvicorn
from fastapi import FastAPI, Query
# 导入Query
app = FastAPI()
@app.get("/items/")
async def read_items(q6: Optional[str] = Query(
None,
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
max_length=50,
regex="^fixedquery$",
deprecated=True,
),
q5: Optional[str] = Query(None, alias="item-query"),
q4: Optional[str] = Query(
None,
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
),
q3: Optional[str] = Query(None, title="Query string", min_length=3),
q2: List[str] = Query(['li','wang']),
q1: Optional[List[str]] = Query(None),
q: Optional[str] = Query(None, min_length=3, max_length=50, regex="^fixedquery$")):
# 默认值为None,查询参数值不得超过50个字符的长度
# Query(None)显示地声明为查询参数
# Query(..., max_length=3) 参数是必须的
# 查询参数是一组值 Optional[List[str]]
# 具有默认值的查询列表 List[str] = Query(['li','wang'])
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}], "q2": q2}
if q:
results.update({"q": q})
if q1:
results.update({"q1": q1})
if q3:
results.update({"q3": q3})
if q4:
results.update({"q4": q4})
if q5:
results.update({"q5": q5})
if q6:
results.update({"q6": q6})
return results
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")
路径参数
设定参数顺序、无默认参数放在有默认参数前,通过*改变顺序
ge、gt、le、lt校验数据
from typing import Optional
import uvicorn
from fastapi import FastAPI, Path, Query
# 导入Path
app = FastAPI()
# @app.get("/items/{item_id}")
# async def read_items(
# item_id: int = Path(..., title="The ID of the item to get"),
# q: Optional[str] = Query(None, alias="item-query"),
# ):
# # ... 必须参数、
# results = {"item_id": item_id}
# if q:
# results.update({"q": q})
# return results
# 以下会报错,item_id是带有默认参数的,q没有默认参数
# 无默认参数放在带有默认参数前
@app.get("/items/{item_id}")
async def read_items(
q: str,
item_id: int = Path(..., title="The ID of the item to get")
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
# 与以上参数顺序不同
@app.get("/items1/{item_id}")
async def read_items(
*, item_id: int = Path(..., title="The ID of the item to get", ge=1), q: str,
size: float = Query(..., gt=0, lt=10.5)
):
# 大于等于 ge 大于 gt 小于等于 le
results = {"item_id": item_id, 'size': size}
if q:
results.update({"q": q})
return results
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio")