pyquoks 2.1.3__tar.gz → 2.2.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyquoks
3
- Version: 2.1.3
3
+ Version: 2.2.0
4
4
  Summary: Пакет PyPI для часто используемых модулей в проектах diquoks
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -10,6 +10,7 @@ Requires-Python: >=3.14
10
10
  Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.14
13
+ Requires-Dist: annotated-types (==0.7.0)
13
14
  Requires-Dist: blinker (==1.9.0)
14
15
  Requires-Dist: certifi (==2025.11.12)
15
16
  Requires-Dist: charset-normalizer (==3.4.4)
@@ -22,7 +23,11 @@ Requires-Dist: jinja2 (==3.1.6)
22
23
  Requires-Dist: markupsafe (==3.0.3)
23
24
  Requires-Dist: pillow (==12.0.0)
24
25
  Requires-Dist: psutil (==7.1.3)
26
+ Requires-Dist: pydantic (==2.12.5)
27
+ Requires-Dist: pydantic-core (==2.41.5)
25
28
  Requires-Dist: requests (==2.32.5)
29
+ Requires-Dist: typing-extensions (==4.15.0)
30
+ Requires-Dist: typing-inspection (==0.4.2)
26
31
  Requires-Dist: urllib3 (==2.6.1)
27
32
  Requires-Dist: waitress (==3.0.2)
28
33
  Requires-Dist: werkzeug (==3.1.4)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyquoks"
3
- version = "2.1.3"
3
+ version = "2.2.0"
4
4
  description = "Пакет PyPI для часто используемых модулей в проектах diquoks"
5
5
  authors = [
6
6
  { name = "Denis Titovets <den232titovets@yandex.ru>" }
@@ -9,6 +9,7 @@ license = { text = "MIT" }
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.14"
11
11
  dependencies = [
12
+ "annotated-types (==0.7.0)",
12
13
  "blinker (==1.9.0)",
13
14
  "certifi (==2025.11.12)",
14
15
  "charset-normalizer (==3.4.4)",
@@ -21,7 +22,11 @@ dependencies = [
21
22
  "markupsafe (==3.0.3)",
22
23
  "pillow (==12.0.0)",
23
24
  "psutil (==7.1.3)",
25
+ "pydantic (==2.12.5)",
26
+ "pydantic-core (==2.41.5)",
24
27
  "requests (==2.32.5)",
28
+ "typing-inspection (==0.4.2)",
29
+ "typing-extensions (==4.15.0)",
25
30
  "urllib3 (==2.6.1)",
26
31
  "waitress (==3.0.2)",
27
32
  "werkzeug (==3.1.4)"
@@ -0,0 +1,8 @@
1
+ __all__ = [
2
+ "data",
3
+ "utils",
4
+ "localhost",
5
+ "test",
6
+ ]
7
+
8
+ from . import data, utils, localhost, test
@@ -9,6 +9,7 @@ import sys
9
9
  import typing
10
10
 
11
11
  import PIL.Image
12
+ import pydantic
12
13
  import requests
13
14
 
14
15
  import pyquoks.utils
@@ -76,13 +77,13 @@ class AssetsProvider(pyquoks.utils._HasRequiredAttributes):
76
77
 
77
78
  self._PATH = self._parent._PATH + self._PATH
78
79
 
79
- for filename in self._ATTRIBUTES:
80
+ for attribute in self._ATTRIBUTES:
80
81
  try:
81
- setattr(self, filename, self._parent.file_image(
82
- path=self._PATH + self._FILENAME.format(filename),
82
+ setattr(self, attribute, self._parent.file_image(
83
+ path=self._PATH + self._FILENAME.format(attribute),
83
84
  ))
84
85
  except Exception:
85
- setattr(self, filename, None)
86
+ setattr(self, attribute, None)
86
87
 
87
88
  class Network(pyquoks.utils._HasRequiredAttributes):
88
89
  """
@@ -133,8 +134,8 @@ class AssetsProvider(pyquoks.utils._HasRequiredAttributes):
133
134
  def __init__(self) -> None:
134
135
  self._check_attributes()
135
136
 
136
- for attribute, object_class in self._OBJECTS.items():
137
- setattr(self, attribute, object_class(self))
137
+ for attribute, child_class in self._OBJECTS.items():
138
+ setattr(self, attribute, child_class(self))
138
139
 
139
140
  @staticmethod
140
141
  def file_image(path: str) -> PIL.Image.Image:
@@ -190,8 +191,8 @@ class StringsProvider(pyquoks.utils._HasRequiredAttributes):
190
191
  def __init__(self) -> None:
191
192
  self._check_attributes()
192
193
 
193
- for attribute, object_class in self._OBJECTS.items():
194
- setattr(self, attribute, object_class(self))
194
+ for attribute, child_class in self._OBJECTS.items():
195
+ setattr(self, attribute, child_class(self))
195
196
 
196
197
 
197
198
  # endregion
@@ -270,20 +271,20 @@ class ConfigManager(pyquoks.utils._HasRequiredAttributes):
270
271
 
271
272
  for attribute, object_type in self._VALUES.items():
272
273
  try:
273
- match object_type.__name__:
274
- case str.__name__:
275
- pass
276
- case int.__name__:
277
- setattr(self, attribute, int(getattr(self, attribute)))
278
- case float.__name__:
279
- setattr(self, attribute, float(getattr(self, attribute)))
280
- case bool.__name__:
274
+ match object_type():
275
+ case bool():
281
276
  if getattr(self, attribute) not in [str(True), str(False)]:
282
277
  setattr(self, attribute, None)
283
278
  raise self._incorrect_content_exception
284
279
  else:
285
280
  setattr(self, attribute, getattr(self, attribute) == str(True))
286
- case dict.__name__ | list.__name__:
281
+ case int():
282
+ setattr(self, attribute, int(getattr(self, attribute)))
283
+ case float():
284
+ setattr(self, attribute, float(getattr(self, attribute)))
285
+ case str():
286
+ pass
287
+ case dict() | list():
287
288
  setattr(self, attribute, json.loads(getattr(self, attribute)))
288
289
  case _:
289
290
  raise ValueError(f"{object_type.__name__} type is not supported!")
@@ -337,8 +338,8 @@ class ConfigManager(pyquoks.utils._HasRequiredAttributes):
337
338
  def __init__(self) -> None:
338
339
  self._check_attributes()
339
340
 
340
- for attribute, object_class in self._OBJECTS.items():
341
- setattr(self, attribute, object_class(self))
341
+ for attribute, child_class in self._OBJECTS.items():
342
+ setattr(self, attribute, child_class(self))
342
343
 
343
344
 
344
345
  class DataManager(pyquoks.utils._HasRequiredAttributes):
@@ -347,7 +348,7 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
347
348
 
348
349
  **Required attributes**::
349
350
 
350
- _OBJECTS = {"users": UsersContainer}
351
+ _OBJECTS = {"users": list[UserModel]}
351
352
 
352
353
  # Predefined:
353
354
 
@@ -356,7 +357,7 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
356
357
  _FILENAME = "{0}.json"
357
358
 
358
359
  Attributes:
359
- _OBJECTS: Dictionary with filenames and containers
360
+ _OBJECTS: Dictionary with filenames and types of models
360
361
  _PATH: Path to the directory with JSON-like files
361
362
  _FILENAME: Filename of JSON-like files
362
363
  """
@@ -367,7 +368,7 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
367
368
  "_FILENAME",
368
369
  }
369
370
 
370
- _OBJECTS: dict[str, type]
371
+ _OBJECTS: dict[str, type[pydantic.BaseModel] | list[type[pydantic.BaseModel]]]
371
372
 
372
373
  _PATH: str = pyquoks.utils.get_path("data/")
373
374
 
@@ -376,12 +377,17 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
376
377
  def __init__(self) -> None:
377
378
  self._check_attributes()
378
379
 
379
- for filename, object_class in self._OBJECTS.items():
380
+ for attribute, object_type in self._OBJECTS.items():
380
381
  try:
381
- with open(self._PATH + self._FILENAME.format(filename), "rb") as file:
382
- setattr(self, filename, object_class(json.loads(file.read())))
382
+ with open(self._PATH + self._FILENAME.format(attribute), "rb") as file:
383
+ data = json.loads(file.read())
384
+
385
+ if typing.get_origin(object_type) == list:
386
+ setattr(self, attribute, [typing.get_args(object_type)[0](**model) for model in data])
387
+ else:
388
+ setattr(self, attribute, object_type(**data))
383
389
  except Exception:
384
- setattr(self, filename, None)
390
+ setattr(self, attribute, None)
385
391
 
386
392
  def update(self, **kwargs) -> None:
387
393
  """
@@ -395,13 +401,19 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
395
401
  object_class = self._OBJECTS.get(attribute)
396
402
 
397
403
  try:
398
- object_class(value)
404
+ if typing.get_origin(object_class) == list:
405
+ [typing.get_args(object_class)[0](**model) for model in value]
406
+ else:
407
+ object_class(**value)
399
408
  except Exception:
400
409
  raise AttributeError(
401
410
  f"{attribute} cannot be converted to {object_class.__name__}!",
402
411
  )
403
412
  else:
404
- setattr(self, attribute, object_class(value))
413
+ if typing.get_origin(object_class) == list:
414
+ setattr(self, attribute, [typing.get_args(object_class)[0](**model) for model in value])
415
+ else:
416
+ setattr(self, attribute, object_class(**value))
405
417
 
406
418
  os.makedirs(
407
419
  name=self._PATH,
@@ -510,16 +522,16 @@ class DatabaseManager(pyquoks.utils._HasRequiredAttributes):
510
522
  exist_ok=True,
511
523
  )
512
524
 
513
- for attribute, object_class in self._OBJECTS.items():
514
- setattr(self, attribute, object_class(self))
525
+ for attribute, child_class in self._OBJECTS.items():
526
+ setattr(self, attribute, child_class(self))
515
527
 
516
528
  def close_all(self) -> None:
517
529
  """
518
530
  Closes all database connections
519
531
  """
520
532
 
521
- for database in self._OBJECTS.keys():
522
- getattr(self, database).close()
533
+ for attribute in self._OBJECTS.keys():
534
+ getattr(self, attribute).close()
523
535
 
524
536
 
525
537
  # endregion
@@ -1,9 +0,0 @@
1
- __all__ = [
2
- "models",
3
- "data",
4
- "utils",
5
- "localhost",
6
- "test",
7
- ]
8
-
9
- from . import models, data, utils, localhost, test
@@ -1,164 +0,0 @@
1
- import typing
2
-
3
- import pyquoks.utils
4
-
5
-
6
- class _HasInitialData:
7
- """
8
- Assistive class for providing initial data
9
-
10
- Attributes:
11
- _data: Initial data that was passed into object
12
- """
13
-
14
- _data: typing.Any
15
-
16
- def __init__(self, data: typing.Any) -> None:
17
- self._data = data
18
-
19
-
20
- class Model(_HasInitialData):
21
- """
22
- Class for storing parameters and models
23
-
24
- **Optional attributes**::
25
-
26
- _ATTRIBUTES = {"beatmap_id", "score_id"}
27
-
28
- _OBJECTS = {"beatmap": BeatmapModel}
29
-
30
- Attributes:
31
- _ATTRIBUTES: Set of parameters that stored in this model
32
- _OBJECTS: Dictionary with attributes and their models
33
- _data: Initial data that was passed into object
34
- """
35
-
36
- _ATTRIBUTES: set[str] | None
37
-
38
- _OBJECTS: dict[str, type] | None
39
-
40
- _data: dict
41
-
42
- def __init__(self, data: dict) -> None:
43
- super().__init__(data)
44
-
45
- if hasattr(self, "_ATTRIBUTES"):
46
- if isinstance(self._ATTRIBUTES, set):
47
- for attribute in self._ATTRIBUTES:
48
- setattr(self, attribute, self._data.get(attribute, None))
49
- else:
50
- self._ATTRIBUTES = None
51
-
52
- if hasattr(self, "_OBJECTS"):
53
- if isinstance(self._OBJECTS, dict):
54
- for attribute, object_class in self._OBJECTS.items():
55
- try:
56
- setattr(self, attribute, object_class(self._data.get(attribute)))
57
- except Exception:
58
- setattr(self, attribute, None)
59
- else:
60
- self._OBJECTS = None
61
-
62
-
63
- class Container(Model, _HasInitialData):
64
- """
65
- Class for storing lists of models and another parameters
66
-
67
- **Optional attributes**::
68
-
69
- _ATTRIBUTES = {"beatmap_id", "score_id"}
70
-
71
- _OBJECTS = {"beatmap": BeatmapModel}
72
-
73
- _DATA = {"scores": ScoreModel}
74
-
75
- Attributes:
76
- _ATTRIBUTES: Set of parameters that stored in this container
77
- _OBJECTS: Dictionary with attributes and their models
78
- _DATA: Dictionary with attributes and models stored in their lists
79
- _data: Initial data that was passed into object
80
- """
81
-
82
- _ATTRIBUTES: set[str] | None
83
-
84
- _OBJECTS: dict[str, type] | None
85
-
86
- _DATA: dict[str, type] | None
87
-
88
- _data: dict
89
-
90
- def __init__(self, data: dict) -> None:
91
- super().__init__(data)
92
-
93
- if hasattr(self, "_DATA"):
94
- if isinstance(self._DATA, dict):
95
- for attribute, object_class in self._DATA.items():
96
- try:
97
- setattr(self, attribute, [object_class(data) for data in self._data.get(attribute)])
98
- except Exception:
99
- setattr(self, attribute, None)
100
- else:
101
- self._DATA = None
102
-
103
-
104
- class Listing(_HasInitialData):
105
- """
106
- Class for storing list of models
107
-
108
- **Optional attributes**::
109
-
110
- _DATA = {"scores": ScoreModel}
111
-
112
- Attributes:
113
- _DATA: Dictionary with attribute and model stored in list
114
- _data: Initial data that was passed into object
115
- """
116
-
117
- _DATA: dict[str, type] | None
118
-
119
- _data: list
120
-
121
- def __init__(self, data: list) -> None:
122
- super().__init__(data)
123
-
124
- if hasattr(self, "_DATA"):
125
- if isinstance(self._DATA, dict):
126
- for attribute, object_class in self._DATA.items():
127
- try:
128
- setattr(self, attribute, [object_class(data) for data in self._data])
129
- except Exception:
130
- setattr(self, attribute, None)
131
- else:
132
- self._DATA = None
133
-
134
-
135
- class Values(pyquoks.utils._HasRequiredAttributes):
136
- """
137
- Class for storing various parameters and values
138
-
139
- **Required attributes**::
140
-
141
- _ATTRIBUTES = {"settings", "path"}
142
-
143
- Attributes:
144
- _ATTRIBUTES: Attributes that can be stored in this class
145
- """
146
-
147
- _REQUIRED_ATTRIBUTES = {
148
- "_ATTRIBUTES",
149
- }
150
-
151
- _ATTRIBUTES: set[str]
152
-
153
- def __init__(self, **kwargs) -> None:
154
- self._check_attributes()
155
-
156
- for attribute in self._ATTRIBUTES:
157
- setattr(self, attribute, kwargs.get(attribute, getattr(self, attribute, None)))
158
-
159
- def update(self, **kwargs) -> None:
160
- """
161
- Updates provided attributes in object
162
- """
163
-
164
- self.__init__(**kwargs)
File without changes
File without changes
File without changes
File without changes