Pydantic的可选参数尚未准备好,因此类型仍然是一个ForwardRef。

9 浏览
0 Comments

Pydantic的可选参数尚未准备好,因此类型仍然是一个ForwardRef。

我有以下代码:

endpoints.py

from __future__ import annotations  # 这一行非常重要,需要放在顶部
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List, Optional
class MyOpt(BaseModel):
    fieldfirst: str = "S"
    fieldsecond: int = 1
    fieldthird: Optional[str] = None
    fieldforth: List[int] = []
    fieldfifth: int
    fieldsixth: List[Optional[int]] = [None, None]
    fieldseventh: Optional[str] = None 
    fieldeighth: Optional[int] = None
    fieldnineth: Optional[str] = None
    fieldtenth: Optional[List[Optional[int]]] = [None, None] 
# 创建 FastAPI 对象
app = FastAPI()
# API 端点开始
@app.get("/", tags=["root"])
def root():
    return {"message": "REST API."}
# -- 测试端点 --
@app.get(
    "/health", 
    name="health", 
    tags=["root"],
    summary="Test connection to API",
    status_code=200
)
def health():
    return {"type": "complete"}
@app.post(
        "/send_instruction", 
        name="send_instruction", 
        tags=["web"],
    )
def send_instruction(myopts: MyOpt = None):    
    return {"result": "ok"}

run_api.py:

import uvicorn
if __name__ == "__main__":
    uvicorn.run("endpoints:app", host="0.0.0.0", port=8822, reload=True, access_log=False)

当我调用 API(python3 run_api.py)时,只有在发送 MyOpt 的可选值时才会出现以下错误:

File "/home/ubuntu/.local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi

result = await app(self.scope, self.receive, self.send)

File "/home/ubuntu/.local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__

return await self.app(scope, receive, send)

File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/applications.py", line 269, in __call__

await super().__call__(scope, receive, send)

File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__

await self.middleware_stack(scope, receive, send)

File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__

raise exc

File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__

await self.app(scope, receive, _send)

File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/exceptions.py", line 93, in __call__

raise exc

File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/exceptions.py", line 82, in __call__

await self.app(scope, receive, sender)

File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__

raise e

File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__

await self.app(scope, receive, send)

File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/routing.py", line 670, in __call__

await route.handle(scope, receive, send)

File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/routing.py", line 266, in handle

await self.app(scope, receive, send)

File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/routing.py", line 65, in app

response = await func(request)

File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/routing.py", line 217, in app

solved_result = await solve_dependencies(

File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 557, in solve_dependencies

) = await request_body_to_args( # body_params checked above

File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 692, in request_body_to_args

v_, errors_ = field.validate(value, values, loc=loc)

File "pydantic/fields.py", line 857, in pydantic.fields.ModelField.validate

File "pydantic/fields.py", line 1074, in pydantic.fields.ModelField._validate_singleton

File "pydantic/fields.py", line 1121, in pydantic.fields.ModelField._apply_validators

File "pydantic/class_validators.py", line 313, in pydantic.class_validators._generic_validator_basic.lambda12

File "pydantic/main.py", line 686, in pydantic.main.BaseModel.validate

File "pydantic/main.py", line 339, in pydantic.main.BaseModel.__init__

File "pydantic/main.py", line 1038, in pydantic.main.validate_model

File "pydantic/fields.py", line 833, in pydantic.fields.ModelField.validate

pydantic.errors.ConfigError: field "fieldnineth" not yet prepared so type is still a ForwardRef, you might need to call SatOpt.update_forward_refs().

我使用 Postman 发送请求,在 Body 中选择 raw 格式,格式化为 JSON,内容如下:

{

"fieldfirst": "S",

"fieldsecond": 1,

"fieldthird": "a test",

"fieldforth": [1, 2],

"fieldfifth": 42,

"fieldsixth": [

[1, 8, 3],

[1, 9, 2]

],

"fieldseventh": "yey",

"fieldnineth": "VV"

}

我的代码有什么问题?

0