I've been tasked with handling the update from Mypy 0.770 to 0.870 in our FastAPI project, and this has produced an error that I can't quite wrap my head around. My endpoint can return two different models based on some condition, and this was denoted as follows the endpont decorator:
@router.get("/", response_model=Union[Model1, Model2])
Mypy 0.870 now complains about this, stating that
Argument "response_model" to "get" of "APIRouter" has incompatible type "object"; expected "Optional[Type[Any]]"
Setting it to single types, such as Model1
or even str
removes the error. Any
however, does not work.
Now, looking into the get
method, I see that the response_model
argument is typed as Type[Any]
, which I assume must be a pointer.
How I can define non-simple return models for my API, and make Mypy happy?
edit: I tried to reproduce the problem in a smaller frame, but couldn't. The following code works fine:
from typing import Any, Type, Union
def test1(var, response_model: Type[Any]):
print(f"Accepted Type[Any], {var}")
def test2(var, response_model: Union[dict, set]):
print(f"Accepted Union, {var}")
def main():
test1('test1', response_model=Union[dict, set])
test2('test2', response_model=Union[dict, set])
if __name__ == '__main__':
main()
This is a compatibility issue introduced in newer versions of mypy. There is an open issue on Github about this topic: https://github.com/tiangolo/fastapi/issues/2279
In the discussion they provide the following workarounds:
Using a different approach to create a type alias:
NewModel = TypeVar('NewModel',Model1,Model2)
Creating a new Pydantic Model :
class NewModel(BaseModel):
__root__: Union[Model1, Model2]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With