pyquoks 2.2.1__tar.gz → 2.3.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.2.1
3
+ Version: 2.3.0
4
4
  Summary: Пакет PyPI для часто используемых модулей в проектах diquoks
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -22,7 +22,7 @@ Requires-Dist: itsdangerous (==2.2.0)
22
22
  Requires-Dist: jinja2 (==3.1.6)
23
23
  Requires-Dist: markupsafe (==3.0.3)
24
24
  Requires-Dist: pillow (==12.0.0)
25
- Requires-Dist: psutil (==7.1.3)
25
+ Requires-Dist: psutil (==7.2.1)
26
26
  Requires-Dist: pydantic (==2.12.5)
27
27
  Requires-Dist: pydantic-core (==2.41.5)
28
28
  Requires-Dist: requests (==2.32.5)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyquoks"
3
- version = "2.2.1"
3
+ version = "2.3.0"
4
4
  description = "Пакет PyPI для часто используемых модулей в проектах diquoks"
5
5
  authors = [
6
6
  { name = "Denis Titovets <den232titovets@yandex.ru>" }
@@ -21,7 +21,7 @@ dependencies = [
21
21
  "jinja2 (==3.1.6)",
22
22
  "markupsafe (==3.0.3)",
23
23
  "pillow (==12.0.0)",
24
- "psutil (==7.1.3)",
24
+ "psutil (==7.2.1)",
25
25
  "pydantic (==2.12.5)",
26
26
  "pydantic-core (==2.41.5)",
27
27
  "requests (==2.32.5)",
@@ -23,14 +23,11 @@ class AssetsProvider(pyquoks.utils._HasRequiredAttributes):
23
23
 
24
24
  **Required attributes**::
25
25
 
26
- _OBJECTS = {"images": ImagesDirectory, "example": ExampleNetwork}
27
-
28
26
  # Predefined:
29
27
 
30
28
  _PATH = pyquoks.utils.get_path("assets/")
31
29
 
32
30
  Attributes:
33
- _OBJECTS: Dictionary with names of attributes and child objects
34
31
  _PATH: Path to the directory with assets folders
35
32
  """
36
33
 
@@ -123,19 +120,21 @@ class AssetsProvider(pyquoks.utils._HasRequiredAttributes):
123
120
  setattr(self, attribute, None)
124
121
 
125
122
  _REQUIRED_ATTRIBUTES = {
126
- "_OBJECTS",
127
123
  "_PATH",
128
124
  }
129
125
 
130
- _OBJECTS: dict[str, type]
131
-
132
126
  _PATH: str = pyquoks.utils.get_path("assets/")
133
127
 
134
128
  def __init__(self) -> None:
135
129
  self._check_attributes()
136
130
 
137
- for attribute, child_class in self._OBJECTS.items():
138
- setattr(self, attribute, child_class(self))
131
+ for attribute, child_class in self.__class__.__annotations__.items():
132
+ if issubclass(child_class, AssetsProvider.Directory | AssetsProvider.Network):
133
+ setattr(self, attribute, child_class(self))
134
+ else:
135
+ raise AttributeError(
136
+ f"{attribute} has incorrect type! (must be subclass of {AssetsProvider.Directory.__name__} or {AssetsProvider.Network.__name__})",
137
+ )
139
138
 
140
139
  @staticmethod
141
140
  def file_image(path: str) -> PIL.Image.Image:
@@ -161,16 +160,9 @@ class AssetsProvider(pyquoks.utils._HasRequiredAttributes):
161
160
  )
162
161
 
163
162
 
164
- class StringsProvider(pyquoks.utils._HasRequiredAttributes):
163
+ class StringsProvider:
165
164
  """
166
165
  Class for providing various strings data
167
-
168
- **Required attributes**::
169
-
170
- _OBJECTS = {"menu": MenuStrings}
171
-
172
- Attributes:
173
- _OBJECTS: Dictionary with names of attributes and child objects
174
166
  """
175
167
 
176
168
  class Strings:
@@ -182,17 +174,14 @@ class StringsProvider(pyquoks.utils._HasRequiredAttributes):
182
174
  def __init__(self, parent: StringsProvider) -> None:
183
175
  ... # TODO
184
176
 
185
- _REQUIRED_ATTRIBUTES = {
186
- "_OBJECTS",
187
- }
188
-
189
- _OBJECTS: dict[str, type]
190
-
191
177
  def __init__(self) -> None:
192
- self._check_attributes()
193
-
194
- for attribute, child_class in self._OBJECTS.items():
195
- setattr(self, attribute, child_class(self))
178
+ for attribute, child_class in self.__class__.__annotations__.items():
179
+ if issubclass(child_class, StringsProvider.Strings):
180
+ setattr(self, attribute, child_class(self))
181
+ else:
182
+ raise AttributeError(
183
+ f"{attribute} has incorrect type! (must be subclass of {StringsProvider.Strings.__name__})",
184
+ )
196
185
 
197
186
 
198
187
  # endregion
@@ -205,14 +194,11 @@ class ConfigManager(pyquoks.utils._HasRequiredAttributes):
205
194
 
206
195
  **Required attributes**::
207
196
 
208
- _OBJECTS = {"settings": SettingsConfig}
209
-
210
197
  # Predefined
211
198
 
212
199
  _PATH = pyquoks.utils.get_path("config.ini")
213
200
 
214
201
  Attributes:
215
- _OBJECTS: Dictionary with names of attributes and child objects
216
202
  _PATH: Path to the configuration file
217
203
  """
218
204
 
@@ -312,12 +298,16 @@ class ConfigManager(pyquoks.utils._HasRequiredAttributes):
312
298
  """
313
299
 
314
300
  for attribute, value in kwargs.items():
301
+
315
302
  if attribute not in self._VALUES.keys():
316
303
  raise AttributeError(f"{attribute} is not specified!")
317
304
 
318
305
  object_type = self._VALUES.get(attribute)
319
306
 
320
- if type(value) is not object_type:
307
+ if not isinstance(
308
+ value,
309
+ typing.get_origin(object_type) if typing.get_origin(object_type) else object_type,
310
+ ):
321
311
  raise AttributeError(
322
312
  f"{attribute} has incorrect type! (must be {object_type.__name__})",
323
313
  )
@@ -329,19 +319,21 @@ class ConfigManager(pyquoks.utils._HasRequiredAttributes):
329
319
  self._config.write(file)
330
320
 
331
321
  _REQUIRED_ATTRIBUTES = {
332
- "_OBJECTS",
333
322
  "_PATH",
334
323
  }
335
324
 
336
- _OBJECTS: dict[str, type]
337
-
338
325
  _PATH: str = pyquoks.utils.get_path("config.ini")
339
326
 
340
327
  def __init__(self) -> None:
341
328
  self._check_attributes()
342
329
 
343
- for attribute, child_class in self._OBJECTS.items():
344
- setattr(self, attribute, child_class(self))
330
+ for attribute, child_class in self.__class__.__annotations__.items():
331
+ if issubclass(child_class, ConfigManager.Config):
332
+ setattr(self, attribute, child_class(self))
333
+ else:
334
+ raise AttributeError(
335
+ f"{attribute} has incorrect type! (must be subclass of {ConfigManager.Config.__name__})",
336
+ )
345
337
 
346
338
 
347
339
  class DataManager(pyquoks.utils._HasRequiredAttributes):
@@ -350,8 +342,6 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
350
342
 
351
343
  **Required attributes**::
352
344
 
353
- _OBJECTS = {"users": list[UserModel]}
354
-
355
345
  # Predefined:
356
346
 
357
347
  _PATH = pyquoks.utils.get_path("data/")
@@ -359,19 +349,15 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
359
349
  _FILENAME = "{0}.json"
360
350
 
361
351
  Attributes:
362
- _OBJECTS: Dictionary with filenames and types of models
363
352
  _PATH: Path to the directory with JSON-like files
364
353
  _FILENAME: Filename of JSON-like files
365
354
  """
366
355
 
367
356
  _REQUIRED_ATTRIBUTES = {
368
- "_OBJECTS",
369
357
  "_PATH",
370
358
  "_FILENAME",
371
359
  }
372
360
 
373
- _OBJECTS: dict[str, type[pydantic.BaseModel] | list[type[pydantic.BaseModel]]]
374
-
375
361
  _PATH: str = pyquoks.utils.get_path("data/")
376
362
 
377
363
  _FILENAME: str = "{0}.json"
@@ -379,17 +365,28 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
379
365
  def __init__(self) -> None:
380
366
  self._check_attributes()
381
367
 
382
- for attribute, object_type in self._OBJECTS.items():
383
- try:
384
- with open(self._PATH + self._FILENAME.format(attribute), "rb") as file:
385
- data = json.loads(file.read())
368
+ for attribute, object_type in self.__class__.__annotations__.items():
369
+ if issubclass(
370
+ typing.get_args(object_type)[0],
371
+ pydantic.BaseModel,
372
+ ) if typing.get_origin(object_type) else issubclass(
373
+ object_type,
374
+ pydantic.BaseModel,
375
+ ):
376
+ try:
377
+ with open(self._PATH + self._FILENAME.format(attribute), "rb") as file:
378
+ data = json.loads(file.read())
386
379
 
387
- if typing.get_origin(object_type) == list:
388
- setattr(self, attribute, [typing.get_args(object_type)[0](**model) for model in data])
389
- else:
390
- setattr(self, attribute, object_type(**data))
391
- except Exception:
392
- setattr(self, attribute, None)
380
+ if typing.get_origin(object_type) == list:
381
+ setattr(self, attribute, [typing.get_args(object_type)[0](**model) for model in data])
382
+ else:
383
+ setattr(self, attribute, object_type(**data))
384
+ except Exception:
385
+ setattr(self, attribute, None)
386
+ else:
387
+ raise AttributeError(
388
+ f"{attribute} has incorrect type! (must be subclass of {pydantic.BaseModel.__name__} or {list.__name__} of its subclasses)",
389
+ )
393
390
 
394
391
  def update(self, **kwargs) -> None:
395
392
  """
@@ -397,12 +394,17 @@ class DataManager(pyquoks.utils._HasRequiredAttributes):
397
394
  """
398
395
 
399
396
  for attribute, value in kwargs.items():
400
- if attribute not in self._OBJECTS.keys():
397
+ value: pydantic.BaseModel | list[pydantic.BaseModel]
398
+
399
+ if attribute not in self.__class__.__annotations__.keys():
401
400
  raise AttributeError(f"{attribute} is not specified!")
402
401
 
403
- object_type = self._OBJECTS.get(attribute)
402
+ object_type = self.__class__.__annotations__.get(attribute)
404
403
 
405
- if type(value) is not object_type:
404
+ if not isinstance(
405
+ value,
406
+ typing.get_origin(object_type) if typing.get_origin(object_type) else object_type,
407
+ ):
406
408
  raise AttributeError(
407
409
  f"{attribute} has incorrect type! (must be {object_type.__name__})",
408
410
  )
@@ -431,14 +433,11 @@ class DatabaseManager(pyquoks.utils._HasRequiredAttributes):
431
433
 
432
434
  **Required attributes**::
433
435
 
434
- _OBJECTS = {"users": UsersDatabase}
435
-
436
436
  # Predefined
437
437
 
438
438
  _PATH = pyquoks.utils.get_path("db/")
439
439
 
440
440
  Attributes:
441
- _OBJECTS: Dictionary with names of attributes and child objects
442
441
  _PATH: Path to the directory with databases
443
442
  """
444
443
 
@@ -502,12 +501,9 @@ class DatabaseManager(pyquoks.utils._HasRequiredAttributes):
502
501
  self.commit()
503
502
 
504
503
  _REQUIRED_ATTRIBUTES = {
505
- "_OBJECTS",
506
504
  "_PATH",
507
505
  }
508
506
 
509
- _OBJECTS: dict[str, type]
510
-
511
507
  _PATH: str = pyquoks.utils.get_path("db/")
512
508
 
513
509
  def __init__(self) -> None:
@@ -518,15 +514,20 @@ class DatabaseManager(pyquoks.utils._HasRequiredAttributes):
518
514
  exist_ok=True,
519
515
  )
520
516
 
521
- for attribute, child_class in self._OBJECTS.items():
522
- setattr(self, attribute, child_class(self))
517
+ for attribute, child_class in self.__class__.__annotations__.items():
518
+ if issubclass(child_class, DatabaseManager.Database):
519
+ setattr(self, attribute, child_class(self))
520
+ else:
521
+ raise AttributeError(
522
+ f"{attribute} has incorrect type! (must be subclass of {DatabaseManager.Database.__name__})",
523
+ )
523
524
 
524
525
  def close_all(self) -> None:
525
526
  """
526
527
  Closes all database connections
527
528
  """
528
529
 
529
- for attribute in self._OBJECTS.keys():
530
+ for attribute in self.__class__.__annotations__.keys():
530
531
  getattr(self, attribute).close()
531
532
 
532
533
 
@@ -1,29 +1,26 @@
1
1
  import datetime
2
2
  import os
3
+ import platform
4
+ import subprocess
3
5
  import sys
4
6
 
5
7
  import psutil
6
8
 
7
9
 
8
- class _HasRequiredAttributes:
10
+ def check_connection() -> bool:
9
11
  """
10
- Assistive class for checking required attributes
11
-
12
- **Required attributes**::
13
-
14
- _REQUIRED_ATTRIBUTES = {"_ATTRIBUTES", "_OBJECTS"}
15
-
16
- Attributes:
17
- _REQUIRED_ATTRIBUTES: Set of required attributes in the class
12
+ :return: Status of "ping www.google.com"
18
13
  """
19
14
 
20
- _REQUIRED_ATTRIBUTES: set[str]
21
-
22
- def _check_attributes(self) -> None:
23
- if hasattr(self, "_REQUIRED_ATTRIBUTES"):
24
- for attribute in self._REQUIRED_ATTRIBUTES:
25
- if not hasattr(self, attribute):
26
- raise AttributeError(f"The required class attribute is not set! ({attribute})")
15
+ return subprocess.run(
16
+ args=[
17
+ "ping",
18
+ "-n" if platform.system().lower() == "windows" else "-c",
19
+ "1",
20
+ "www.google.com",
21
+ ],
22
+ capture_output=True,
23
+ ).returncode == 0
27
24
 
28
25
 
29
26
  def get_path(relative_path: str, use_meipass: bool = False) -> str:
@@ -52,3 +49,24 @@ def get_process_created_datetime(pid: int = os.getpid()) -> datetime.datetime:
52
49
  return datetime.datetime.fromtimestamp(
53
50
  timestamp=process.create_time(),
54
51
  )
52
+
53
+
54
+ class _HasRequiredAttributes:
55
+ """
56
+ Assistive class for checking required attributes
57
+
58
+ **Required attributes**::
59
+
60
+ _REQUIRED_ATTRIBUTES = {"_ATTRIBUTES", "_PATH"}
61
+
62
+ Attributes:
63
+ _REQUIRED_ATTRIBUTES: Set of required attributes in the class
64
+ """
65
+
66
+ _REQUIRED_ATTRIBUTES: set[str]
67
+
68
+ def _check_attributes(self) -> None:
69
+ if hasattr(self, "_REQUIRED_ATTRIBUTES"):
70
+ for attribute in self._REQUIRED_ATTRIBUTES:
71
+ if not hasattr(self, attribute):
72
+ raise AttributeError(f"The required class attribute is not set! ({attribute})")
File without changes
File without changes
File without changes
File without changes