python-datamodel


Namepython-datamodel JSON
Version 0.9.1 PyPI version JSON
download
home_pagehttps://github.com/phenobarbital/python-datamodel
Summarysimple library based on python +3.8 to use Dataclass-syntaxfor interacting with Data
upload_time2025-01-21 04:07:11
maintainerNone
docs_urlNone
authorJesus Lara
requires_python>=3.9.13
licenseBSD
keywords asyncio dataclass dataclasses data models
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # DataModel
DataModel is a simple library based on python +3.8 to use Dataclass-syntax for interacting with
Data, using the same syntax of Dataclass, users can write Python Objects
and work with Data in the same way (like ORM's), is a reimplementation of python Dataclasses supporting true inheritance (without decorators), true composition and other good features.

The key features are:
* **Easy to use**: No more using decorators, concerns abour re-ordering attributes or common problems with using dataclasses with inheritance.
* **Extensibility**: Can use other dataclasses, Data objects or primitives as data-types.
* **Fast**: DataModel is a replacement 100% full compatible with dataclasses, without any overhead.



## Requirements

Python 3.8+

## Installation

<div class="termy">

```console
$ pip install python-datamodel
---> 100%
Successfully installed datamodel
```


</div>

## Quickstart


```python

from datamodel import Field, BaseModel
from dataclasses import dataclass, fields, is_dataclass


# This pure Dataclass:
@dataclass
class Point:
    x: int = Field(default=0, min=0, max=10)
    y: int = Field(default=0, min=0, max=10)

point = Point(x=10, y=10)
print(point)
print(fields(point))
print('IS a Dataclass?: ', is_dataclass(point))

# Can be represented by BaseModel
class newPoint(BaseModel):
    x: int = Field(default=0, min=0, max=10)
    y: int = Field(default=0, min=0, max=10)

    def get_coordinate(self):
        return (self.x, self.y)

point = newPoint(x=10, y=10)
print(point)
print(fields(point))
print('IS a Dataclass?: ', is_dataclass(point))
print(point.get_coordinate())
```
## Supported types

DataModel support recursive transformation of fields, so you can easily work with nested dataclasses or complex types.

DataModel supports automatic conversion of:

- [datetime](https://docs.python.org/3/library/datetime.html#available-types)
objects. `datetime` objects are encoded to str exactly like orjson conversion, any str typed as datetime is decoded to datetime.
The same behavior is used to decoding time, date and timedelta objects.

- [UUID](https://docs.python.org/3/library/uuid.html#uuid.UUID) objects. They
are encoded as `str` (JSON string) and decoded back to uuid.UUID objects.

- [Decimal](https://docs.python.org/3/library/decimal.html) objects. They are
also encoded as `float` and decoded back to Decimal.

Also, "custom" encoders are supported.

```python

import uuid
from typing import (
    List,
    Optional,
    Union
)
from dataclasses import dataclass, field
from datamodel import BaseModel, Field

@dataclass
class Point:
    x: int = Field(default=0, min=0, max=10)
    y: int = Field(default=0, min=0, max=10)

class coordinate(BaseModel, intSum):
    latitude: float
    longitude: float

    def get_location(self) -> tuple:
        return (self.latitude, self.longitude)

def auto_uid():
    return uuid.uuid4()

def default_rect():
    return [0,0,0,0]

def valid_zipcode(field, value):
    return value > 1000

class Address(BaseModel):
    id: uuid.UUID = field(default_factory=auto_uid)
    street: str = Field(required=True)
    zipcode: int = Field(required=False, default=1010, validator=valid_zipcode)
    location: Optional[coordinate]
    box: List[Optional[Point]]
    rect: List[int] = Field(factory=default_rect)


addr = Address(street="Calle Mayor", location=(18.1, 22.1), zipcode=3021, box=[(2, 10), (4, 8)], rect=[1, 2, 3, 4])
print('IS a Dataclass?: ', is_dataclass(addr))

print(addr.location.get_location())
```
```console
# returns
Address(id=UUID('24b34dd5-8d35-4cfd-8916-7876b28cdae3'), street='Calle Mayor', zipcode=3021, location=coordinate(latitude=18.1, longitude=22.1), box=[Point(x=2, y=10), Point(x=4, y=8)], rect=[1, 2, 3, 4])
```

* Fast and convenience conversion from-to JSON (using orjson):

```python
import orjson

b = addr.json()
print(b)
```
```console
{"id":"24b34dd5-8d35-4cfd-8916-7876b28cdae3","street":"Calle Mayor","zipcode":3021,"location":{"latitude":18.1,"longitude":22.1}, "box":[{"x":2,"y":10},{"x":4,"y":8}],"rect":[1,2,3,4]}
```

```python
# and re-imported from json
new_addr = Address.from_json(b) # load directly from json string
# or using a dictionary decoded by orjson
data = orjson.loads(b)
new_addr = Address(**data)

```

## Inheritance

python-datamodel supports inheritance of classes.

```python
import uuid
from typing import Union, List
from dataclasses import dataclass, field
from datamodel import BaseModel, Column, Field


def auto_uid():
    return uuid.uuid4()

class User(BaseModel):
    id: uuid.UUID = field(default_factory=auto_uid)
    name: str
    first_name: str
    last_name: str


@dataclass
class Address:
    street: str
    city: str
    state: str
    zipcode: str
    country: Optional[str] = 'US'

    def __str__(self) -> str:
        """Provides pretty response of address"""
        lines = [self.street]
        lines.append(f"{self.city}, {self.zipcode} {self.state}")
        lines.append(f"{self.country}")
        return "\n".join(lines)

class Employee(User):
    """
    Base Employee.
    """
    role: str
    address: Address # composition of a dataclass inside of DataModel is possible.

# Supporting multiple inheritance and composition
# Wage Policies
class MonthlySalary(BaseModel):
    salary: Union[float, int]

    def calculate_payroll(self) -> Union[float, int]:
        return self.salary

class HourlySalary(BaseModel):
    salary: Union[float, int] = Field(default=0)
    hours_worked: Union[float, int] = Field(default=0)

    def calculate_payroll(self) -> Union[float, int]:
        return (self.hours_worked * self.salary)

# employee types
class Secretary(Employee, MonthlySalary):
    """Secretary.

    Person with montly salary policy and no commissions.
    """
    role: str = 'Secretary'

class FactoryWorker(Employee, HourlySalary):
    """
    FactoryWorker is an employee with hourly salary policy and no commissions.
    """
    role: str = 'Factory Worker'

class PayrollSystem:
    def calculate_payroll(self, employees: List[dataclass]) -> None:
        print('=== Calculating Payroll === ')
        for employee in employees:
            print(f"Payroll for employee {employee.id} - {employee.name}")
            print(f"- {employee.role} Amount: {employee.calculate_payroll()}")
            if employee.address:
                print('- Sent to:')
                print(employee.address)
            print("")

jane = Secretary(name='Jane Doe', first_name='Jane', last_name='Doe', salary=1500)
bob = FactoryWorker(name='Bob Doyle', first_name='Bob', last_name='Doyle', salary=15, hours_worked=40)
mitch = FactoryWorker(name='Mitch Brian', first_name='Mitch', last_name='Brian', salary=20, hours_worked=35)

payroll = PayrollSystem()
payroll.calculate_payroll([jane, bob, mitch])
```
A sample of output:
```
```console
=== Calculating Payroll ===
Payroll for employee 745a2623-d4d2-4da6-bf0a-1fa691bafd33 - Jane Doe
- Secretary Amount: 1500
- Sent to:
Rodeo Drive, Rd
Los Angeles, 31050 CA
US
```
## Contributing

First of all, thank you for being interested in contributing to this library.
I really appreciate you taking the time to work on this project.

- If you're just interested in getting into the code, a good place to start are
issues tagged as bugs.
- If introducing a new feature, especially one that modifies the public API,
consider submitting an issue for discussion before a PR. Please also take a look
at existing issues / PRs to see what you're proposing has  already been covered
before / exists.
- I like to follow the commit conventions documented [here](https://www.conventionalcommits.org/en/v1.0.0/#summary)

## License

This project is licensed under the terms of the BSD v3. license.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/phenobarbital/python-datamodel",
    "name": "python-datamodel",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9.13",
    "maintainer_email": null,
    "keywords": "asyncio, dataclass, dataclasses, data models",
    "author": "Jesus Lara",
    "author_email": "jesuslarag@gmail.com",
    "download_url": null,
    "platform": "any",
    "description": "# DataModel\nDataModel is a simple library based on python +3.8 to use Dataclass-syntax for interacting with\nData, using the same syntax of Dataclass, users can write Python Objects\nand work with Data in the same way (like ORM's), is a reimplementation of python Dataclasses supporting true inheritance (without decorators), true composition and other good features.\n\nThe key features are:\n* **Easy to use**: No more using decorators, concerns abour re-ordering attributes or common problems with using dataclasses with inheritance.\n* **Extensibility**: Can use other dataclasses, Data objects or primitives as data-types.\n* **Fast**: DataModel is a replacement 100% full compatible with dataclasses, without any overhead.\n\n\n\n## Requirements\n\nPython 3.8+\n\n## Installation\n\n<div class=\"termy\">\n\n```console\n$ pip install python-datamodel\n---> 100%\nSuccessfully installed datamodel\n```\n\n\n</div>\n\n## Quickstart\n\n\n```python\n\nfrom datamodel import Field, BaseModel\nfrom dataclasses import dataclass, fields, is_dataclass\n\n\n# This pure Dataclass:\n@dataclass\nclass Point:\n    x: int = Field(default=0, min=0, max=10)\n    y: int = Field(default=0, min=0, max=10)\n\npoint = Point(x=10, y=10)\nprint(point)\nprint(fields(point))\nprint('IS a Dataclass?: ', is_dataclass(point))\n\n# Can be represented by BaseModel\nclass newPoint(BaseModel):\n    x: int = Field(default=0, min=0, max=10)\n    y: int = Field(default=0, min=0, max=10)\n\n    def get_coordinate(self):\n        return (self.x, self.y)\n\npoint = newPoint(x=10, y=10)\nprint(point)\nprint(fields(point))\nprint('IS a Dataclass?: ', is_dataclass(point))\nprint(point.get_coordinate())\n```\n## Supported types\n\nDataModel support recursive transformation of fields, so you can easily work with nested dataclasses or complex types.\n\nDataModel supports automatic conversion of:\n\n- [datetime](https://docs.python.org/3/library/datetime.html#available-types)\nobjects. `datetime` objects are encoded to str exactly like orjson conversion, any str typed as datetime is decoded to datetime.\nThe same behavior is used to decoding time, date and timedelta objects.\n\n- [UUID](https://docs.python.org/3/library/uuid.html#uuid.UUID) objects. They\nare encoded as `str` (JSON string) and decoded back to uuid.UUID objects.\n\n- [Decimal](https://docs.python.org/3/library/decimal.html) objects. They are\nalso encoded as `float` and decoded back to Decimal.\n\nAlso, \"custom\" encoders are supported.\n\n```python\n\nimport uuid\nfrom typing import (\n    List,\n    Optional,\n    Union\n)\nfrom dataclasses import dataclass, field\nfrom datamodel import BaseModel, Field\n\n@dataclass\nclass Point:\n    x: int = Field(default=0, min=0, max=10)\n    y: int = Field(default=0, min=0, max=10)\n\nclass coordinate(BaseModel, intSum):\n    latitude: float\n    longitude: float\n\n    def get_location(self) -> tuple:\n        return (self.latitude, self.longitude)\n\ndef auto_uid():\n    return uuid.uuid4()\n\ndef default_rect():\n    return [0,0,0,0]\n\ndef valid_zipcode(field, value):\n    return value > 1000\n\nclass Address(BaseModel):\n    id: uuid.UUID = field(default_factory=auto_uid)\n    street: str = Field(required=True)\n    zipcode: int = Field(required=False, default=1010, validator=valid_zipcode)\n    location: Optional[coordinate]\n    box: List[Optional[Point]]\n    rect: List[int] = Field(factory=default_rect)\n\n\naddr = Address(street=\"Calle Mayor\", location=(18.1, 22.1), zipcode=3021, box=[(2, 10), (4, 8)], rect=[1, 2, 3, 4])\nprint('IS a Dataclass?: ', is_dataclass(addr))\n\nprint(addr.location.get_location())\n```\n```console\n# returns\nAddress(id=UUID('24b34dd5-8d35-4cfd-8916-7876b28cdae3'), street='Calle Mayor', zipcode=3021, location=coordinate(latitude=18.1, longitude=22.1), box=[Point(x=2, y=10), Point(x=4, y=8)], rect=[1, 2, 3, 4])\n```\n\n* Fast and convenience conversion from-to JSON (using orjson):\n\n```python\nimport orjson\n\nb = addr.json()\nprint(b)\n```\n```console\n{\"id\":\"24b34dd5-8d35-4cfd-8916-7876b28cdae3\",\"street\":\"Calle Mayor\",\"zipcode\":3021,\"location\":{\"latitude\":18.1,\"longitude\":22.1}, \"box\":[{\"x\":2,\"y\":10},{\"x\":4,\"y\":8}],\"rect\":[1,2,3,4]}\n```\n\n```python\n# and re-imported from json\nnew_addr = Address.from_json(b) # load directly from json string\n# or using a dictionary decoded by orjson\ndata = orjson.loads(b)\nnew_addr = Address(**data)\n\n```\n\n## Inheritance\n\npython-datamodel supports inheritance of classes.\n\n```python\nimport uuid\nfrom typing import Union, List\nfrom dataclasses import dataclass, field\nfrom datamodel import BaseModel, Column, Field\n\n\ndef auto_uid():\n    return uuid.uuid4()\n\nclass User(BaseModel):\n    id: uuid.UUID = field(default_factory=auto_uid)\n    name: str\n    first_name: str\n    last_name: str\n\n\n@dataclass\nclass Address:\n    street: str\n    city: str\n    state: str\n    zipcode: str\n    country: Optional[str] = 'US'\n\n    def __str__(self) -> str:\n        \"\"\"Provides pretty response of address\"\"\"\n        lines = [self.street]\n        lines.append(f\"{self.city}, {self.zipcode} {self.state}\")\n        lines.append(f\"{self.country}\")\n        return \"\\n\".join(lines)\n\nclass Employee(User):\n    \"\"\"\n    Base Employee.\n    \"\"\"\n    role: str\n    address: Address # composition of a dataclass inside of DataModel is possible.\n\n# Supporting multiple inheritance and composition\n# Wage Policies\nclass MonthlySalary(BaseModel):\n    salary: Union[float, int]\n\n    def calculate_payroll(self) -> Union[float, int]:\n        return self.salary\n\nclass HourlySalary(BaseModel):\n    salary: Union[float, int] = Field(default=0)\n    hours_worked: Union[float, int] = Field(default=0)\n\n    def calculate_payroll(self) -> Union[float, int]:\n        return (self.hours_worked * self.salary)\n\n# employee types\nclass Secretary(Employee, MonthlySalary):\n    \"\"\"Secretary.\n\n    Person with montly salary policy and no commissions.\n    \"\"\"\n    role: str = 'Secretary'\n\nclass FactoryWorker(Employee, HourlySalary):\n    \"\"\"\n    FactoryWorker is an employee with hourly salary policy and no commissions.\n    \"\"\"\n    role: str = 'Factory Worker'\n\nclass PayrollSystem:\n    def calculate_payroll(self, employees: List[dataclass]) -> None:\n        print('=== Calculating Payroll === ')\n        for employee in employees:\n            print(f\"Payroll for employee {employee.id} - {employee.name}\")\n            print(f\"- {employee.role} Amount: {employee.calculate_payroll()}\")\n            if employee.address:\n                print('- Sent to:')\n                print(employee.address)\n            print(\"\")\n\njane = Secretary(name='Jane Doe', first_name='Jane', last_name='Doe', salary=1500)\nbob = FactoryWorker(name='Bob Doyle', first_name='Bob', last_name='Doyle', salary=15, hours_worked=40)\nmitch = FactoryWorker(name='Mitch Brian', first_name='Mitch', last_name='Brian', salary=20, hours_worked=35)\n\npayroll = PayrollSystem()\npayroll.calculate_payroll([jane, bob, mitch])\n```\nA sample of output:\n```\n```console\n=== Calculating Payroll ===\nPayroll for employee 745a2623-d4d2-4da6-bf0a-1fa691bafd33 - Jane Doe\n- Secretary Amount: 1500\n- Sent to:\nRodeo Drive, Rd\nLos Angeles, 31050 CA\nUS\n```\n## Contributing\n\nFirst of all, thank you for being interested in contributing to this library.\nI really appreciate you taking the time to work on this project.\n\n- If you're just interested in getting into the code, a good place to start are\nissues tagged as bugs.\n- If introducing a new feature, especially one that modifies the public API,\nconsider submitting an issue for discussion before a PR. Please also take a look\nat existing issues / PRs to see what you're proposing has  already been covered\nbefore / exists.\n- I like to follow the commit conventions documented [here](https://www.conventionalcommits.org/en/v1.0.0/#summary)\n\n## License\n\nThis project is licensed under the terms of the BSD v3. license.\n",
    "bugtrack_url": null,
    "license": "BSD",
    "summary": "simple library based on python +3.8 to use Dataclass-syntaxfor interacting with Data",
    "version": "0.9.1",
    "project_urls": {
        "Funding": "https://paypal.me/phenobarbital",
        "Homepage": "https://github.com/phenobarbital/python-datamodel",
        "Say Thanks!": "https://saythanks.io/to/phenobarbital",
        "Source": "https://github.com/phenobarbital/datamodel"
    },
    "split_keywords": [
        "asyncio",
        " dataclass",
        " dataclasses",
        " data models"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "01895fb68aff3de68f149b64b676be745d654ef84ee4134a2dbe5ba3e5e876d3",
                "md5": "06e4073cbfd07d4c8b5c37518aae0cdb",
                "sha256": "8e8961827c6c2be3c02dd4d47b7feff16e04a02c3085ca19634c023bbf9615fd"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "06e4073cbfd07d4c8b5c37518aae0cdb",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9.13",
            "size": 3375902,
            "upload_time": "2025-01-21T04:07:11",
            "upload_time_iso_8601": "2025-01-21T04:07:11.364265Z",
            "url": "https://files.pythonhosted.org/packages/01/89/5fb68aff3de68f149b64b676be745d654ef84ee4134a2dbe5ba3e5e876d3/python_datamodel-0.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5afa662ce6e153c0b0a071755184438cd5532254cdfcb6402586f40abd9fa5a4",
                "md5": "8137e5240ffb749af984c82b8a11d2e6",
                "sha256": "47082f86151cf5d50ce4f28fe8d5d356489e180ca10b2fdba851d257dd8fc65b"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "8137e5240ffb749af984c82b8a11d2e6",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9.13",
            "size": 1350738,
            "upload_time": "2025-01-21T04:07:22",
            "upload_time_iso_8601": "2025-01-21T04:07:22.016779Z",
            "url": "https://files.pythonhosted.org/packages/5a/fa/662ce6e153c0b0a071755184438cd5532254cdfcb6402586f40abd9fa5a4/python_datamodel-0.9.1-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "58688318911e7b150923c7bf53e08d275afca78737aea2d3ff5090d76223f3cc",
                "md5": "db26917079d880363d9d2ea78e062ff4",
                "sha256": "52f8aaeef8a0642f3430a607bdb3be55d2170995510d37326ea7c2ab900cf9bf"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "db26917079d880363d9d2ea78e062ff4",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9.13",
            "size": 3564609,
            "upload_time": "2025-01-21T04:07:14",
            "upload_time_iso_8601": "2025-01-21T04:07:14.227524Z",
            "url": "https://files.pythonhosted.org/packages/58/68/8318911e7b150923c7bf53e08d275afca78737aea2d3ff5090d76223f3cc/python_datamodel-0.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bd1cb2d691ed391172acea37ff6fa7f77ccf7808f1a109937736b4f218613d78",
                "md5": "d6f242194c078dddf2c18ea491308af3",
                "sha256": "9394a2f5bbbeeb8ea6960f3979dbb6edf1503404deb316cffff74ecdba636d9b"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "d6f242194c078dddf2c18ea491308af3",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9.13",
            "size": 1354507,
            "upload_time": "2025-01-21T04:07:23",
            "upload_time_iso_8601": "2025-01-21T04:07:23.520910Z",
            "url": "https://files.pythonhosted.org/packages/bd/1c/b2d691ed391172acea37ff6fa7f77ccf7808f1a109937736b4f218613d78/python_datamodel-0.9.1-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "50b2f8a26b746643a28836594bf3c8c2f4c7aaebbcb793638e08f283c495e112",
                "md5": "0257a140d8293520e1a9f89ed180e958",
                "sha256": "8ed6aafab1810dc91fb033938e867f6db4b09c29cb3934e45588ffee888bf5bd"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "0257a140d8293520e1a9f89ed180e958",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9.13",
            "size": 3824742,
            "upload_time": "2025-01-21T04:07:16",
            "upload_time_iso_8601": "2025-01-21T04:07:16.529044Z",
            "url": "https://files.pythonhosted.org/packages/50/b2/f8a26b746643a28836594bf3c8c2f4c7aaebbcb793638e08f283c495e112/python_datamodel-0.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ce43f955b7a032d70b1fffb7dbf8dac3ea07826d1305377e6ff7a8208e0df251",
                "md5": "6948e1cd55a1e80ea6dd4be2d006c8a5",
                "sha256": "456c16a24c6022b905beedef6411e54e7609933b365d7517d32831b4dcf04d69"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "6948e1cd55a1e80ea6dd4be2d006c8a5",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9.13",
            "size": 1345895,
            "upload_time": "2025-01-21T04:07:26",
            "upload_time_iso_8601": "2025-01-21T04:07:26.425811Z",
            "url": "https://files.pythonhosted.org/packages/ce/43/f955b7a032d70b1fffb7dbf8dac3ea07826d1305377e6ff7a8208e0df251/python_datamodel-0.9.1-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ed00dc5edc72677daa06651a853e92757874c97be480b7c0ff073ca018978219",
                "md5": "2aa4ef771ce634ee8c9ed8f589a023fa",
                "sha256": "897ac8cc05b57f77d6abd29420581352d89d0ccf73b83e17e816fd70e76c202e"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "2aa4ef771ce634ee8c9ed8f589a023fa",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9.13",
            "size": 3730589,
            "upload_time": "2025-01-21T04:07:18",
            "upload_time_iso_8601": "2025-01-21T04:07:18.226640Z",
            "url": "https://files.pythonhosted.org/packages/ed/00/dc5edc72677daa06651a853e92757874c97be480b7c0ff073ca018978219/python_datamodel-0.9.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b0ebf71e386a035ee0544b76934e09c4ddf04f0763219c6153156a264e5e5c66",
                "md5": "a6f9e503c6dfa7b2749bbfede5a13e4c",
                "sha256": "6e57d1ee0ebbee590c8bd0dd925a541360b07c6532969e6b6e8e00ce3d54bb61"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp313-cp313-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "a6f9e503c6dfa7b2749bbfede5a13e4c",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9.13",
            "size": 1340462,
            "upload_time": "2025-01-21T04:07:28",
            "upload_time_iso_8601": "2025-01-21T04:07:28.496875Z",
            "url": "https://files.pythonhosted.org/packages/b0/eb/f71e386a035ee0544b76934e09c4ddf04f0763219c6153156a264e5e5c66/python_datamodel-0.9.1-cp313-cp313-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "efa6eca77141c213460212d351aba109cc2e0717cffe935c8c35be6bf5f9e95b",
                "md5": "c1bf072fcc29e00def689967e7ebba71",
                "sha256": "0520b8f38e5b983c9864da55754ca321649d1cf48722726b77a78ec5722f678d"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "c1bf072fcc29e00def689967e7ebba71",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9.13",
            "size": 3386880,
            "upload_time": "2025-01-21T04:07:19",
            "upload_time_iso_8601": "2025-01-21T04:07:19.965592Z",
            "url": "https://files.pythonhosted.org/packages/ef/a6/eca77141c213460212d351aba109cc2e0717cffe935c8c35be6bf5f9e95b/python_datamodel-0.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c541af525299f787708906ac871e49fbedc66c266e41a2c9d5bf275895e35f51",
                "md5": "4269c6fad5a2e4ebf33d9c2a27d274a4",
                "sha256": "c7b57fcdefde4179d0dd8f8166132ec2cc58eb3dc949ce69c87daa032f7b4689"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "4269c6fad5a2e4ebf33d9c2a27d274a4",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9.13",
            "size": 1353179,
            "upload_time": "2025-01-21T04:07:30",
            "upload_time_iso_8601": "2025-01-21T04:07:30.138389Z",
            "url": "https://files.pythonhosted.org/packages/c5/41/af525299f787708906ac871e49fbedc66c266e41a2c9d5bf275895e35f51/python_datamodel-0.9.1-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4953d010e815b6ff20f17eff11445ff3bd6ad359332fb272b5bb222e3a30a31a",
                "md5": "256398b8179fd2ff81d85bfc7e2be099",
                "sha256": "72d1c4c9d42df08797d6dc5570380287e8ca2a95fa842375983d6e39ddb1373b"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-pp310-pypy310_pp73-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "256398b8179fd2ff81d85bfc7e2be099",
            "packagetype": "bdist_wheel",
            "python_version": "pp310",
            "requires_python": ">=3.9.13",
            "size": 1279891,
            "upload_time": "2025-01-21T04:07:34",
            "upload_time_iso_8601": "2025-01-21T04:07:34.525860Z",
            "url": "https://files.pythonhosted.org/packages/49/53/d010e815b6ff20f17eff11445ff3bd6ad359332fb272b5bb222e3a30a31a/python_datamodel-0.9.1-pp310-pypy310_pp73-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d422a7b175a4668fa58fb2c0625293b35fb7c864c6b7007e44d674f930eeebd7",
                "md5": "7daee8c682e66161815a742a2c3c757c",
                "sha256": "dbb1c80819c68715c60cdb3445434fa4407ab6adddde6bd1de4ab349501b5e61"
            },
            "downloads": -1,
            "filename": "python_datamodel-0.9.1-pp39-pypy39_pp73-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "7daee8c682e66161815a742a2c3c757c",
            "packagetype": "bdist_wheel",
            "python_version": "pp39",
            "requires_python": ">=3.9.13",
            "size": 1279405,
            "upload_time": "2025-01-21T04:07:36",
            "upload_time_iso_8601": "2025-01-21T04:07:36.565477Z",
            "url": "https://files.pythonhosted.org/packages/d4/22/a7b175a4668fa58fb2c0625293b35fb7c864c6b7007e44d674f930eeebd7/python_datamodel-0.9.1-pp39-pypy39_pp73-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-21 04:07:11",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "phenobarbital",
    "github_project": "python-datamodel",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "python-datamodel"
}
        
Elapsed time: 0.48249s