'How to create a Python ABC interface pattern using Pydantic
I'm implementing a Python Interface using the abstract base class (known as the strategy pattern). I want to be able to do this with Pydantic.
Without Pydantic, I would use properties, like this:
from abc import ABC, abstractproperty
@dataclass
class PersonEntity(ABC):
@abstractproperty
def first_name(self):
raise NotImplementedError
@abstractproperty
def last_name(self):
raise NotImplementedError
@dataclass
class Person(PersonEntity):
@property
def first_name(self):
return 'Jimmy'
@property
def last_name(self):
return 'Kelly'
This way, if I were to implement another class, like
@dataclass
class SillyPerson(PersonEntity):
@property
def first_name(self):
return 'Jimmy'
@property
def last_name(self):
return 'Kelly'
@property
def sillyness(self):
return 5
then the interface will throw an error. This helps constrain any new class that inherits from PersonEntity.
However, I want to spit this information into a FastAPI response object. I cannot do this without figuring out some kind of serializer to grab all the values of each property field, and just the property fields (which I'm struggling to do).
I would rather use Pydantic. In this case, I dont need properties, I can simply do:
from pydantic import BaseModel
class PersonEntity(ABC, BaseModel):
first_name: str
last_name: str
class Person(PersonEntity):
first_name: str
last_name: str
These will serialize in the way that I need, but I lose the interface functionality because now
I have no properties, and therefore cannot use @abstractproperty.
So if I were to implement
class SillyPerson(PersonEntity):
first_name: str
last_name: str
sillyness: str
there's no error, because pydantic allows this.
(Incidentally, I wasn't sure in these examples whether to inherit from BaseModel in child classes or not.)
Is there some way I can constrain the Pydantic model to give me the interface behaviour that I need, throwing errors
when a field is introduced that is not included in the ABC PersonEntity class?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
