Ami*_* Ba 5 enums pydantic fastapi
我有这个应用程序:
import enum
from typing import Annotated, Literal
import uvicorn
from fastapi import FastAPI, Query, Depends
from pydantic import BaseModel
app = FastAPI()
class MyEnum(enum.Enum):
ab = "ab"
cd = "cd"
class MyInput(BaseModel):
q: Annotated[MyEnum, Query(...)]
@app.get("/")
def test(inp: MyInput = Depends()):
return "Hello world"
def main():
uvicorn.run("run:app", host="0.0.0.0", reload=True, port=8001)
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
curl http://127.0.0.1:8001/?q=ab
或curl http://127.0.0.1:8001/?q=cd
返回“Hello World”
但任何这些
curl http://127.0.0.1:8001/?q=aB
curl http://127.0.0.1:8001/?q=AB
curl http://127.0.0.1:8001/?q=Cd
返回422Unprocessable Entity
这是有道理的。
如何使此验证不区分大小写?
Chr*_*ris 11
您可以enum
通过重写Enum
\ 的_missing_
方法来使值不区分大小写。根据文档,此类方法\xe2\x80\x94 默认情况下不执行任何操作 \xe2\x80\x94 可用于查找 ; 中未找到的值cls
。因此,允许人们尝试通过 找到枚举成员value
。
str
请注意,在声明枚举类(例如, )时,可以从该类扩展class MyEnum(str, Enum)
,这将表明枚举中的所有成员都必须具有指定类型的值(例如,str
)。这还允许将字符串与枚举成员进行比较(使用相等运算符==
),而不必使用.value
枚举成员上的属性(例如,if member.lower() == value
)。否则,如果枚举类被声明为class MyEnum(Enum)
(没有str
子类),则需要使用.value
枚举成员上的属性(例如,if member.value.lower() == value
)来安全地将枚举成员与字符串进行比较。
另请注意,没有必要lower()
在枚举成员(即 )上调用函数,除非类的枚举成员值也包含大写(或大写和小写的组合)字母(例如,, 等) 。因此,对于下面的示例,仅使用小写字母,您可以避免使用它,而只需使用它来将 枚举成员与值进行比较;因此,您无需致电member.lower()
ab = \'aB\'
cd = \'Cd\'
if member == value
lower()
类中每个成员的函数。
from enum import Enum\n\nclass MyEnum(str, Enum):\n ab = \'ab\'\n cd = \'cd\'\n \n @classmethod\n def _missing_(cls, value):\n value = value.lower()\n for member in cls:\n if member.lower() == value:\n return member\n return None\n
Run Code Online (Sandbox Code Playgroud)\nfrom fastapi import FastAPI\nfrom enum import Enum\n\n\napp = FastAPI()\n\n\nclass CaseInsensitiveEnum(str, Enum):\n @classmethod\n def _missing_(cls, value):\n value = value.lower()\n for member in cls:\n if member.lower() == value:\n return member\n return None\n \n\nclass MyEnum(CaseInsensitiveEnum):\n ab = \'aB\'\n cd = \'Cd\'\n\n\n@app.get("/")\ndef main(q: MyEnum):\n return q\n
Run Code Online (Sandbox Code Playgroud)\n如果您需要Enum
使用 Pydantic\'s 定义查询参数BaseModel
,则可以使用以下内容(有关更多详细信息,请参阅此答案和此答案):
from fastapi import Query, Depends\nfrom pydantic import BaseModel\n\n\nclass MyInput(BaseModel):\n q: MyEnum = Query(...)\n\n\n@app.get("/")\ndef main(inp: MyInput = Depends()):\n return inp.q\n
Run Code Online (Sandbox Code Playgroud)\n在这两种情况下,可以按如下方式调用端点:
\nhttp://127.0.0.1:8000/?q=ab\nhttp://127.0.0.1:8000/?q=aB\nhttp://127.0.0.1:8000/?q=cD\nhttp://127.0.0.1:8000/?q=CD\n...\n
Run Code Online (Sandbox Code Playgroud)\n在Python 3.11+中,可以改用新引入的StrEnum
,它允许使用该auto()
功能,从而将成员名称的小写版本作为值。
http://127.0.0.1:8000/?q=ab\nhttp://127.0.0.1:8000/?q=aB\nhttp://127.0.0.1:8000/?q=cD\nhttp://127.0.0.1:8000/?q=CD\n...\n
Run Code Online (Sandbox Code Playgroud)\n