Skip to content

Instantly share code, notes, and snippets.

@w495
Last active July 25, 2024 12:52
Show Gist options
  • Save w495/d79e77094ae5324578d3be19d87a0ad4 to your computer and use it in GitHub Desktop.
Save w495/d79e77094ae5324578d3be19d87a0ad4 to your computer and use it in GitHub Desktop.
Validation example with connected fields
import logging
from typing import TypeVar, Literal
from pydantic import BaseModel, root_validator
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
class TestMarkup(BaseModel):
test: str
class TaskMarkup(BaseModel):
task: str
markup_dict = dict(
{
"test-repr": TestMarkup,
"ege-repr": TaskMarkup,
}
)
RendererSlugType = TypeVar('RendererSlugType', *(Literal[x] for x in markup_dict))
MarkupType = TypeVar('MarkupType', *markup_dict.values())
class Markup(BaseModel):
markup: MarkupType
class MarkupWithRenderer(Markup):
renderer_slug: RendererSlugType
class Config:
from_attributess = True
@root_validator(pre=True)
def validate_before(cls, data) -> BaseModel:
logger.debug("validate_before: data - %s", data)
renderer_slug = data.get('renderer_slug')
markup = data.get('markup')
for name, markup_class in markup_dict.items():
if renderer_slug == name:
data['markup'] = markup_class(**markup)
return data
@root_validator(pre=False)
def validate_after(cls, data) -> BaseModel:
logger.debug("validate_after: data - %s", data)
return data
if __name__ == '__main__':
test_repr = MarkupWithRenderer(
renderer_slug='test-repr',
markup=dict(test='test-val')
)
ege_repr = MarkupWithRenderer(
renderer_slug='ege-repr',
markup=dict(task='task-val')
)
# Works only with pydantic > 2.
import logging
from typing import TypeVar, Literal
from pydantic import BaseModel, model_validator
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
class TestMarkup(BaseModel):
test: str
class TaskMarkup(BaseModel):
task: str
markup_dict = dict(
{
"test-repr": TestMarkup,
"ege-repr": TaskMarkup,
}
)
RendererSlugType = TypeVar('RendererSlugType', *(Literal[x] for x in markup_dict))
MarkupType = TypeVar('MarkupType', *markup_dict.values())
class Markup(BaseModel):
markup: MarkupType
class MarkupWithRenderer(Markup):
renderer_slug: RendererSlugType
class Config:
from_attributess = True
@model_validator(mode='before')
@classmethod
def validate_before(cls, data, info) -> BaseModel:
logger.debug("validate_before: info - %s", info)
logger.debug("validate_before: data - %s", data)
renderer_slug = data.get('renderer_slug')
markup = data.get('markup')
for name, markup_class in markup_dict.items():
if renderer_slug == name:
data['markup'] = markup_class(**markup)
return data
@model_validator(mode='after')
@classmethod
def validate_after(cls, data, info) -> BaseModel:
logger.debug("validate_after: info - %s", info)
logger.debug("validate_after: data - %s", data)
return data
if __name__ == '__main__':
test_repr = MarkupWithRenderer(
renderer_slug='test-repr',
markup=dict(test='ss')
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment