我不明白FastAPI 中的可选查询参数。它与默认值为 的默认查询参数有何不同None?
如上面链接中所述,下面的示例中的可选查询参数arg1与 之间有什么区别?arg2arg2
@app.get("/info/")
async def info(arg1: int = None, arg2: int | None = None):
return {"arg1": arg1, "arg2": arg2}
Run Code Online (Sandbox Code Playgroud) Pydantic 2.0 似乎发生了巨大的变化。
以前使用 FastAPI 和 Pydantic 1.XI 可以像这样定义模式,其中收据是可选的:
class VerifyReceiptIn(BaseModel):
device_id: str
device_type: DeviceType
receipt: Optional[str]
Run Code Online (Sandbox Code Playgroud)
然后在 FastAPI 端点中我可以这样做:
@router_verify_receipt.post(
"/",
status_code=201,
response_model=VerifyReceiptOut,
responses={201: {"model": VerifyReceiptOut}, 400: {"model": HTTPError}},
)
async def verify_receipt(body: VerifyReceiptIn):
auth_service = AuthService()
...
Run Code Online (Sandbox Code Playgroud)
没有体内收据的单元测试没问题,但现在 Pydantic 2.0 失败了。现在它声称需要收据并抛出 422 错误。
response = await client.post(
"/verify-receipt/",
headers={"api-token": "abc123"},
json={
"device_id": "u1",
"device_type": DeviceType.ANDROID.value,
},
)
Run Code Online (Sandbox Code Playgroud)
但这就是为什么我们有可选的。为什么我必须通过receipt=None身体?这并不理想,因为它会破坏生产中的一切。有没有解决的办法?谢谢
当有人点击 API 时是否可以获取 cookie?我需要读取每个请求的cookie。
@app.get("/")
async def root(text: str, sessionKey: str = Header(None)):
print(sessionKey)
return {"message": text+" returned"}
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=5001 ,reload=True)
Run Code Online (Sandbox Code Playgroud) 在 FastAPI 中传递字典列表,一般我们会定义一个 pydantic 模式,并会提到
param: List[schema_model]
Run Code Online (Sandbox Code Playgroud)
我面临的问题是我有文件要附加到我的请求中。我找不到在路由器功能中定义架构和文件上传的方法。为此,我将所有参数(请求正文)定义为正文参数,如下所示。
@router.post("/", response_model=DataModelOut)
async def create_policy_details(request:Request,
countryId: str = Body(...),
policyDetails: List[dict] = Body(...),
leaveTypeId: str = Body(...),
branchIds: List[str] = Body(...),
cityIds: List[str] = Body(...),
files: List[UploadFile] = File(None)
):
Run Code Online (Sandbox Code Playgroud)
当我使用 postman 的 form-data 选项发送请求时,它为 policyDetails 参数显示“0:value is not a valid dict”。我正在发送 [{"name":"name1","department":"d1"}]。它说不是有效的字典,即使我发送有效的字典。谁可以帮我这个事?DataModelOut 类
class DataModelOut(BaseModel):
message: str = ""
id: str = ""
input_data: dict = None
result: List[dict] = []
statusCode: int
Run Code Online (Sandbox Code Playgroud) 我试图在该对象的 JSON 架构中允许 null:
from pydantic import BaseModel
from typing import Optional
class NextSong(BaseModel):
song_title: Optional[str] = ...
Run Code Online (Sandbox Code Playgroud)
但结果的模式如下:
{
"title": "NextSong",
"type": "object",
"properties": {
"song_title": {
"title": "Song Title",
"type": "string"
}
},
"required": ["song_title"]
}
Run Code Online (Sandbox Code Playgroud)
生成的架构不允许 Song_title 的值为 null,这不符合预期,但我不确定如何指定允许 null,但该字段仍然是必需的。
我想在 FastAPI 中创建一个可能接收(多部分)Form数据或JSON正文的端点。有没有办法让这样的端点接受或者检测正在接收哪种类型的数据?
我在 FastAPI 中的 REST API 端点上遇到问题,该端点通过单个查询参数接受字符串列表。此端点的用法示例如下:
http://127.0.0.1:8000/items/2?short=false&response=this&response=that
Run Code Online (Sandbox Code Playgroud)
此处,名为“response”的参数接受 FastAPI 教程“查询参数和字符串验证”部分中记录的字符串列表。端点在浏览器中按预期工作。
但是,它在 Swagger 文档中不起作用。单击“执行”以测试端点时,标记为“添加字符串项目”的按钮会晃动。Swagger UI 似乎无法使用嵌入的查询参数创建预期的 URL(如图 1 所示)。
端点的代码如下。我尝试过有验证和没有验证。
@app.get("/items/{item_ID}")
async def getQuestion_byID(item_ID: int = Path(
...,
title = "Numeric ID of the question",
description = "Specify a number between 1 and 999",
ge = 1,
le = 999
), response: Optional[List[str]] = Query(
[],
title="Furnish an answer",
description="Answer can only have letters of the alphabet and is case-insensitive",
min_length=3,
max_length=99,
regex="^[a-zA-Z]+$"
), short: bool = Query(
False,
title="Set …Run Code Online (Sandbox Code Playgroud) 我试图有一个像这样的端点/services?status=New
status将是 New或者Old
这是我的代码:
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from enum import Enum
router = APIRouter()
class ServiceStatusEnum(str, Enum):
new = "New"
old = "Old"
class ServiceStatusQueryParam(BaseModel):
status: ServiceStatusEnum
@router.get("/services")
def get_services(
status: ServiceStatusQueryParam = Query(..., title="Services", description="my desc"),
):
pass #my code for handling this route.....
Run Code Online (Sandbox Code Playgroud)
结果是我收到一个似乎与此问题相关的错误
错误说AssertionError: Param: status can only be a request body, using Body()
然后我找到了这里解释的另一个解决方案。
所以,我的代码将是这样的:
from fastapi import APIRouter, Depends
from pydantic …Run Code Online (Sandbox Code Playgroud) 该代码在 Postman 中运行良好,并提供有效的响应,但无法生成 OpenAPI/Swagger UI 自动文档。
class Role(str, Enum):
Internal = "internal"
External = "external"
class Info(BaseModel):
id: int
role: Role
class AppInfo(Info):
info: str
@app.post("/api/v1/create", status_code=status.HTTP_200_OK)
async def create(info: Info, apikey: Union[str, None] = Header(str)):
if info:
alias1 = AppInfo(info="Portal Gun", id=123, role=info.role)
alias2 = AppInfo(info="Plumbus", id=123, , role=info.role)
info_dict.append(alias1.dict())
info_dict.append(alias2.dict())
return {"data": info_dict}
else:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Please provide the input"
)
Run Code Online (Sandbox Code Playgroud)
收到错误:
TypeError: Object of type 'type' is not JSON serializable
Run Code Online (Sandbox Code Playgroud) @router.post('/update_attributes/{username}')
def update_attributes(request: Request, username: str, email: str = Form(...)):
pass
Run Code Online (Sandbox Code Playgroud)
如何处理表单上输入的空字符串?email如果表单上的文本字段未填写,我会收到错误消息。