python-datamodel 0.8.13__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
datamodel/version.py ADDED
@@ -0,0 +1,13 @@
1
+ """DataModel Meta information."""
2
+
3
+
4
+ __title__ = 'python-datamodel'
5
+ __description__ = (
6
+ 'simple library based on python +3.8 to use Dataclass-syntax'
7
+ 'for interacting with Data'
8
+ )
9
+ __version__ = '0.8.13'
10
+ __copyright__ = 'Copyright (c) 2020-2024 Jesus Lara'
11
+ __author__ = 'Jesus Lara'
12
+ __author_email__ = 'jesuslarag@gmail.com'
13
+ __license__ = 'BSD'
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2022, phenobarbital
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,316 @@
1
+ Metadata-Version: 2.1
2
+ Name: python-datamodel
3
+ Version: 0.8.13
4
+ Summary: simple library based on python +3.8 to use Dataclass-syntaxfor interacting with Data
5
+ Home-page: https://github.com/phenobarbital/python-datamodel
6
+ Author: Jesus Lara
7
+ Author-email: jesuslarag@gmail.com
8
+ License: BSD
9
+ Project-URL: Source, https://github.com/phenobarbital/datamodel
10
+ Project-URL: Funding, https://paypal.me/phenobarbital
11
+ Project-URL: Say Thanks!, https://saythanks.io/to/phenobarbital
12
+ Keywords: asyncio,dataclass,dataclasses,data models
13
+ Platform: any
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: System Administrators
17
+ Classifier: Topic :: Software Development :: Build Tools
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3 :: Only
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Framework :: AsyncIO
26
+ Classifier: License :: OSI Approved :: BSD License
27
+ Classifier: Operating System :: OS Independent
28
+ Classifier: Topic :: System :: Systems Administration
29
+ Classifier: Topic :: Utilities
30
+ Classifier: Environment :: Web Environment
31
+ Requires-Python: >=3.9.13
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Requires-Dist: numpy>=1.26.4
35
+ Requires-Dist: uvloop>=0.21.0
36
+ Requires-Dist: asyncio==3.4.3
37
+ Requires-Dist: faust-cchardet==2.1.19
38
+ Requires-Dist: ciso8601==2.3.2
39
+ Requires-Dist: objectpath==0.6.1
40
+ Requires-Dist: orjson==3.10.11
41
+ Requires-Dist: typing-extensions>=4.9.0
42
+ Requires-Dist: asyncpg>=0.29.0
43
+ Requires-Dist: python-dateutil>=2.8.2
44
+ Requires-Dist: python-slugify==8.0.1
45
+ Requires-Dist: pendulum==3.0.0
46
+
47
+ # DataModel
48
+ DataModel is a simple library based on python +3.8 to use Dataclass-syntax for interacting with
49
+ Data, using the same syntax of Dataclass, users can write Python Objects
50
+ 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.
51
+
52
+ The key features are:
53
+ * **Easy to use**: No more using decorators, concerns abour re-ordering attributes or common problems with using dataclasses with inheritance.
54
+ * **Extensibility**: Can use other dataclasses, Data objects or primitives as data-types.
55
+ * **Fast**: DataModel is a replacement 100% full compatible with dataclasses, without any overhead.
56
+
57
+
58
+
59
+ ## Requirements
60
+
61
+ Python 3.8+
62
+
63
+ ## Installation
64
+
65
+ <div class="termy">
66
+
67
+ ```console
68
+ $ pip install python-datamodel
69
+ ---> 100%
70
+ Successfully installed datamodel
71
+ ```
72
+
73
+
74
+ </div>
75
+
76
+ ## Quickstart
77
+
78
+
79
+ ```python
80
+
81
+ from datamodel import Field, BaseModel
82
+ from dataclasses import dataclass, fields, is_dataclass
83
+
84
+
85
+ # This pure Dataclass:
86
+ @dataclass
87
+ class Point:
88
+ x: int = Field(default=0, min=0, max=10)
89
+ y: int = Field(default=0, min=0, max=10)
90
+
91
+ point = Point(x=10, y=10)
92
+ print(point)
93
+ print(fields(point))
94
+ print('IS a Dataclass?: ', is_dataclass(point))
95
+
96
+ # Can be represented by BaseModel
97
+ class newPoint(BaseModel):
98
+ x: int = Field(default=0, min=0, max=10)
99
+ y: int = Field(default=0, min=0, max=10)
100
+
101
+ def get_coordinate(self):
102
+ return (self.x, self.y)
103
+
104
+ point = newPoint(x=10, y=10)
105
+ print(point)
106
+ print(fields(point))
107
+ print('IS a Dataclass?: ', is_dataclass(point))
108
+ print(point.get_coordinate())
109
+ ```
110
+ ## Supported types
111
+
112
+ DataModel support recursive transformation of fields, so you can easily work with nested dataclasses or complex types.
113
+
114
+ DataModel supports automatic conversion of:
115
+
116
+ - [datetime](https://docs.python.org/3/library/datetime.html#available-types)
117
+ objects. `datetime` objects are encoded to str exactly like orjson conversion, any str typed as datetime is decoded to datetime.
118
+ The same behavior is used to decoding time, date and timedelta objects.
119
+
120
+ - [UUID](https://docs.python.org/3/library/uuid.html#uuid.UUID) objects. They
121
+ are encoded as `str` (JSON string) and decoded back to uuid.UUID objects.
122
+
123
+ - [Decimal](https://docs.python.org/3/library/decimal.html) objects. They are
124
+ also encoded as `float` and decoded back to Decimal.
125
+
126
+ Also, "custom" encoders are supported.
127
+
128
+ ```python
129
+
130
+ import uuid
131
+ from typing import (
132
+ List,
133
+ Optional,
134
+ Union
135
+ )
136
+ from dataclasses import dataclass, field
137
+ from datamodel import BaseModel, Field
138
+
139
+ @dataclass
140
+ class Point:
141
+ x: int = Field(default=0, min=0, max=10)
142
+ y: int = Field(default=0, min=0, max=10)
143
+
144
+ class coordinate(BaseModel, intSum):
145
+ latitude: float
146
+ longitude: float
147
+
148
+ def get_location(self) -> tuple:
149
+ return (self.latitude, self.longitude)
150
+
151
+ def auto_uid():
152
+ return uuid.uuid4()
153
+
154
+ def default_rect():
155
+ return [0,0,0,0]
156
+
157
+ def valid_zipcode(field, value):
158
+ return value > 1000
159
+
160
+ class Address(BaseModel):
161
+ id: uuid.UUID = field(default_factory=auto_uid)
162
+ street: str = Field(required=True)
163
+ zipcode: int = Field(required=False, default=1010, validator=valid_zipcode)
164
+ location: Optional[coordinate]
165
+ box: List[Optional[Point]]
166
+ rect: List[int] = Field(factory=default_rect)
167
+
168
+
169
+ addr = Address(street="Calle Mayor", location=(18.1, 22.1), zipcode=3021, box=[(2, 10), (4, 8)], rect=[1, 2, 3, 4])
170
+ print('IS a Dataclass?: ', is_dataclass(addr))
171
+
172
+ print(addr.location.get_location())
173
+ ```
174
+ ```console
175
+ # returns
176
+ 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])
177
+ ```
178
+
179
+ * Fast and convenience conversion from-to JSON (using orjson):
180
+
181
+ ```python
182
+ import orjson
183
+
184
+ b = addr.json()
185
+ print(b)
186
+ ```
187
+ ```console
188
+ {"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]}
189
+ ```
190
+
191
+ ```python
192
+ # and re-imported from json
193
+ new_addr = Address.from_json(b) # load directly from json string
194
+ # or using a dictionary decoded by orjson
195
+ data = orjson.loads(b)
196
+ new_addr = Address(**data)
197
+
198
+ ```
199
+
200
+ ## Inheritance
201
+
202
+ python-datamodel supports inheritance of classes.
203
+
204
+ ```python
205
+ import uuid
206
+ from typing import Union, List
207
+ from dataclasses import dataclass, field
208
+ from datamodel import BaseModel, Column, Field
209
+
210
+
211
+ def auto_uid():
212
+ return uuid.uuid4()
213
+
214
+ class User(BaseModel):
215
+ id: uuid.UUID = field(default_factory=auto_uid)
216
+ name: str
217
+ first_name: str
218
+ last_name: str
219
+
220
+
221
+ @dataclass
222
+ class Address:
223
+ street: str
224
+ city: str
225
+ state: str
226
+ zipcode: str
227
+ country: Optional[str] = 'US'
228
+
229
+ def __str__(self) -> str:
230
+ """Provides pretty response of address"""
231
+ lines = [self.street]
232
+ lines.append(f"{self.city}, {self.zipcode} {self.state}")
233
+ lines.append(f"{self.country}")
234
+ return "\n".join(lines)
235
+
236
+ class Employee(User):
237
+ """
238
+ Base Employee.
239
+ """
240
+ role: str
241
+ address: Address # composition of a dataclass inside of DataModel is possible.
242
+
243
+ # Supporting multiple inheritance and composition
244
+ # Wage Policies
245
+ class MonthlySalary(BaseModel):
246
+ salary: Union[float, int]
247
+
248
+ def calculate_payroll(self) -> Union[float, int]:
249
+ return self.salary
250
+
251
+ class HourlySalary(BaseModel):
252
+ salary: Union[float, int] = Field(default=0)
253
+ hours_worked: Union[float, int] = Field(default=0)
254
+
255
+ def calculate_payroll(self) -> Union[float, int]:
256
+ return (self.hours_worked * self.salary)
257
+
258
+ # employee types
259
+ class Secretary(Employee, MonthlySalary):
260
+ """Secretary.
261
+
262
+ Person with montly salary policy and no commissions.
263
+ """
264
+ role: str = 'Secretary'
265
+
266
+ class FactoryWorker(Employee, HourlySalary):
267
+ """
268
+ FactoryWorker is an employee with hourly salary policy and no commissions.
269
+ """
270
+ role: str = 'Factory Worker'
271
+
272
+ class PayrollSystem:
273
+ def calculate_payroll(self, employees: List[dataclass]) -> None:
274
+ print('=== Calculating Payroll === ')
275
+ for employee in employees:
276
+ print(f"Payroll for employee {employee.id} - {employee.name}")
277
+ print(f"- {employee.role} Amount: {employee.calculate_payroll()}")
278
+ if employee.address:
279
+ print('- Sent to:')
280
+ print(employee.address)
281
+ print("")
282
+
283
+ jane = Secretary(name='Jane Doe', first_name='Jane', last_name='Doe', salary=1500)
284
+ bob = FactoryWorker(name='Bob Doyle', first_name='Bob', last_name='Doyle', salary=15, hours_worked=40)
285
+ mitch = FactoryWorker(name='Mitch Brian', first_name='Mitch', last_name='Brian', salary=20, hours_worked=35)
286
+
287
+ payroll = PayrollSystem()
288
+ payroll.calculate_payroll([jane, bob, mitch])
289
+ ```
290
+ A sample of output:
291
+ ```
292
+ ```console
293
+ === Calculating Payroll ===
294
+ Payroll for employee 745a2623-d4d2-4da6-bf0a-1fa691bafd33 - Jane Doe
295
+ - Secretary Amount: 1500
296
+ - Sent to:
297
+ Rodeo Drive, Rd
298
+ Los Angeles, 31050 CA
299
+ US
300
+ ```
301
+ ## Contributing
302
+
303
+ First of all, thank you for being interested in contributing to this library.
304
+ I really appreciate you taking the time to work on this project.
305
+
306
+ - If you're just interested in getting into the code, a good place to start are
307
+ issues tagged as bugs.
308
+ - If introducing a new feature, especially one that modifies the public API,
309
+ consider submitting an issue for discussion before a PR. Please also take a look
310
+ at existing issues / PRs to see what you're proposing has already been covered
311
+ before / exists.
312
+ - I like to follow the commit conventions documented [here](https://www.conventionalcommits.org/en/v1.0.0/#summary)
313
+
314
+ ## License
315
+
316
+ This project is licensed under the terms of the BSD v3. license.
@@ -0,0 +1,35 @@
1
+ datamodel/__init__.py,sha256=k6FaIeF_ElduM4jAO5DCv6ZAb0nHgD2mKHxIzljvIrI,412
2
+ datamodel/abstract.py,sha256=CeXseLbsmmSEeAR6eNALzzeRB4pq5T_iLkcSsLyyeTQ,12596
3
+ datamodel/base.py,sha256=mNAgW6HuvHdTX9Jo-VlNSKY17wLJMkyiCnzyE9vHLZ0,6696
4
+ datamodel/converters.c,sha256=1XWuvrv55Y0qJpzx3fuZr6icFYgQd5ddZfn5FaFNINU,1608809
5
+ datamodel/converters.cp313-win_amd64.pyd,sha256=Hl4VITCfOHu8uZTHmoxuXFnu9qNsldq-_Lk2hLOXG18,259584
6
+ datamodel/exceptions.c,sha256=LH7o7Urv7-r6-G6oIXcx9-8j_d4ZWL9Eewd3y0Pl-7g,551384
7
+ datamodel/exceptions.cp313-win_amd64.pyd,sha256=DfJw5Luo8p0q4LG9avVxO-WzVf9i609LzdKGKcZ-Stk,79872
8
+ datamodel/fields.cp313-win_amd64.pyd,sha256=_47Oxj0JSV34D55X3DRHK7w4qHuXZ0UkF3ukyb3vImY,118784
9
+ datamodel/fields.cpp,sha256=AKqrscB7nkbk_cmqevSnU6nEcRDVe53hA2wwaaDR6fU,690239
10
+ datamodel/functions.cp313-win_amd64.pyd,sha256=sKBY5yiSpNrk_mpmM3jMH3qzILuL9uYiS_yEwnUGvGk,50176
11
+ datamodel/functions.cpp,sha256=KRo6xsoN0mr_JBx7pigZqTg8eIHdYIz6GyLrWhXIcIk,344391
12
+ datamodel/models.py,sha256=fU6ya_vVuhrEMG2OFRU705XteVqOdjuPvfMkkCsjJus,26486
13
+ datamodel/profiler.py,sha256=Cb7BYFV9886dvCHWL5V_znat1iU9XKAaoQ43olszlL4,520
14
+ datamodel/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ datamodel/types.c,sha256=wsSeZv7gG_vOMkfSV-bOcD83_2I8ePH1efl1JIjaHG4,278676
16
+ datamodel/types.cp313-win_amd64.pyd,sha256=H7ZY90_Xcy4ksY3dE9CdOeYBMVUKqb_xrT_Fr6shkEE,41472
17
+ datamodel/validation.cp313-win_amd64.pyd,sha256=dCwnHxEDMTaS5UQHMdHrAuZHQIvGDrzY3IrFtl_jWcM,101376
18
+ datamodel/validation.cpp,sha256=WXnhmKIKP5M_UJEh3Iin8AWMXYI7h6EjKjL89VR6AQQ,616852
19
+ datamodel/version.py,sha256=T8S28M4FiNGg9AW58vAIS43OuaTpdKiJ-514G088MAE,364
20
+ datamodel/aliases/__init__.py,sha256=-LqJfuqgbFngQg-27tbomLtQYFCXXOwlBdWIU6qyR6o,736
21
+ datamodel/jsonld/__init__.py,sha256=mRo4_tJnrK8B36Omsd6XCee2s9Rjj4RACte83OhNjSg,1041
22
+ datamodel/jsonld/models.py,sha256=nR7b0zUL7Hlu1aPfH6Sa5b-54Hfw709tRjgLMlaBcvI,14911
23
+ datamodel/libs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ datamodel/libs/mapping.c,sha256=4j_Uil1WFSWIJjzh5IE90Lw2xfxX7TqBbLTDpxjuLuE,593941
25
+ datamodel/libs/mapping.cp313-win_amd64.pyd,sha256=BB86pPSz6d1qk2JtWcjP1ETQZJNOZHk5YLiyzKxUUps,93696
26
+ datamodel/libs/mutables.py,sha256=KnRrtc4u_o6PCW-KS4D_TgKB8Z8qodHaaEzU_D8Zd-o,4029
27
+ datamodel/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ datamodel/parsers/encoders.py,sha256=Ku02PGA9bI-yOOUrFDewhCF8wi1YICbuERpPOmLJ-1E,331
29
+ datamodel/parsers/json.cp313-win_amd64.pyd,sha256=HEBTp-DdYestuXAh3FJpIl7rrYRCYEvBa58l3B1VPAY,81920
30
+ datamodel/parsers/json.cpp,sha256=Q5lQfYGUS3vedQJekUL_4nyPA50o-lyt5JQ0zn8pOmg,518483
31
+ python_datamodel-0.8.13.dist-info/LICENSE,sha256=_EiwMP8q1rs_BSFvxlBQSFwP_edqbBhOu45VBhMRPG0,1550
32
+ python_datamodel-0.8.13.dist-info/METADATA,sha256=STH7blzo4r1a1yOzj2zKoq07aG63xUQXHBK9i0FaDNc,9897
33
+ python_datamodel-0.8.13.dist-info/WHEEL,sha256=JWMnXFGOMSosTxV20oUANVJN2xZmOIHG9fWtyY9SQ-E,101
34
+ python_datamodel-0.8.13.dist-info/top_level.txt,sha256=UsBQ6QEFuPGiQI1zqcnYox8lCSYAVgDpxxIlShl-gac,10
35
+ python_datamodel-0.8.13.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (74.0.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp313-cp313-win_amd64
5
+
@@ -0,0 +1 @@
1
+ datamodel