Question: I have this application: 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()  curl http://127.0.0.1:8001/?q=ab or curl http://127.0.0.1:8001/?q=cd returns "Hello World" But any of these  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 etc  returns 422Unprocessable Entity which makes sense. How can I make this validation case insensitive?

Answer: You could make case insensitive enum values by overriding the Enum's _missing_ method . As per the documentation, this classmethod—which by default does nothing—can be used to look up for values not found in cls; thus, allowing one to try and find the enum member by value. Note that one could extend from the str class when declaring the enumeration class (e.g., class MyEnum(str, Enum)), which would indicate that all members in the enum must have values of the specified type (e.g., str). This would also allow comparing a string to an enum member (using the equality operator ==), without having to use the .value attribute on the enum member (e.g., if member.lower() == value). Otherwise, if the enumeration class was declared as class MyEnum(Enum) (without str subclass), one would need to use the .value attribute on the enum member (e.g., if member.value.lower() == value) to safely compare the enum member to a string. Also, note that calling the lower() function on the enum member (i.e., member.lower()) would not be necessary, unless the enum member values of your class include uppercase (or a combination of uppercase and lowercase) letters as well (e.g., ab = 'aB', cd = 'Cd', etc.). Hence, for the example below, where only lowercase letters are used, you could avoid using it, and instead simply use if member == value to compare the enum member to a value; thus, saving you from calling the lower() funciton on every member in the class. Example 1 from enum import Enum class MyEnum(str, Enum): ab = 'ab' cd = 'cd' @classmethod def _missing_(cls, value): value = value.lower() for member in cls: if member.lower() == value: return member return None  Generic Version (with FastAPI example) from fastapi import FastAPI from enum import Enum app = FastAPI() class CaseInsensitiveEnum(str, Enum): @classmethod def _missing_(cls, value): value = value.lower() for member in cls: if member.lower() == value: return member return None class MyEnum(CaseInsensitiveEnum): ab = 'aB' cd = 'Cd' @app.get("/") def main(q: MyEnum): return q  In case you needed the Enum query parameter to be defined using Pydantic's BaseModel, you could then use the below (see this answer and this answer for more details): from fastapi import Query, Depends from pydantic import BaseModel ... class MyInput(BaseModel): q: MyEnum = Query(...) @app.get("/") def main(inp: MyInput = Depends()): return inp.q  In both cases, the endpoint could be called as follows: http://127.0.0.1:8000/?q=ab http://127.0.0.1:8000/?q=aB http://127.0.0.1:8000/?q=cD http://127.0.0.1:8000/?q=CD ...  Example 2 In Python 3.11+, one could instead use the newly introduced StrEnum, which allows using the auto() feature, resulting in the lower-cased version of the member's name as the value. from enum import StrEnum, auto class MyEnum(StrEnum): AB = auto() CD = auto() @classmethod def _missing_(cls, value): value = value.lower() for member in cls: if member == value: return member return None