-
Hi! I note in documentation for pydantic models, there's a My use case is to generate new XML files with new random content. I can read in an XML file, parse it to a dict, parse it into a pydantic model, store it back as XML, however, if I generate new model object using polyfactory, the naming convention of the field breaks, as e.g. attribute fields need to be prefixed by "@", which requires use of alias in pydantic. In case it's needed, I provide a small toy example below: Example codefrom pprint import pprint
import xmltodict
from polyfactory.factories.pydantic_factory import ModelFactory
from pydantic import BaseModel, Field
# Define some xml, that's a mix of attribute values, and child elements
xml_data = """<?xml version="1.0" encoding="iso-8859-1"?>
<Message xmlns:a="http://www.w3.org/2001/XMLSchema-instance" xmlns:b="https://www.gnu.org/licenses/gpl-3.0.en.html">
<Type V="42" D="display" />
<Version>v3.14 2024-03-13</Version>
<MsgId>6591</MsgId>
</Message>
"""
print("XML-INPUT:\n", xml_data)
# Parse XML to dict, attribute fields are prefixed with "@"
dict_from_xml = xmltodict.parse(xml_data, process_namespaces=False)
print("TO DICT:")
pprint(dict_from_xml)
print("\nDICT BACK TO XML:")
print(xmltodict.unparse(dict_from_xml, pretty=True))
# Define pydantic models
class Base(BaseModel):
V: int = Field(alias="@V")
D: str = Field(alias="@D")
class Message(BaseModel):
xmlns_a: str = Field(..., alias="@xmlns:a")
xmlns_b: str = Field(..., alias="@xmlns:b")
Version: str = Field("v3.14 2024-03-14")
msg_id: int = Field(2398, alias="MsgId")
Type: Base
parsed = Message(**dict_from_xml["Message"])
print("\nPARSED PYDANTIC MODEL", parsed)
# Use polyfactor to generate new data
class MessageFactory(ModelFactory[Message]): ...
d_rand = {"Message": MessageFactory.build().dict()}
print("\nPLOYFACTORY DICT")
pprint(d_rand)
print("\nPLOYFACTORY DICT TO XML:")
print(xmltodict.unparse(d_rand, pretty=True)) Example outputOutput from the code above is the following below. (Note how, as a result of not respecting the alias, the XML generated from the model polyfactory made is not the same structure as the initial. XML inputWe can read in some XML...
TO DICT...convert it to dict, using xmltodict....
DICT BACK TO XML:...and convert it back to the same XML
PARSED PYDANTIC MODELThe dictionary can be parsed by pydantic PLOYFACTORY DICTployfactory can use the pydantic model to generate new values...
PLOYFACTORY DICT TO XML:...however, now
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
Not sure I understood this, but isn't this just about doing |
Beta Was this translation helpful? Give feedback.
-
As an addendum, it was surprising / interesting to realize if I want to over-write one of the fields from default factory, the from polyfactory.factories.pydantic_factory import ModelFactory
from faker import Faker
from pydantic import BaseModel, Field
from uuid import UUID
class Pet(BaseModel):
pet_name: str = Field("John Doe", alias="Name")
class Person(BaseModel):
id: UUID
name: str
pets: Pet
class PetFactory(ModelFactory[Pet]):
__set_as_default_factory_for_type__ = True
__random_seed__ = 40
__faker__ = Faker()
# Note: "pet_name(cls)" will be ignored, use alias "Name(cls)":
@classmethod
def Name(cls) -> str:
return cls.__faker__.name()
class PersonFactory(ModelFactory[Person]):
...
print("\nPERSON:")
print(PersonFactory.build())
print("\nPET:")
print(PetFactory.build()) |
Beta Was this translation helpful? Give feedback.
Not sure I understood this, but isn't this just about doing
d_rand = {"Message": MessageFactory.build().dict(by_alias=True)}
?