Assuming I have a layer or an internal package that exposes standard dataclasses, but now I need serialize, desserialize and validate this data. I would love use pydantic but it's annoying rewrite a Model or a pydantic.dataclasses with same body.
This scenario is possible when part of my library are not within my control (my company having several teams, and not all of them agreed using pydantic, but some of them provides libraries with standard dataclasses.
Besides that, I do not need runtime validation in every layer of my application
Something like:
dataclass.py
from dataclasses import dataclass
@dataclass
class Data:
id: int
name: str
In Application layer
from pydantic.dataclasses import parse_obj_to_dataclass
data: Data = parse_obj_to_dataclass({'id': 1, 'name': 'dnp1'}, Data)
# or
model: Model[Data] = model_from_dataclass(Data)
model.parse_obj({'id':2, 'name': 'dnp1'})
It could be a generic function taking T and returning T
It make sense to you?
Hello @dnp1
Does https://github.com/samuelcolvin/pydantic/pull/1817 solve your problem ?
from dataclasses import dataclass
from pydantic.dataclasses import dataclass as pydanticdataclass
@dataclass
class Data:
id: int
name: str
DataclassWithValidation = pydanticdataclass(Data)
DataclassWithValidation(id='123', name='qwe') # ok
PydanticModel = DataclassWithValidation.__pydantic_model__
PydanticModel.parse_obj({'id':2, 'name': 'dnp1'}) # ok
Hello @PrettyWood!
Yes it does.
I'll take a closer look at it.
static typing checkers will consider DataclassWithValidation a subclass of Data?
@dnp1 I let you have a look at the PR and try it out. I'm looking for feedback before writing the documentation. Any help is welcome 馃檪
@PrettyWood can't wait for your PR to merge :-)
I'm wondering now, if there would be a nice way to add additional (field)validators to the generated pydantic model?
@dnp1 yes it will be a subclass
@torstenrudolf it should be possible easily as it will be a regular pydantic.dataclasses
@pydanticdataclass
@dataclass
class Data:
id: int
name: str
@validator('name')
def long_name(cls, name):
assert len(name) > 10
return name
Data(id='123', name='qwe')
# pydantic.error_wrappers.ValidationError: 1 validation error for Data
# name
# (type=assertion_error)
or if you don't want to/can't touch the builtin dataclass
@dataclass
class Data:
id: int
name: str
@pydanticdataclass
class DataWithValidation(Data):
@validator('name')
...
Did I misunderstand your question?
If anyone wants this, this is the way to do it since v1.7
from typing import Type
from pydantic import BaseModel
from pydantic.dataclasses import dataclass as pydantic_dataclass
def model_from_dataclass(kls: 'StdlibDataclass') -> Type[BaseModel]:
"""Converts a stdlib dataclass to a pydantic BaseModel"""
return pydantic_dataclass(kls).__pydantic_model__
This function could be added directly in _pydantic_ if there are many upvotes I reckon
Most helpful comment
@dnp1 yes it will be a subclass
@torstenrudolf it should be possible easily as it will be a regular
pydantic.dataclassesor if you don't want to/can't touch the builtin dataclass
Did I misunderstand your question?