wiederverwendbar 0.8.5__py3-none-any.whl → 0.8.6__py3-none-any.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.
@@ -1,4 +1,4 @@
1
- __version__ = "0.8.5"
1
+ __version__ = "0.8.6"
2
2
  TITLE = "wiederverwendbar"
3
3
  VERSION = __version__
4
4
  AUTHOR = "Julius Koenig"
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  from enum import Enum
2
3
 
3
4
 
@@ -12,3 +13,7 @@ class LogLevels(str, Enum):
12
13
  WARNING = "WARNING"
13
14
  INFO = "INFO"
14
15
  DEBUG = "DEBUG"
16
+
17
+ @property
18
+ def logging_level(self) -> int:
19
+ return getattr(logging, self.value)
@@ -1,15 +1,19 @@
1
1
  import json
2
+ import sys
3
+ from warnings import warn
2
4
  from pathlib import Path
3
- from typing import Any, Union
5
+ from typing import Any, Union, Literal
4
6
 
5
7
  from pydantic import BaseModel, create_model
6
8
 
9
+ from wiederverwendbar.warnings import FileNotFoundWarning
10
+
7
11
 
8
12
  class FileConfig(BaseModel):
9
13
  def __init__(self,
10
14
  file_path: Union[Path, str, None] = None,
11
15
  file_postfix: str = ".json",
12
- file_must_exist: bool = False,
16
+ file_must_exist: Union[bool, Literal["yes_print", "yes_warn", "yes_raise", "no"]] = "no",
13
17
  **overwrite_data: Any):
14
18
  if file_path is None:
15
19
  file_path = Path(Path.cwd() / self.__class__.__name__.lower()).with_suffix(file_postfix)
@@ -17,6 +21,7 @@ class FileConfig(BaseModel):
17
21
  file_path = Path(file_path)
18
22
  if file_path.suffix == "":
19
23
  file_path = file_path.with_suffix(file_postfix)
24
+ file_path = file_path.absolute()
20
25
 
21
26
  # read data from file
22
27
  if file_path.is_file():
@@ -25,8 +30,19 @@ class FileConfig(BaseModel):
25
30
  elif file_path.is_dir():
26
31
  raise ValueError(f"{self.__class__.__name__} file path '{file_path}' is a directory.")
27
32
  else:
28
- if file_must_exist:
29
- raise FileNotFoundError(f"{self.__class__.__name__} file '{file_path}' not found.")
33
+ if file_must_exist is True:
34
+ file_must_exist = "yes_raise"
35
+ elif file_must_exist is False:
36
+ file_must_exist = "no"
37
+ msg = f"{self.__class__.__name__} file '{file_path}' not found."
38
+ if file_must_exist == "yes_print":
39
+ print(msg)
40
+ sys.exit(1)
41
+ elif file_must_exist == "yes_warn":
42
+ warn(msg, FileNotFoundWarning)
43
+ sys.exit(1)
44
+ elif file_must_exist == "yes_raise":
45
+ raise FileNotFoundError(msg)
30
46
  data = {}
31
47
 
32
48
  # overwrite data
@@ -260,7 +260,7 @@ class Base:
260
260
  @classmethod
261
261
  def new(cls,
262
262
  session: Optional[Session] = None,
263
- **kwargs) -> "Base":
263
+ **kwargs) -> Union["Base", Any]:
264
264
  session_created, session = cls.session(session=session)
265
265
 
266
266
  # noinspection PyArgumentList
@@ -292,7 +292,7 @@ class Base:
292
292
  @classmethod
293
293
  def get_all(cls,
294
294
  *criterion: Union[ColumnExpressionArgument[bool], bool],
295
- order_by: Union[str, QueryableAttribute, None] = None,
295
+ order_by: Union[str, QueryableAttribute, Any, None] = None,
296
296
  order_desc: bool = False,
297
297
  rows_per_page: Optional[int] = None,
298
298
  page: int = 1,
@@ -300,7 +300,7 @@ class Base:
300
300
  as_dict: bool = False,
301
301
  dict_columns: Union[list[DictColumn], Default] = Default(),
302
302
  session: Optional[Session] = None,
303
- **kwargs: Any) -> list[Union["Base", None, dict[str, Any]]]:
303
+ **kwargs: Any) -> list[Union["Base", None, dict[str, Any], Any]]:
304
304
  session_created, session = cls.session(session=session)
305
305
 
306
306
  # get order by
@@ -364,7 +364,7 @@ class Base:
364
364
  as_dict: bool = False,
365
365
  dict_columns: Union[list[DictColumn], Default] = Default(),
366
366
  session: Optional[Session] = None,
367
- **kwargs: Any) -> Union["Base", None, dict[str, Any]]:
367
+ **kwargs: Any) -> Union["Base", None, dict[str, Any], Any]:
368
368
  session_created, session = cls.session(session=session)
369
369
 
370
370
  if criterion:
@@ -59,16 +59,13 @@ class Task:
59
59
  raise ValueError("Manager object is required.")
60
60
  manager.add_task(self)
61
61
 
62
- def __str__(self):
63
- return f"{self.manager.name}.{self.name}"
64
-
65
62
  def init(self, manager):
66
63
  self.manager = manager
67
64
  self.trigger.init(manager)
68
65
  self.set_next_run()
69
66
 
70
67
  # log task creation
71
- self.manager.logger.debug(f"{self}: Task created.")
68
+ self.manager.logger.debug(f"Task created.")
72
69
 
73
70
  @property
74
71
  def last_run(self) -> Optional[datetime]:
@@ -8,9 +8,6 @@ from typing import Any, Optional
8
8
  from wiederverwendbar.task_manger.task import Task
9
9
  from wiederverwendbar.task_manger.trigger import Trigger
10
10
 
11
- LOGGER = logging.getLogger(__name__)
12
-
13
-
14
11
  class TaskManager:
15
12
  lock = threading.Lock()
16
13
 
@@ -20,7 +17,8 @@ class TaskManager:
20
17
  daemon: bool = False,
21
18
  keep_done_tasks: bool = False,
22
19
  loop_delay: Optional[float] = None,
23
- logger: Optional[logging.Logger] = None):
20
+ logger: Optional[logging.Logger] = None,
21
+ log_self: bool = True):
24
22
  if name is None:
25
23
  name = self.__class__.__name__
26
24
  self.name = name
@@ -29,7 +27,7 @@ class TaskManager:
29
27
  self._stopped: bool = False
30
28
  self._creation_time: datetime = datetime.now()
31
29
  self._keep_done_tasks = keep_done_tasks
32
- self.logger = logger or LOGGER
30
+ self.logger = logger or logging.getLogger(self.name)
33
31
 
34
32
  # create workers
35
33
  if worker_count is None:
@@ -48,9 +46,6 @@ class TaskManager:
48
46
  loop_delay = 0.001
49
47
  self._loop_delay = loop_delay
50
48
 
51
- def __str__(self):
52
- return f"{self.__class__.__name__}({self.name})"
53
-
54
49
  def __del__(self):
55
50
  if not self.stopped:
56
51
  self.stop()
@@ -96,14 +91,14 @@ class TaskManager:
96
91
  :return: None
97
92
  """
98
93
 
99
- self.logger.debug(f"{self}: Starting manager ...")
94
+ self.logger.debug(f"Starting manager ...")
100
95
 
101
96
  # start workers
102
97
  for worker in self._workers:
103
- self.logger.debug(f"{self}: Starting worker '{worker.name}' ...")
98
+ self.logger.debug(f"Starting worker '{worker.name}' ...")
104
99
  worker.start()
105
100
 
106
- self.logger.debug(f"{self}: Manager started.")
101
+ self.logger.debug(f"Manager started.")
107
102
 
108
103
  def stop(self) -> None:
109
104
  """
@@ -112,7 +107,7 @@ class TaskManager:
112
107
  :return: None
113
108
  """
114
109
 
115
- self.logger.debug(f"{self}: Stopping manager ...")
110
+ self.logger.debug(f"Stopping manager ...")
116
111
 
117
112
  # set stopped flag
118
113
  with self.lock:
@@ -121,10 +116,10 @@ class TaskManager:
121
116
  # wait for workers to finish
122
117
  for worker in self._workers:
123
118
  if worker.is_alive():
124
- self.logger.debug(f"{self}: Waiting for worker '{worker.name}' to finish ...")
119
+ self.logger.debug(f"Waiting for worker '{worker.name}' to finish ...")
125
120
  worker.join()
126
121
 
127
- self.logger.debug(f"{self}: Manager stopped.")
122
+ self.logger.debug(f"Manager stopped.")
128
123
 
129
124
  def loop(self, stay_in_loop: Optional[bool] = None) -> None:
130
125
  """
@@ -155,7 +150,7 @@ class TaskManager:
155
150
  time.sleep(loop_delay)
156
151
  continue
157
152
 
158
- self.logger.debug(f"{self}: Running task '{current_task}' ...")
153
+ self.logger.debug(f"Running task '{current_task.name}' ...")
159
154
 
160
155
  with self.lock:
161
156
  if current_task.time_measurement_before_run:
@@ -165,7 +160,7 @@ class TaskManager:
165
160
  # run task
166
161
  current_task.payload()
167
162
 
168
- self.logger.debug(f"{self}: Task '{current_task}' successfully run.")
163
+ self.logger.debug(f"Task '{current_task.name}' successfully run.")
169
164
 
170
165
  with self.lock:
171
166
  if not current_task.time_measurement_before_run:
@@ -174,7 +169,7 @@ class TaskManager:
174
169
  if not current_task.is_done:
175
170
  self._tasks.append(current_task)
176
171
  else:
177
- self.logger.debug(f"{self}: Task '{current_task}' is done.")
172
+ self.logger.debug(f"Task '{current_task.name}' is done.")
178
173
  if self._keep_done_tasks:
179
174
  self._tasks.append(current_task)
180
175
 
@@ -192,7 +187,7 @@ class TaskManager:
192
187
  task.init(self)
193
188
  with self.lock:
194
189
  self._tasks.append(task)
195
- self.logger.debug(f"{self}: Task '{task}' added.")
190
+ self.logger.debug(f"Task '{task.name}' added.")
196
191
 
197
192
  def remove_task(self, task: Task):
198
193
  """
@@ -204,7 +199,7 @@ class TaskManager:
204
199
 
205
200
  with self.lock:
206
201
  self._tasks.remove(task)
207
- self.logger.debug(f"{self}: Task '{task}' removed.")
202
+ self.logger.debug(f"Task '{task.name}' removed.")
208
203
 
209
204
  def task(self,
210
205
  name: Optional[str] = None,
@@ -0,0 +1,6 @@
1
+ class WiederverwendbarWarning(Warning):
2
+ ...
3
+
4
+
5
+ class FileNotFoundWarning(WiederverwendbarWarning):
6
+ ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wiederverwendbar
3
- Version: 0.8.5
3
+ Version: 0.8.6
4
4
  Summary: A collection of scripts, classes and tools they are \"wiederverwendbar\".
5
5
  Author-Email: Julius Koenig <info@bastelquartier.de>
6
6
  License: GPL-3.0
@@ -1,7 +1,7 @@
1
- wiederverwendbar-0.8.5.dist-info/METADATA,sha256=_Rv2S2NNzn3-vzHy6EQZpS9668alPFZHtDRWdNS2sKU,2012
2
- wiederverwendbar-0.8.5.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
- wiederverwendbar-0.8.5.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- wiederverwendbar/__init__.py,sha256=rI0baW27B0s4avXRykXayN0cZK4x2ItpEvLEkLDLSm4,156
1
+ wiederverwendbar-0.8.6.dist-info/METADATA,sha256=zQ-6Wgc3BqZMgcz_hVwr-wmVw8AH3T18Y1vYAPQmVIo,2012
2
+ wiederverwendbar-0.8.6.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
+ wiederverwendbar-0.8.6.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ wiederverwendbar/__init__.py,sha256=_HswkZyK44st-yq5YH55yG3k1EjhaE6FRMN3MVgy_uc,156
5
5
  wiederverwendbar/before_after_wrap.py,sha256=8rjyRrDpwbzrsKkY7vbIgtitgLjlF8Lwx8YNvcJWwgY,10425
6
6
  wiederverwendbar/default.py,sha256=MQBBpJMh8Tz4FUwxszVm7M3j6qbW2JH-5jKSjbvsUUk,49
7
7
  wiederverwendbar/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -60,7 +60,7 @@ wiederverwendbar/logger/handlers/rich_console_handler.py,sha256=C2bFR0-yc4NqMCU-
60
60
  wiederverwendbar/logger/handlers/stream_console_handler.py,sha256=-mPYV3d3xKx9CizdEaIEgLh6_OABbsj8SJ6cBm8P99Q,573
61
61
  wiederverwendbar/logger/handlers/tar_rotating_file_handler.py,sha256=Ci2f4Mvy9f1DacNJiA_P0loWwI4y4oEW9fP0D1iMd8w,2500
62
62
  wiederverwendbar/logger/helper.py,sha256=bI3Qi6aCugmmRkuB5dJGSkKxpr-0bX8TaZtwdk6IS4c,1292
63
- wiederverwendbar/logger/log_levels.py,sha256=DIr1xN3GIvOZajsGNrUKo39f3h7OHq7wP3K0jtB-psY,212
63
+ wiederverwendbar/logger/log_levels.py,sha256=M8NOL8nRRtin2fOhAzaJL5XdPP03GCfBHHGp-BTzeVM,322
64
64
  wiederverwendbar/logger/logger.py,sha256=yb-0aD3_mYHdwC-xnbg3oPegM_q4H0S-q14mlVedfVA,2860
65
65
  wiederverwendbar/logger/settings.py,sha256=w2gGbx447UsnjB1uZ5hjt_J28PGrnMNxQp5qveVmifo,5876
66
66
  wiederverwendbar/logger/singleton.py,sha256=3FWKLSIF7aGOUR2TlBHfO2BHFwYvzGa5hrtsD6Im2GE,3260
@@ -88,7 +88,7 @@ wiederverwendbar/mongoengine/settings.py,sha256=Kgc2VTWvXa5CcZdxOsVBx9HdcaWeOLG3
88
88
  wiederverwendbar/mongoengine/singleton.py,sha256=xeh0OQM8q79ffn9Yz8tyNcjzZg68TD6xpfIZRT_M0mU,183
89
89
  wiederverwendbar/post_init.py,sha256=7w1iQbOlRpydDJT3Ti0v8_OmjwjVTIQjOZUVPEIvrpw,474
90
90
  wiederverwendbar/pydantic/__init__.py,sha256=lQRcyAOXBZfq-jTd-n7zpzC9HxsbiLgMvU8bKuFbSW8,335
91
- wiederverwendbar/pydantic/file_config.py,sha256=DCiCFK8FZm9lurwKtbR8GfAkzd4Yv0O9AAlrW2jN3Mw,2157
91
+ wiederverwendbar/pydantic/file_config.py,sha256=qX5wVS7TvNGjyzo9wRzBK92c73ux8X75pIoMUyPoRgA,2794
92
92
  wiederverwendbar/pydantic/indexable_model.py,sha256=o9Ej9Z0oVWxYOJQdqJsik0C3LWi0dnLjoDB00VMs24g,775
93
93
  wiederverwendbar/pydantic/printable_settings.py,sha256=CSN8n1NUnviOMc6wgnvIdcQlbti71oCTAq8fbFLjP_4,879
94
94
  wiederverwendbar/pydantic/security/__init__.py,sha256=l-DRf-vueyP-M4pePTzQgCYZcBMb_0Fg5flwN-0dBWc,83
@@ -97,7 +97,7 @@ wiederverwendbar/pydantic/singleton.py,sha256=4YMBcKiTik2KmuN97CUCmy_ldhfyeDzrsU
97
97
  wiederverwendbar/route.py,sha256=moYlZ5IvV_uDroSggxe80-sR3_nlNsl9Bp69CcCfK8Y,12061
98
98
  wiederverwendbar/singleton.py,sha256=6QqeQpzx4UhBZnvto5_yUs7hpmzt_-dyE169RuwsTa8,6866
99
99
  wiederverwendbar/sqlalchemy/__init__.py,sha256=gkt99fc9wIxaSjrl1xNhmPLrlJNZhrY-sJ5yIezREGM,888
100
- wiederverwendbar/sqlalchemy/base.py,sha256=q_wiVyiAK4c-z3InFIy4TEN140Rp8MjEQqhxhL2bvaw,15030
100
+ wiederverwendbar/sqlalchemy/base.py,sha256=wNL0vnDuCwM7bLm8imLGAtGxz5uWWsg4d9n64HZZKT4,15057
101
101
  wiederverwendbar/sqlalchemy/db.py,sha256=u3nHJh8pxnOMALldp72sohe1XZ-ZfksZZVpE5qIxHgc,9610
102
102
  wiederverwendbar/sqlalchemy/raise_has_not_attr.py,sha256=GdmbSC8EoBCkpuZQGLp3zzQ0iScsj2XfFZC9OZtWbkA,403
103
103
  wiederverwendbar/sqlalchemy/settings.py,sha256=RM-bFg_Ga0AUko4JWOvCZLcfoB91kKpn1TqVzgxAm_k,2579
@@ -158,8 +158,8 @@ wiederverwendbar/starlette_admin/settings/admin.py,sha256=moEgCDUpf2eQ2o7e2SaeMk
158
158
  wiederverwendbar/starlette_admin/settings/settings.py,sha256=3T1EcFNATDI45o99MIlzmfs-1XYzUWB6p9C7L4zvJ0A,7378
159
159
  wiederverwendbar/task_manger/__init__.py,sha256=A46SQ_MJiMdcZ7HU2ePEsv0xGdek9gnW1X4Q1QXtB7E,354
160
160
  wiederverwendbar/task_manger/singleton.py,sha256=HQ6XwVmBmCEVAzTLeloMU-vf3JnctBUXDGC2SaEL2vw,183
161
- wiederverwendbar/task_manger/task.py,sha256=ZCT6EFGlJzVCgHNHm-xAdgwDHGc2cp10SUdF5d_-piU,3043
162
- wiederverwendbar/task_manger/task_manager.py,sha256=UNY1MAqw6m3uUvCkfDT0a0QJwJgepVjr7yxnSrLkMTE,6992
161
+ wiederverwendbar/task_manger/task.py,sha256=NanEdg28Bn6JwG6mwrL0qLZIcGI6XQzVbctwXa0-j14,2961
162
+ wiederverwendbar/task_manger/task_manager.py,sha256=FuB0Lf2ff4KaVtPp7G585uF7GjjMFszY7oGGNSOIfSI,6871
163
163
  wiederverwendbar/task_manger/trigger.py,sha256=biTQv3_S7d14CkPXKjDQxL6XbTet7-PVRwofsCBs3Wc,9906
164
164
  wiederverwendbar/threading/__init__.py,sha256=jFeP8mQws_JVwxL8W1fCsWPUcFqO-l39yQ8d9P3AqtQ,508
165
165
  wiederverwendbar/threading/extended_thread.py,sha256=CJi2fmpHBZD9jo5B8_85Ax8jo1pM5n9cjEVuG6Guxg8,23409
@@ -168,4 +168,5 @@ wiederverwendbar/typer/typer_resolve_defaults.py,sha256=2KD09rxKaur2TbJ3BCcLxbrc
168
168
  wiederverwendbar/uvicorn/__init__.py,sha256=9F7gT-8QyxS41xWKEIHMLUBV9ZTBKZJj8tHPqhMzoHA,126
169
169
  wiederverwendbar/uvicorn/server.py,sha256=04WpB8AUtVkYhoS6qsBVJHOtTNkISQVg_mLVtYmK-1Y,5657
170
170
  wiederverwendbar/uvicorn/settings.py,sha256=IAjlpWR-KH7098jIgH_t46yG17YPbH8MoEmMdn0hgNo,2217
171
- wiederverwendbar-0.8.5.dist-info/RECORD,,
171
+ wiederverwendbar/warnings.py,sha256=6P1wn-OkrDCo5zg_hL28nt5b9w4ZXo4qXwlpW9B_QWI,110
172
+ wiederverwendbar-0.8.6.dist-info/RECORD,,