我有一个非常简单的 FastAPI
GET
端点。它不接受任何请求正文 - 它只接受单个强制性 GET
参数。例如:
/v1/app/end?foo=abcdef1234567890
这个
foo
参数绝对必须符合某些正则表达式。为了这个问题,我简化了正则表达式,但这并不疯狂。
这很容易做到,事实上,我已经在 Pydantic 1.9 中工作了:
# Works perfectly with Pydantic v1.9
from pydantic import constr
@router.get(
"/v1/app/end",
response_model=src.schemas.foo.Bar,
)
def get_with_parameter(
foo: constr(regex=r"^[a-z0-9]{16}$"),
) -> src.schemas.foo.Bar:
现在,迁移到 Pydantic 2.5,我不能再这样做了。请注意,我已将
regex
重命名为 pattern
,但它仍然应该做同样的事情。
# Validation is completely ignored!
...
def get_with_parameter(
foo: constr(pattern=r"^[a-z0-9]{16}$"),
) -> src.schemas.foo.Bar:
按照官方文档和源代码中的建议也不起作用:
# Validation is completely ignored!
from typing_extensions import Annotated
from pydantic import StringConstraints
def get_with_parameter(
foo: Annotated[str, StringConstraints(pattern=r"^[a-z0-9]{16}$")],
) -> src.schemas.foo.Bar:
我发现我可以让它再次工作,但前提是我将其设为可选、最终或其他一些奇怪的类型,这是我不想做的:
from typing import Optional, Final
# Validation works, but is now Optional
...
def get_with_parameter(
foo: Optional[constr(pattern=r"^[a-z0-9]{16}$")],
) -> src.schemas.foo.Bar:
# Validation works, but is now Final
...
def get_with_parameter(
foo: Final[constr(pattern=r"^[a-z0-9]{16}$")],
) -> src.schemas.foo.Bar:
--
我怎样才能让它像以前一样工作?
我找到了一个修复方法,即使用 FastAPI 中的
Query
类型
from typing import Annotated
from fastapi import Query
@router.get(
"/v1/app/end",
response_model=src.schemas.foo.Bar,
)
def get_with_parameter(
foo: Annotated[str, Query(pattern=MY_REGEX)]),
) -> src.schemas.foo.Bar: