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.
- wiederverwendbar/__init__.py +1 -1
- wiederverwendbar/logger/log_levels.py +5 -0
- wiederverwendbar/pydantic/file_config.py +20 -4
- wiederverwendbar/sqlalchemy/base.py +4 -4
- wiederverwendbar/task_manger/task.py +1 -4
- wiederverwendbar/task_manger/task_manager.py +14 -19
- wiederverwendbar/warnings.py +6 -0
- {wiederverwendbar-0.8.5.dist-info → wiederverwendbar-0.8.6.dist-info}/METADATA +1 -1
- {wiederverwendbar-0.8.5.dist-info → wiederverwendbar-0.8.6.dist-info}/RECORD +11 -10
- {wiederverwendbar-0.8.5.dist-info → wiederverwendbar-0.8.6.dist-info}/WHEEL +0 -0
- {wiederverwendbar-0.8.5.dist-info → wiederverwendbar-0.8.6.dist-info}/entry_points.txt +0 -0
wiederverwendbar/__init__.py
CHANGED
@@ -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 =
|
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
|
-
|
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"
|
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
|
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"
|
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"
|
98
|
+
self.logger.debug(f"Starting worker '{worker.name}' ...")
|
104
99
|
worker.start()
|
105
100
|
|
106
|
-
self.logger.debug(f"
|
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"
|
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"
|
119
|
+
self.logger.debug(f"Waiting for worker '{worker.name}' to finish ...")
|
125
120
|
worker.join()
|
126
121
|
|
127
|
-
self.logger.debug(f"
|
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"
|
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"
|
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"
|
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"
|
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"
|
202
|
+
self.logger.debug(f"Task '{task.name}' removed.")
|
208
203
|
|
209
204
|
def task(self,
|
210
205
|
name: Optional[str] = None,
|
@@ -1,7 +1,7 @@
|
|
1
|
-
wiederverwendbar-0.8.
|
2
|
-
wiederverwendbar-0.8.
|
3
|
-
wiederverwendbar-0.8.
|
4
|
-
wiederverwendbar/__init__.py,sha256=
|
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=
|
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=
|
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=
|
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=
|
162
|
-
wiederverwendbar/task_manger/task_manager.py,sha256=
|
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
|
171
|
+
wiederverwendbar/warnings.py,sha256=6P1wn-OkrDCo5zg_hL28nt5b9w4ZXo4qXwlpW9B_QWI,110
|
172
|
+
wiederverwendbar-0.8.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|