评论([[comments.sum]])
一个 url 的组成
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
@app.get("/query/")
async def query(item: str, age: int, sex: bool = False,):
return {'sex': sex}
# 传递参数 /query/?item=sa&sex=1&age=18
# 路由中:sex=0 or sex=false or ...
# sex === False or True
参数如果没有默认值则为必须传入的
@app.get("/as/{item}/")
async def test(item: str):
# 函数定义中传入的参数值必须与路由中定义的名字相同,不同则会作为url的查询参数 query
return {'item': item}
# 除非此路由定义在上面,否则永远不会被访问
@app.get("/as/")
async def test1():
return {'item': item}
将会匹配路由
/as/+
参数类型为 str. 实际生成的路由为, 但不会匹配
/as/+/+++/as/(+)/
(后面的斜杠来自路由的定义)如果有两个路由
gat:/as/{item}/ get:/as/
此时访问 as 就转到 as/item/ 所有不要再主路由上直接使用路径参数
from fastapi import FastAPI, Form
app = FastAPI()
@app.post('/user/')
def user(uname: str = Form(...), password: str = Form(...)):
print('uname', uname)
print('pw', password)
# 不再渲染模板
return {'uname': uname, 'password': password}
<body>
<form action="/user/" method="post">
<input type="text" name="uname">
<input type="password" name="password">
<input type="submit">
</form>
</body>
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(file: bytes = File(...)):
return {"file_size": len(file)}
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
return {"filename": file.filename}
# 多文件上传
@app.post("/uploadfiles/")
async def create_upload_files(files: List[UploadFile] = File(...)):
return {"filenames": [file.filename for file in files]}
要声明文件主体,您需要使用
File
,因为否则参数将被解释为查询参数或主体( JSON )参数。
bytes
,FastAPI将为您读取文件,并且您将收到内容bytes
。这意味着全部内容将存储在内存中。这对于小文件将非常有效。使用UploadFile
比较bytes
有以下优点:
SpooledTemporaryFile
对象,您可以将其直接传递给需要类似文件的对象的其他库。uploadfile 的方法:
write(data)
:将data
(str
或bytes
)写入文件。read(size)
:读取size
(int
)个文件的字节/字符, 参数为空读取所有。seek(offset)
:转到文件中的字节位置offset
(int
)close()
:关闭文件。Tips: 这些方法都是异步的, 需要使用 await 等待
请求体是客户端发送到您的 API 的数据。
API 几乎总是必须发送一个响应体,但是客户端并不需要一直发送请求体。
定义请求体,需要使用 Pydantic 模型。
不能通过GET
请求发送请求体
发送请求体数据,必须使用以下几种方法之一:
POST
(最常见),PUT
DELETE
PATCH
请求体的类型为 json 格式
可以同时定义Path参数
、Query参数
和 请求体参数
:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(
item_id: int,
item: Item,
q: str = None
):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result
from fastapi import FastAPI, Query
@app.get("/query/")
async def query(item: str = Query(None, min_length=3, max_length=10),
test: int = Query(...)):
return {'item': item}
# 传入参数item 长度不满足条件则为默认值 None
# test 为必填项
@app.get("/query1/")
async def query1(q: List[str] = Query(['foo', 'bar'],)):
return {'item': q}
# q 接收一个数组, 这个数组具有两个默认值
# alias="item-q" 指定别名,参数传递必须使用此名
# /query1?item-q=1&item-q=30&q=as 则 q === ['1', '30']
@app.get('/path/{aid}/')
async def path(aid: int = Path(..., ge=1, le=10)):
return {'aid': aid}
# /path/0 err: ensure this value is greater than or equal to 1
您想得到一个带有 key 的 JSON ,并且在 key 对应的包含模型内容,就像声明额外的主体参数时那样,则可以使用嵌入的特殊参数
Body(..., embed=True)
class Item(BaseModel):
name: str = 'tes'
description: str = None
class Item1(BaseModel):
price: float = 1.82
tax: float = None
@app.post('/body/')
async def query(*, item: Item = Body(..., embed=True)):
return item
# 则 预期的请求体则会为
# {
# "item": {
# "name": "tes",
# "description": "The pretender",
# }
# }
而 Body 不传递 embed 参数或者为 Fales 则为:
{
"name": "Foo",
"description": "The pretender",
}
而对于多个参数,
class Item2(BaseModel):
item2: str = None
@app.post('/body/')
async def query(*, item2: Item2, item1: Item1, item: Item = Body({}, embed=False)):
return [item, item1, item2]
不管 embed 的值如何,传输参数格式必须为:
{
"item2": {
"item2": "string"
},
"item1": {
"price": 1.82,
"tax": 0
}
}
from pydantic import BaseModel, Field
class Item3(BaseModel):
name: str = Field(..., min_length=2)
sex: bool = Field(False, title="性别", description='true is man')
@app.post('/body/field', description='接口描述及字段约束测试')
def body_field(item: Item3):
return item
对于一个参数的两个验证产生的冲突,现不完全了解。尽量不要发生这种情况:
def body_field(item: Item3 = Body({})):
return item
# 此时可以不传入参数,则值为 {}, 代表上面 Item3类定义的约束失效。
baseModel 定义的数据类型可以嵌套,以便支持复杂的参数
from typing import Set, List
from pydantic import BaseModel, Field, HttpUrl
class Img(BaseModel):
filename: str = Field(..., regex='^filename\-.*')
# 默认提供的一些参数验证
url: HttpUrl
# 接收任意的字典 {str:float, ...}, 则在验证一些密钥时 很有用
token: Dict[str, float]
class Item(BaseModel):
name: List[str] = []
tags: Set[str] = set()
imgs: List[Img] = None
传递的参数样式:
{
"name": [],
"tags": [],
"imgs": [
{
"filename": "filename-test",
"url": "http://127.0.0.1:8000/docs",
"token": {
"additionalProp1": 0,
}
}
]
}
还有很多额外的参数类型.... , (官网
这些类属性的元素,也是可以作为其他类型参数的约束的。( query, path
from fastapi import FastAPI
from enum import Enum
class Name(str, Enum):
Allan = 'allan'
Jon = 'jon'
Bob = 'bob'
@app.get('/name/{who}')
async def get_name(who: Name):
return {'name': who}
传入的参数必须被枚举类型定义
@app.get('/cookie/')
def cookie(*, abs_id: str = Cookie(None)):
return {'abs_id': abs_id}
# 获取cookie中 键为 abs_id 的cookie值
from typing import List
from fastapi import FastAPI, Header
app = FastAPI()
@app.get('/items')
async def items(*, user_agent: str = Header(None),
users_agent: str = Header(None), # Null
x_token: List[str] = Header(None)):
return {'userAgent': user_agent,
'x_token': x_token}
对于参数值的匹配是按照参数名来匹配的。
x_token
接收的是一个 按照分号分割的字符串如:["a,b,c,d"]
. 是因为 hender 它不支持列表. 因为传递形式也是为:"x-token: 'string', 'b,', 'c'"
. 所以还是字节接收字符串比较好
您可以使用指定响应模型的相同方法,也可以status_code
在任何路径操作中使用参数声明用于响应的 HTTP 状态代码. 您可以直接传递int
代码,例如404
。
@app.post("/items/", status_code=201)
async def create_item(name: str):
return {"name": name}
果您不记得每个数字代码的用途,则可以在中使用快捷方式常量status
from fastapi import FastAPI, status
@app.post("/items/", response_model=Item, status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
return item
该状态代码将在响应中使用,并将添加到 OpenAPI 架构中。
Tips:
您也可以使用
from starlette import status
。FastAPI提供相同
starlette.status
的fastapi.status
,但它来自 Starlette。Tips: 你可以标记添加到您的路径操作,传递参数
tags
用list
的str
. 它们将被添加到 OpenAPI 架构中,并由自动文档接口使用.@app.get("/users/", tags=["users"])
相关推荐:
来自系列:fastapi评论([[comments.sum]])
[[item.name]] [[item.email]] [[item.date_time]]
[[itemSon.name]] [[itemSon.email]] [[itemSon.date_time]]
回复 @[[itemSon.reply_user.name]]:
加载更多([[item.son.length-2]])...