# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['pydantic_xml', 'pydantic_xml.backend']

package_data = \
{'': ['*']}

install_requires = \
['pydantic>=1.9.0,<2.0.0']

extras_require = \
{'lxml': ['lxml>=4.9.1,<5.0.0']}

setup_kwargs = {
    'name': 'pydantic-xml',
    'version': '0.5.0',
    'description': 'pydantic xml serialization/deserialization extension',
    'long_description': '[![Downloads][download-badge]][download-url]\n[![License][licence-badge]][licence-url]\n[![Python Versions][python-version-badge]][python-version-url]\n[![Test Status][test-badge]][test-url]\n[![Test Coverage][test-cov-badge]][test-cov-url]\n\n[download-badge]: https://static.pepy.tech/personalized-badge/pydantic-xml?period=month&units=international_system&left_color=grey&right_color=orange&left_text=Downloads/month\n[download-url]: https://pepy.tech/project/pydantic-xml\n[licence-badge]: https://img.shields.io/badge/license-Unlicense-blue.svg\n[licence-url]: https://github.com/dapper91/pydantic-xml/blob/master/LICENSE\n[python-version-badge]: https://img.shields.io/pypi/pyversions/pydantic-xml.svg\n[python-version-url]: https://pypi.org/project/pydantic-xml\n[test-badge]: https://github.com/dapper91/pydantic-xml/actions/workflows/test.yml/badge.svg?branch=master\n[test-url]: https://github.com/dapper91/pydantic-xml/actions/workflows/test.yml\n[test-cov-badge]: https://codecov.io/gh/dapper91/pydantic-xml/branch/master/graph/badge.svg\n[test-cov-url]: https://codecov.io/gh/dapper91/pydantic-xml\n\n# pydantic-xml\n\npydantic xml extension\n\n\n## Installation\n\n```commandline\npip install pydantic-xml[lxml]\n```\n\n* **lxml** - use `lxml` instead of standard `xml.etree.ElementTree` library\n\n## Quickstart\n\n`pydantic-xml` is a pydantic extension implementing model xml serialization/deserialization.\nIt is closely integrated with `pydantic` which means it supports most of the `pydantic` features.\n\nAll xml serializable/deserializable models should be inherited from `BaseXmlModel` base class.\n`BaseXmlModel` implements method `to_xml` to serialize an object to an xml string and `from_xml` to deserialize it.\nModel field data could be extracted from xml attribute, element or text. Field data location is derived\nusing the following rules:\n\n* fields of primitive types (`int`, `float`, `str`, `datetime`, ...) are extracted from element text by default.\n  To alter the default behaviour the field should be marked as `attr` or `element`.\n\n```python\nclass Company(BaseXmlModel):\n    trade_name: str = attr(name=\'trade-name\') # extracted from the \'trade-name\' attribute\n    website: HttpUrl = element() # extracted from the \'website\' element text\n    description: str # extracted from the root element text\n```\n\n```xml\n<Company trade-name="SpaceX">\n    company description text\n    <website>https://www.spacex.com</website>\n</Company>\n```\n\n* fields of model types are extracted from an element.\n\n```python\nclass Headquarters(BaseXmlModel):\n    country: str = element()\n    state: str = element()\n    city: str = element()\n\n\nclass Company(BaseXmlModel):\n    headquarters: Headquarters\n```\n\n```xml\n<Company>\n    <headquarters>\n        <country>US</country>\n        <state>California</state>\n        <city>Hawthorne</city>\n    </headquarters>\n</Company>\n```\n\n* fields of mapping types are extracted from the current element attributes (by default)\n  or from a nested element attributes if the field is marked as `element`.\n\n```python\nclass Company(BaseXmlModel):\n    company_attributes: Dict[str, str]\n    founder_attributes: Dict[str, str] = element(tag=\'Founder\')\n```\n\n```xml\n<Company trade-name="SpaceX" type="Private">\n    <Founder name="Elon" surname="Musk"/>\n</Company>\n```\n\n* fields of collection types (`list`, `tuple`, `set`, ...) are extracted from multiple elements with the same name.\n\n```python\nclass Product(BaseXmlModel):\n    status: Literal[\'running\', \'development\'] = attr()\n    launched: Optional[int] = attr()\n    title: str\n\n\nclass Company(BaseXmlModel):\n    products: List[Product] = element(tag=\'product\')\n```\n\n```xml\n<Company>\n    <product status="running" launched="2013">Several launch vehicles</product>\n    <product status="running" launched="2019">Starlink</product>\n    <product status="development">Starship</product>\n</Company>\n```\n\n* wrapped fields are extracted from a sub-element located at the provided path.\n\n```python\nclass Social(BaseXmlModel):\n    type: str = attr()\n    url: str\n\n\nclass Company(BaseXmlModel):\n    socials: List[Social] = wrapped(\'contacts/socials\', element(tag=\'social\'))\n```\n\n```xml\n<Company>\n    <contacts>\n        <socials>\n            <social type="linkedin">https://www.linkedin.com/company/spacex</social>\n            <social type="twitter">https://twitter.com/spacex</social>\n            <social type="youtube">https://www.youtube.com/spacex</social>\n        </socials>\n    </contacts>\n</Company>\n```\n\nThe following example illustrates all previously described rules in conjunction with some `pydantic` feature:\n\n*company.xml:*\n\n```xml\n<Company trade-name="SpaceX" type="Private" xmlns:pd="http://www.test.com/prod">\n    <Founder name="Elon" surname="Musk"/>\n    <Founded>2002-03-14</Founded>\n    <Employees>12000</Employees>\n    <WebSite>https://www.spacex.com</WebSite>\n\n    <Industries>\n        <Industry>space</Industry>\n        <Industry>communications</Industry>\n    </Industries>\n\n    <key-people>\n        <person position="CEO" name="Elon Musk"/>\n        <person position="CTO" name="Elon Musk"/>\n        <person position="COO" name="Gwynne Shotwell"/>\n    </key-people>\n\n    <hq:headquarters xmlns:hq="http://www.test.com/hq">\n        <hq:country>US</hq:country>\n        <hq:state>California</hq:state>\n        <hq:city>Hawthorne</hq:city>\n    </hq:headquarters>\n\n    <co:contacts xmlns:co="http://www.test.com/contact" >\n        <co:socials>\n            <co:social co:type="linkedin">https://www.linkedin.com/company/spacex</co:social>\n            <co:social co:type="twitter">https://twitter.com/spacex</co:social>\n            <co:social co:type="youtube">https://www.youtube.com/spacex</co:social>\n        </co:socials>\n    </co:contacts>\n\n    <pd:product pd:status="running" pd:launched="2013">Several launch vehicles</pd:product>\n    <pd:product pd:status="running" pd:launched="2019">Starlink</pd:product>\n    <pd:product pd:status="development">Starship</pd:product>\n</Company>\n```\n\n*main.py:*\n\n```python\nfrom datetime import date\nfrom enum import Enum\nfrom typing import Dict, List, Optional, Set, Literal, Tuple\n\nimport pydantic as pd\nfrom pydantic import conint, HttpUrl\n\nfrom pydantic_xml import BaseXmlModel, attr, element, wrapped\n\nNSMAP = {\n    \'co\': \'http://www.test.com/contact\',\n    \'hq\': \'http://www.test.com/hq\',\n    \'pd\': \'http://www.test.com/prod\',\n}\n\n\nclass Headquarters(BaseXmlModel, ns=\'hq\', nsmap=NSMAP):\n    country: str = element()\n    state: str = element()\n    city: str = element()\n\n    @pd.validator(\'country\')\n    def validate_country(cls, value: str) -> str:\n        if len(value) > 2:\n            raise ValueError(\'country must be of 2 characters\')\n        return value\n\n\nclass Industries(BaseXmlModel):\n    __root__: Set[str] = element(tag=\'Industry\')\n\n\nclass Social(BaseXmlModel, ns_attrs=True, ns=\'co\', nsmap=NSMAP):\n    type: str = attr()\n    url: str\n\n\nclass Product(BaseXmlModel, ns_attrs=True, ns=\'pd\', nsmap=NSMAP):\n    status: Literal[\'running\', \'development\'] = attr()\n    launched: Optional[int] = attr()\n    title: str\n\n\nclass Person(BaseXmlModel):\n    name: str = attr()\n\n\nclass CEO(Person):\n    position: Literal[\'CEO\'] = attr()\n\n\nclass CTO(Person):\n    position: Literal[\'CTO\'] = attr()\n\n\nclass COO(Person):\n    position: Literal[\'COO\'] = attr()\n\n\nclass Company(BaseXmlModel, tag=\'Company\', nsmap=NSMAP):\n    class CompanyType(str, Enum):\n        PRIVATE = \'Private\'\n        PUBLIC = \'Public\'\n\n    trade_name: str = attr(name=\'trade-name\')\n    type: CompanyType = attr()\n    employees: conint(gt=0) = element(tag=\'Employees\')\n    website: HttpUrl = element(tag=\'WebSite\')\n\n    founder: Dict[str, str] = element(tag=\'Founder\')\n    founded: Optional[date] = element(tag=\'Founded\')\n    industries: Industries = element(tag=\'Industries\')\n\n    key_people: Tuple[CEO, CTO, COO] = wrapped(\'key-people\', element(tag=\'person\'))\n    headquarters: Headquarters\n    socials: List[Social] = wrapped(\n        \'contacts/socials\',\n        element(tag=\'social\', default_factory=list),\n        ns=\'co\',\n        nsmap=NSMAP,\n    )\n\n    products: Tuple[Product, ...] = element(tag=\'product\', ns=\'pd\')\n\n\nwith open(\'company.xml\') as file:\n    document = file.read()\n\ncompany = Company.from_xml(document)\n\nprint(company)\n\n```\n\n### Name resolution:\n\n**TBD**\n\n\n### Namespace resolution:\n\n#### Default namespace\n\nTo parse xml documents with a declared default namespace add it to `nsmap`  with an empty key.\nLook at the following example:\n\n```xml\n<headquarters xmlns="http://www.test.com/hq">\n    <country>US</country>\n    <state>California</state>\n    <city>Hawthorne</city>\n</headquarters>\n```\n\n```python\nclass Headquarters(BaseXmlModel, tag=\'headquarters\', nsmap={\'\': \'http://www.test.com/hq\'}):\n    country: str = element()\n    state: str = element()\n    city: str = element()\n```\n\n**TBD**\n\n\n### Generics:\n\n`pydantic` library supports [generic-models](https://pydantic-docs.helpmanual.io/usage/models/#generic-models).\n`pydantic-xml` supports it either. To declare one inherit your model from `BaseGenericXmlModel`,\nthe rest is the same as `pydantic` generic model declaration.\n\nThe following example illustrates it:\n\n*request.xml:*\n\n```xml\n<request service-name="api-gateway"\n         request-id="27765d90-f3ef-426f-be9d-8da2b405b4a9"\n         timestamp="2019-06-12T12:21:34.123+00:00">\n    <auth type="basic">\n        <user>gw</user>\n        <password>secret</password>\n    </auth>\n    <payload type="rpc">\n        <method>crete_event</method>\n        <param name="timestamp">1660892066.1952798</param>\n        <param name="user">admin</param>\n        <param name="method">POST</param>\n        <param name="resource">https://api-gateway.test.com/api/v1/users</param>\n    </payload>\n</request>\n```\n\n*main.py:*\n\n```python\nimport datetime as dt\nfrom typing import Generic, Optional, Tuple, TypeVar\n\nfrom pydantic import HttpUrl\n\nimport pydantic_xml as pxml\n\n\nclass BasicAuth(pxml.BaseXmlModel):\n    type: str = pxml.attr()\n    user: str = pxml.element()\n    password: str = pxml.element()\n\n\nAuthType = TypeVar(\'AuthType\')\nPayloadType = TypeVar(\'PayloadType\')\n\n\nclass Request(pxml.BaseGenericXmlModel, Generic[AuthType, PayloadType], tag=\'request\'):\n    service_name: str = pxml.attr(name=\'service-name\')\n    request_id: str = pxml.attr(name=\'request-id\')\n    timestamp: dt.datetime = pxml.attr()\n\n    auth: Optional[AuthType]\n\n    payload: PayloadType\n\n\nParamsType = TypeVar(\'ParamsType\')\nParamType = TypeVar(\'ParamType\')\n\n\nclass Rpc(pxml.BaseGenericXmlModel, Generic[ParamsType]):\n    class Param(pxml.BaseGenericXmlModel, Generic[ParamType]):\n        name: str = pxml.attr()\n        value: ParamType\n\n    method: str = pxml.element()\n    params: ParamsType = pxml.element(tag=\'param\')\n\n\nwith open(\'request.xml\') as file:\n    xml = file.read()\n\nrequest = Request[\n    BasicAuth,\n    Rpc[\n        Tuple[\n            Rpc.Param[float],\n            Rpc.Param[str],\n            Rpc.Param[str],\n            Rpc.Param[HttpUrl]\n        ]\n    ]\n].from_xml(xml)\n\nprint(request.json(indent=4))\n```\n\n*output:*\n\n```json\n{\n    "service_name": "api-gateway",\n    "request_id": "27765d90-f3ef-426f-be9d-8da2b405b4a9",\n    "timestamp": "2019-06-12T12:21:34.123000+00:00",\n    "auth": {\n        "type": "basic",\n        "user": "gw",\n        "password": "secret"\n    },\n    "payload": {\n        "method": "crete_event",\n        "params": [\n            {\n                "name": "timestamp",\n                "value": 1660892066.1952798\n            },\n            {\n                "name": "user",\n                "value": "admin"\n            },\n            {\n                "name": "method",\n                "value": "POST"\n            },\n            {\n                "name": "resource",\n                "value": "https://api-gateway.test.com/api/v1/users"\n            }\n        ]\n    }\n}\n```\n\n\n### Self-referencing models:\n\n`pydantic` library supports [self-referencing models](https://pydantic-docs.helpmanual.io/usage/postponed_annotations/#self-referencing-models).\n`pydantic-xml` supports it either.\n\n*request.xml:*\n\n```xml\n<Directory Name="root" Mode="rwxr-xr-x">\n    <Directory Name="etc" Mode="rwxr-xr-x">\n        <File Name="passwd" Mode="-rw-r--r--"/>\n        <File Name="hosts" Mode="-rw-r--r--"/>\n        <Directory Name="ssh" Mode="rwxr-xr-x"/>\n    </Directory>\n    <Directory Name="bin" Mode="rwxr-xr-x"/>\n    <Directory Name="usr" Mode="rwxr-xr-x">\n        <Directory Name="bin" Mode="rwxr-xr-x"/>\n    </Directory>\n</Directory>\n```\n\n*main.py:*\n\n```python\nfrom typing import List, Optional\n\nimport pydantic_xml as pxml\n\n\nclass File(pxml.BaseXmlModel, tag="File"):\n    name: str = pxml.attr(name=\'Name\')\n    mode: str = pxml.attr(name=\'Mode\')\n\n\nclass Directory(pxml.BaseXmlModel, tag="Directory"):\n    name: str = pxml.attr(name=\'Name\')\n    mode: str = pxml.attr(name=\'Mode\')\n    dirs: Optional[List[\'Directory\']] = pxml.element(tag=\'Directory\')\n    files: Optional[List[File]] = pxml.element(tag=\'File\', default_factory=list)\n\n\nwith open(\'request.xml\') as file:\n    xml = file.read()\n\nroot = Directory.from_xml(xml)\nprint(root.json(indent=4))\n\n```\n\n*output:*\n\n```json\n{\n    "name": "root",\n    "mode": "rwxr-xr-x",\n    "dirs": [\n        {\n            "name": "etc",\n            "mode": "rwxr-xr-x",\n            "dirs": [\n                {\n                    "name": "ssh",\n                    "mode": "rwxr-xr-x",\n                    "dirs": [],\n                    "files": []\n                }\n            ],\n            "files": [\n                {\n                    "name": "passwd",\n                    "mode": "-rw-r--r--"\n                },\n                {\n                    "name": "hosts",\n                    "mode": "-rw-r--r--"\n                }\n            ]\n        },\n        {\n            "name": "bin",\n            "mode": "rwxr-xr-x",\n            "dirs": [],\n            "files": []\n        },\n        {\n            "name": "usr",\n            "mode": "rwxr-xr-x",\n            "dirs": [\n                {\n                    "name": "bin",\n                    "mode": "rwxr-xr-x",\n                    "dirs": [],\n                    "files": []\n                }\n            ],\n            "files": []\n        }\n    ],\n    "files": []\n}\n```\n\n### JSON\n\nSince `pydantic` supports json serialization, `pydantic-xml` could be used as xml-to-json transcoder:\n\n```python\n...\n\nwith open(\'company.xml\') as file:\n    xml = file.read()\n\ncompany = Company.from_xml(xml)\n\nprint(company.json(indent=4))\n```\n\n*output:*\n\n```json\n{\n    "trade_name": "SpaceX",\n    "type": "Private",\n    "employees": 12000,\n    "website": "https://www.spacex.com",\n    "founder": {\n        "name": "Elon",\n        "surname": "Musk"\n    },\n    "founded": "2002-03-14",\n    "industries": [\n        "space",\n        "communications"\n    ],\n    "key_people": [\n        {\n            "name": "Elon Musk",\n            "position": "CEO"\n        },\n        {\n            "name": "Elon Musk",\n            "position": "CTO"\n        },\n        {\n            "name": "Gwynne Shotwell",\n            "position": "COO"\n        }\n    ],\n    "headquarters": {\n        "country": "US",\n        "state": "California",\n        "city": "Hawthorne"\n    },\n    "socials": [\n        {\n            "type": "linkedin",\n            "url": "https://www.linkedin.com/company/spacex"\n        },\n        {\n            "type": "twitter",\n            "url": "https://twitter.com/spacex"\n        },\n        {\n            "type": "youtube",\n            "url": "https://www.youtube.com/spacex"\n        }\n    ],\n    "products": [\n        {\n            "status": "running",\n            "launched": 2013,\n            "title": "Several launch vehicles"\n        },\n        {\n            "status": "running",\n            "launched": 2019,\n            "title": "Starlink"\n        },\n        {\n            "status": "development",\n            "launched": null,\n            "title": "Starship"\n        }\n    ]\n}\n```\n\n\n### XML parser\n\n`pydantic-xml` tries to use the fastest xml parser in your system. It uses `lxml` if it is installed\nin your environment otherwise falls back to the standard library xml parser.\n\n\n### Custom type serialization\n\nOnly several primitive standard type serialization are supported\n(`str`, `int`, `float`, `Decimal`, `bool`, `datetime`, `date`, `time`).\nTo allow custom types serialization `BaseXmlModel.to_xml` method takes an optional encoder as an argument.\nA custom one should be inherited from `XmlEncoder`.\n\nThe following example illustrate how to implement `bytes` type xml serialization:\n\n*file1.txt:*\n\n```text\nhello world!!!\n```\n\n*file2.txt:*\n\n```text\ntest\n```\n\n*main.py:*\n\n```python\nimport base64\nfrom typing import Any, List\nfrom pydantic_xml import BaseXmlModel, XmlEncoder, attr, element\n\n\nclass CustomXmlEncoder(XmlEncoder):\n    def encode(self, obj: Any) -> str:\n        if isinstance(obj, bytes):\n            return base64.b64encode(obj).decode()\n\n        return super().encode(obj)\n\n\nclass File(BaseXmlModel):\n    name: str = attr()\n    content: bytes = element()\n\n\nclass Files(BaseXmlModel, tag=\'files\'):\n    __root__: List[File] = element(tag=\'file\', default=[])\n\n\nfiles = Files()\nfor filename in [\'file1.txt\', \'file2.txt\']:\n    with open(filename, \'rb\') as f:\n        content = f.read()\n\n    files.__root__.append(File(name=filename, content=content))\n\nxml = files.to_xml(encoder=CustomXmlEncoder(), pretty_print=True, encoding=\'UTF-8\', standalone=True)\nprint(xml.decode())\n```\n\n*output:*\n\n```xml\n<?xml version=\'1.0\' encoding=\'UTF-8\' standalone=\'yes\'?>\n<files>\n  <file name="file1.txt">\n    <content>aGVsbG8gd29ybGQhISE=</content>\n  </file>\n  <file name="file2.txt">\n    <content>dGVzdA==</content>\n  </file>\n</files>\n```\n\n\n### Data modeling\n\nThis section provides examples of the most common use-cases with xml and json outputs.\n\n#### Primitive types:\n\n```python\nclass Company(BaseXmlModel):\n    class CompanyType(str, Enum):\n        PRIVATE = \'Private\'\n        PUBLIC = \'Public\'\n\n    trade_name: str = attr(name=\'trade-name\')\n    type: CompanyType = attr()  # field name is used as an attribute name by default\n    founded: Optional[date] = element(tag=\'Founded\')\n```\n\n```xml\n<Company trade-name="SpaceX" type="Private">\n    <Founded>2002-03-14</Founded>\n</Company>\n```\n\n```json\n{\n    "trade_name": "SpaceX",\n    "type": "Private",\n    "founded": "2002-03-14"\n}\n```\n--------------------------------------------------------------------------------\n\n```python\nclass Product(BaseXmlModel):\n    status: Literal[\'running\', \'development\'] = attr()\n    launched: Optional[int] = attr()\n    title: str  # primitive types are extracted from the element text by default\n```\n\n```xml\n<Product status="running" launched="2019">Starlink</Product>\n```\n\n```json\n{\n    "status": "running",\n    "launched": 2019,\n    "title": "Starlink"\n}\n```\n--------------------------------------------------------------------------------\n\n\n#### Sub-models:\n\n```python\nclass Headquarters(BaseXmlModel):\n    country: str = element()\n    state: str = element()\n    city: str = element()\n\n\nclass Product(BaseXmlModel):\n    status: Literal[\'running\', \'development\'] = attr()\n    launched: Optional[int] = attr()\n    title: str\n\n\nclass Company(BaseXmlModel):\n    headquarters: Headquarters  # models are extracted from the element by default\n    products: Tuple[Product, ...] = element(tag=\'product\')\n```\n\n```xml\n<Company>\n    <headquarters>\n        <country>US</country>\n        <state>California</state>\n        <city>Hawthorne</city>\n    </headquarters>\n\n    <product status="running" launched="2013">Several launch vehicles</product>\n    <product status="running" launched="2019">Starlink</product>\n    <product status="development">Starship</product>\n</Company>\n```\n\n```json\n{\n    "headquarters": {\n        "country": "US",\n        "state": "California",\n        "city": "Hawthorne"\n    },\n    "products": [\n        {\n            "status": "running",\n            "launched": 2013,\n            "title": "Several launch vehicles"\n        },\n        {\n            "status": "running",\n            "launched": 2019,\n            "title": "Starlink"\n        },\n        {\n            "status": "development",\n            "launched": null,\n            "title": "Starship"\n        }\n    ]\n}\n```\n--------------------------------------------------------------------------------\n\n```python\nclass Founded(BaseXmlModel):\n    __root__: datetime.date\n\nclass Company(BaseXmlModel):\n    founded: Founded = element(tag=\'Founded\')\n```\n\n```xml\n<Company>\n    <Founded>2002-03-14</Founded>\n</Company>\n```\n\n```json\n{\n    "founded": "2002-03-14"\n}\n```\n--------------------------------------------------------------------------------\n\n\n#### Mappings:\n\n```python\nclass Company(BaseXmlModel):\n    founder: Dict[str, str] = element(tag=\'Founder\')\n```\n\n```xml\n<Company>\n    <Founder name="Elon" surname="Musk"/>\n</Company>\n```\n\n```json\n{\n    "founder": {\n        "name": "Elon",\n        "surname": "Musk"\n    }\n}\n```\n--------------------------------------------------------------------------------\n\n```python\nclass Founder(BaseXmlModel):\n    __root__: Dict[str, str]  # mappings are extracted from attributes by default\n```\n\n```xml\n<Founder name="Elon" surname="Musk"/>\n```\n\n```json\n{\n    "name": "Elon",\n    "surname": "Musk"\n}\n```\n--------------------------------------------------------------------------------\n\n\n#### Homogeneous collections:\n\n```python\nclass Industries(BaseXmlModel):\n    __root__: Set[str] = element(tag=\'industry\')\n\n\nclass Social(BaseXmlModel):\n    type: str = attr()\n    url: str\n\n\nclass Product(BaseXmlModel):\n    status: Literal[\'running\', \'development\'] = attr()\n    launched: Optional[int] = attr()\n    title: str\n\n\nclass Company(BaseXmlModel):\n    industries: Industries = element()\n    socials: List[Social] = element(tag=\'social\', default_factory=list)\n    products: Tuple[Product, ...] = element(tag=\'product\')\n```\n\n```xml\n<Company>\n    <industries>\n        <industry>space</industry>\n        <industry>communications</industry>\n    </industries>\n\n    <social type="linkedin">https://www.linkedin.com/company/spacex</social>\n    <social type="twitter">https://twitter.com/spacex</social>\n    <social type="youtube">https://www.youtube.com/spacex</social>\n\n    <product status="running" launched="2013">Several launch vehicles</product>\n    <product status="running" launched="2019">Starlink</product>\n    <product status="development">Starship</product>\n</Company>\n```\n\n```json\n{\n    "industries": [\n        "space",\n        "communications"\n    ],\n    "socials": [\n        {\n            "type": "linkedin",\n            "url": "https://www.linkedin.com/company/spacex"\n        },\n        {\n            "type": "twitter",\n            "url": "https://twitter.com/spacex"\n        },\n        {\n            "type": "youtube",\n            "url": "https://www.youtube.com/spacex"\n        }\n    ],\n    "products": [\n        {\n            "status": "running",\n            "launched": 2013,\n            "title": "Several launch vehicles"\n        },\n        {\n            "status": "running",\n            "launched": 2019,\n            "title": "Starlink"\n        },\n        {\n            "status": "development",\n            "launched": null,\n            "title": "Starship"\n        }\n    ]\n}\n```\n--------------------------------------------------------------------------------\n\n\n#### Heterogeneous collections:\n\n```python\nclass Person(BaseXmlModel):\n    name: str = attr()\n\n\nclass CEO(Person):\n    position: Literal[\'CEO\'] = attr()\n\n\nclass CTO(Person):\n    position: Literal[\'CTO\'] = attr()\n\n\nclass COO(Person):\n    position: Literal[\'COO\'] = attr()\n\n\nclass Company(BaseXmlModel):\n    key_people: Tuple[CEO, CTO, COO] = element(tag=\'person\')\n```\n\n```xml\n<Company>\n    <person position="CEO" name="Elon Musk"/>\n    <person position="CTO" name="Elon Musk"/>\n    <person position="COO" name="Gwynne Shotwell"/>\n</Company>\n```\n\n```json\n{\n    "key_people": [\n        {\n            "name": "Elon Musk",\n            "position": "CEO"\n        },\n        {\n            "name": "Elon Musk",\n            "position": "CTO"\n        },\n        {\n            "name": "Gwynne Shotwell",\n            "position": "COO"\n        }\n    ]\n}\n```\n--------------------------------------------------------------------------------\n\n\n#### Wrapped entities:\n\n```python\nclass Company(BaseXmlModel):\n    hq_country: str = wrapped(\'headquarters/country\')\n    hq_state: str = wrapped(\'headquarters/state\')\n    hq_city: str = wrapped(\'headquarters/city\')\n```\n\n```xml\n<Company>\n    <headquarters>\n        <country>US</country>\n        <state>California</state>\n        <city>Hawthorne</city>\n    </headquarters>\n</Company>\n```\n\n```json\n{\n    "hq_country": "US",\n    "hq_state": "California",\n    "hq_city": "Hawthorne"\n}\n```\n--------------------------------------------------------------------------------\n\n\n```python\nclass Social(BaseXmlModel):\n    type: str = attr()\n    url: str\n\n\nclass Company(BaseXmlModel):\n    socials: List[Social] = wrapped(\'contacts/socials\', element(tag=\'social\', default_factory=list))\n```\n\n```xml\n<Company>\n    <contacts>\n        <socials>\n            <social type="linkedin">https://www.linkedin.com/company/spacex</social>\n            <social type="twitter">https://twitter.com/spacex</social>\n            <social type="youtube">https://www.youtube.com/spacex</social>\n        </socials>\n    </contacts>\n</Company>\n```\n\n```json\n{\n    "socials": [\n        {\n            "type": "linkedin",\n            "url": "https://www.linkedin.com/company/spacex"\n        },\n        {\n            "type": "twitter",\n            "url": "https://twitter.com/spacex"\n        },\n        {\n            "type": "youtube",\n            "url": "https://www.youtube.com/spacex"\n        }\n    ]\n}\n```\n--------------------------------------------------------------------------------\n\n```python\nclass Company(BaseXmlModel):\n    persons: List[Dict[str, str]] = wrapped(\'key-people\', element(tag="person"))\n```\n\n```xml\n<Company>\n    <key-people>\n        <person position="CEO" name="Elon Musk"/>\n        <person position="CTO" name="Elon Musk"/>\n        <person position="COO" name="Gwynne Shotwell"/>\n    </key-people>\n</Company>\n```\n\n```json\n{\n    "persons": [\n        {\n            "position": "CEO",\n            "name": "Elon Musk"\n        },\n        {\n            "position": "CTO",\n            "name": "Elon Musk"\n        },\n        {\n            "position": "COO",\n            "name": "Gwynne Shotwell"\n        }\n    ]\n}\n```\n--------------------------------------------------------------------------------\n',
    'author': 'Dmitry Pershin',
    'author_email': 'dapper1291@gmail.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'https://github.com/dapper91/pydantic-xml',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'extras_require': extras_require,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
