Home > OS >  pydantic models to reference another class
pydantic models to reference another class

Time:12-27

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

  • Related