Is it possible on a pydantic model to reference another class? For example below in the ReadRequestModel
in point_type
I am trying to figure out if its possible reference that only these "types of points" in a string format can be chosen:
# type-of-points
# just for reference
multiStateValue
multiStateInput
multiStateOutput
analogValue
analogInput
analogOutput
binaryValue
binaryInput
binaryOutput
And depending on what point_type
is that depics what type of point_id
can be chosen that I am trying to reference in the PointType
class.
from typing import List, Literal, Optional
from pydantic import BaseModel
BOOLEAN_ACTION_MAPPING = Literal["active", "inactive"]
class ReadRequestModel(BaseModel):
device_address: str
point_type: PointType <--- not correct
point_id: PointType <--- not correct
class PointType(BaseModel):
multiStateValue: Optional[int]
multiStateInput: Optional[int]
multiStateOutput: Optional[int]
analogValue: Optional[int]
analogInput: Optional[int]
analogOutput: Optional[int]
binaryValue: Optional[BOOLEAN_ACTION_MAPPING]
binaryInput: Optional[BOOLEAN_ACTION_MAPPING]
binaryOutput: Optional[BOOLEAN_ACTION_MAPPING]
r = ReadRequestModel({'device_address': '12345:5',
'point_type': 'analogInput',
'point_id': 8})
print(r)
The idea for the request above r
it should be valid because the point_type
is correct (per type-of-points
) and the point_id
for an analogInput
is an int type. Hopefully this makes sense not a lot of wisdom here but there is documentation for this on the pydantic website but I am having some difficulties trying to figure it out. Any tips appreciated.
The code above that has some major issues will just print that the point_type: PointType NameError: name 'PointType' is not defined
CodePudding user response:
Try like this:
from typing import Literal
class ReadRequestModel(BaseModel):
device_address: str
point_type: Literal["multiStateValue", "multiStateInput", "multiStateOutput", "analogValue", "analogInput", "analogOutput", "binaryValue", "binaryInput", "binaryOutput"]
point_id: int
or
from enum import Enum
class PointTypeEnum(str, Enum):
multiStateValue = "multiStateValue"
multiStateInput = "multiStateInput"
multiStateOutput = "multiStateOutput"
analogValue = "analogValue"
analogInput = "analogInput"
analogOutput = "analogOutput"
binaryValue = "binaryValue"
binaryInput = "binaryInput"
binaryOutput = "binaryOutput"
class ReadRequestModel(BaseModel):
device_address: str
point_type: PointTypeEnum
point_id: int
This should allow you to use the PointTypeEnum class in a similar way to the Literal type, but with the added benefits of being able to iterate over the values, etc.
CodePudding user response:
Python loads module content from top to bottom.
That means that you need to place your PointType
definition before the ReadRequestModel
and it will work