Package: dataclass-mapper
Writing mapper methods between two similar dataclasses is boring, need to be actively maintained and are error-prone.
Much better to let this library auto-generate them for you.The focus of this library is:Concise and easy syntax:using it has to be a lot less overhead than writing the mappers by handtrivial mappings should not require codeidentical syntax for mapping between dataclasses and Pydantic modelsSafety:using this library must give equal or more type safety than writing the mappers by handthe types between source and target classes must matches (including optional checks)all target fields must be actually initializedmappings cannot reference non-existing fieldsin case of an error a clean exception must be raisedPerformance:mapping an object using this library must be the same speed than mapping using a custom mapper functionthe type checks shouldn’t slow down the programbecause of the first two points, all type checks and the generation of the mapper functions happen during the definition of the classesMotivationA couple of example usecases, that show why this library might be useful.Given an API with multiple, different interfaces (e.g. different API versions), that are all connected to a common algorithm with some common datamodel.
All the different API models needs to be mapped to the common datamodel, and afterwards mapped back to the API model.Given an API that has aPOSTand aGETendpoint.
Both models (POSTrequest body model andGETresponse body model) are almost the same, but there are some minor differences.
E.g. response model has an additionalidparameter.
You need a way of mapping the request model to a response model.Installationdataclass-mappercan be installed using:pipinstalldataclass-mapper# or for Pydantic supportpipinstall'dataclass-mapper[pydantic]'ExampleWe have the following target data structure, a class calledPerson.>>>fromdataclassesimportdataclass>>>@dataclass...classPerson:...first_name:str...second_name:str...age:intWe want to have a mapper from the source data structure, a class calledContactInfo.
Notice that the attributesecond_nameofPersonis calledsurnameinContactInfo.
Other than that, all the attribute names are the same.Instead of writing a mapper function by hand, you can let it autogenerate one using this library:>>>fromdataclass_mapperimportmap_to,mapper>>>>>>@mapper(Person,{"second_name":"surname"})...@dataclass...classContactInfo:...first_name:str...surname:str...age:int>>>>>>contact=ContactInfo(first_name="Henry",surname="Kaye",age=42)>>>map_to(contact,Person)Person(first_name='Henry',second_name='Kaye',age=42)Thedataclass-mapperlibrary autogenerated a mapper, that can be used with themap_tofunction.
All we had to specify was the name of the target class, and optionally specify which fields map to which other fields.
Notice that we only had to specify that thesecond_namefield has to be mapped tosurname,
all other fields were mapped automatically because the field names didn’t change.And thedataclass-mapperlibrary will perform a lot of checks around this mapping.
It will check if the data types match, if some fields would be left uninitialized, etc.FeaturesThe current version has support for:Python’sdataclass(with recursive models, custom initializers, optional types, extra-context, …): seeSupported featuresfor the full list and examplesMappings between Enum classes:  seeEnum mappingsPydantic models:  seePydantic supportType/Value checks:  seeType safetyContributingSeeCONTRIBUTING.rst.LicenseThe project is released under theMIT license.