Reputation: 111
I have a FastAPI app and I need to create a Car class in which the attributes wheel and speed can take an int or str type. How to do it? This code does not work, because wheel and speed will have only an integer type (not str in second print):
from pydantic import BaseModel
class Car(BaseModel):
wheel: int | str
speed: int | str
bmw = Car(wheel=4, speed=250)
mercedes = Car(wheel='4', speed='200')
print(type(bmw.wheel), type(bmw.speed))
print(type(mercedes.wheel), type(mercedes.speed))
Result is:
<class 'int'> <class 'int'>
<class 'int'> <class 'int'>
Upvotes: 1
Views: 2941
Reputation: 63
What you are looking for is the Union option from typing. An example is below
from typing import Union
from pydantic import BaseModel
class Car(BaseModel):
wheel: Union[str,int]
speed: Union[str,int]
Further, instead of simple str or int you can write your own classes for those types in pydantic and add more attributes as needed.
Upvotes: -1
Reputation: 95948
So, I would personally just use pydantic.StrictInt
and pydantic.StricStr
here (and actually, I use those almost everywhere, particularly StrictStr
because practically any object can be coerced to a string):
import pydantic
class Car(pydantic.BaseModel):
wheel: pydantic.StrictInt | pydantic.StrictStr
speed: pydantic.StrictInt | pydantic.StrictStr
bmw = Car(wheel=4, speed=250)
mercedes = Car(wheel='4', speed='200')
print(type(bmw.wheel), type(bmw.speed))
print(type(mercedes.wheel), type(mercedes.speed))
This prints:
<class 'int'> <class 'int'>
<class 'str'> <class 'str'>
Upvotes: 5
Reputation: 3504
There is order in the type specification. With int | str
, the value will be treated as an int
if possible, otherwise a str
. Reversing the order str | int
will result in the values being treated as str
if possible, otherwise int
. The problem with reversing the order is that pretty much everything can be treated as a str
so the bmw
values will be cast to str
. Example:
from pydantic import BaseModel
class Car(BaseModel):
wheel: str | int
speed: str | int
bmw = Car(wheel=4, speed=250)
mercedes = Car(wheel='4', speed='200')
print(type(bmw.wheel), type(bmw.speed))
print(type(mercedes.wheel), type(mercedes.speed))
<class 'str'> <class 'str'> <class 'str'> <class 'str'>
The key here is that you need to choose which type takes precedence.
Upvotes: 0