asyncz 0.7.0__tar.gz → 0.8.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.
- {asyncz-0.7.0 → asyncz-0.8.0}/PKG-INFO +1 -1
- asyncz-0.8.0/asyncz/__init__.py +1 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/_mapping.py +1 -1
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/asyncio.py +7 -2
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/base.py +15 -49
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/utils.py +3 -7
- {asyncz-0.7.0 → asyncz-0.8.0}/pyproject.toml +4 -3
- asyncz-0.7.0/asyncz/__init__.py +0 -1
- {asyncz-0.7.0 → asyncz-0.8.0}/.gitignore +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/LICENSE +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/README.md +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/contrib/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/contrib/esmerald/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/contrib/esmerald/decorator.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/contrib/esmerald/scheduler.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/datastructures.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/enums.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/events/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/events/base.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/events/constants.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/exceptions.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/asyncio.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/base.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/debug.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/pool.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/types.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/py.typed +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/datastructures.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/types.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/utils.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/state.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/base.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/memory.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/mongo.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/redis.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/types.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/tasks/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/tasks/base.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/tasks/types.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/base.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/combination.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/__init__.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/constants.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/expressions.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/fields.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/trigger.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/types.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/date.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/interval.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/types.py +0 -0
- {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/typing.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.8.0"
|
|
@@ -27,6 +27,6 @@ class AsynczObjectMapping(BaseModel):
|
|
|
27
27
|
def stores(self) -> Dict[str, str]:
|
|
28
28
|
return {
|
|
29
29
|
"memory": "asyncz.stores.memory:MemoryTaskStore",
|
|
30
|
-
"
|
|
30
|
+
"mongodb": "asyncz.stores.mongo:MongoDBStore",
|
|
31
31
|
"redis": "asyncz.stores.redis:RedisStore",
|
|
32
32
|
}
|
|
@@ -18,11 +18,16 @@ class AsyncIOScheduler(BaseScheduler):
|
|
|
18
18
|
event_loop: AsyncOP event loop to use. Default to the global event loop.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
+
event_loop: Optional[Any] = None
|
|
22
|
+
timeout: Optional[int] = None
|
|
23
|
+
timezone: Optional[str] = None
|
|
24
|
+
|
|
21
25
|
def __init__(
|
|
22
26
|
self, event_loop: Optional[Any] = None, timeout: Optional[int] = None, **kwargs: Any
|
|
23
27
|
) -> None:
|
|
24
28
|
super().__init__(**kwargs)
|
|
25
|
-
self.event_loop
|
|
29
|
+
if self.event_loop is None:
|
|
30
|
+
self.event_loop = event_loop
|
|
26
31
|
self.timeout = timeout
|
|
27
32
|
|
|
28
33
|
def start(self, paused: bool = False):
|
|
@@ -36,7 +41,7 @@ class AsyncIOScheduler(BaseScheduler):
|
|
|
36
41
|
self.stop_timer()
|
|
37
42
|
|
|
38
43
|
def _setup(self, config: Any) -> None:
|
|
39
|
-
self.event_loop = maybe_ref(config.pop("event_loop",
|
|
44
|
+
self.event_loop = maybe_ref(config.pop("event_loop", asyncio.get_event_loop()))
|
|
40
45
|
super()._setup(config)
|
|
41
46
|
|
|
42
47
|
def start_timer(self, wait_seconds: Optional[int] = None):
|
|
@@ -45,14 +45,7 @@ from asyncz.stores.memory import MemoryStore
|
|
|
45
45
|
from asyncz.tasks import Task
|
|
46
46
|
from asyncz.triggers.base import BaseTrigger
|
|
47
47
|
from asyncz.typing import undefined
|
|
48
|
-
from asyncz.utils import
|
|
49
|
-
TIMEOUT_MAX,
|
|
50
|
-
maybe_ref,
|
|
51
|
-
timedelta_seconds,
|
|
52
|
-
to_bool,
|
|
53
|
-
to_int,
|
|
54
|
-
to_timezone,
|
|
55
|
-
)
|
|
48
|
+
from asyncz.utils import TIMEOUT_MAX, maybe_ref, timedelta_seconds, to_bool, to_int, to_timezone
|
|
56
49
|
|
|
57
50
|
DictAny = Dict[Any, Any]
|
|
58
51
|
|
|
@@ -181,16 +174,13 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
181
174
|
self.real_add_task(task, store_alias, replace_existing)
|
|
182
175
|
del self.pending_tasks[:]
|
|
183
176
|
|
|
184
|
-
self.state =
|
|
185
|
-
SchedulerState.STATE_PAUSED if paused else SchedulerState.STATE_RUNNING
|
|
186
|
-
)
|
|
177
|
+
self.state = SchedulerState.STATE_PAUSED if paused else SchedulerState.STATE_RUNNING
|
|
187
178
|
self.logger.info("Scheduler started.")
|
|
188
179
|
self.dispatch_event(SchedulerEvent(code=SCHEDULER_START))
|
|
189
180
|
|
|
190
181
|
if not paused:
|
|
191
182
|
self.wakeup()
|
|
192
183
|
|
|
193
|
-
@abstractmethod
|
|
194
184
|
def shutdown(self, wait: bool = True):
|
|
195
185
|
"""
|
|
196
186
|
Shuts down the scheduler, along with its executors and task stores.
|
|
@@ -285,9 +275,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
285
275
|
|
|
286
276
|
self.dispatch_event(SchedulerEvent(code=EXECUTOR_REMOVED, alias=alias))
|
|
287
277
|
|
|
288
|
-
def add_store(
|
|
289
|
-
self, store: "StoreType", alias: str = "default", **store_options: Any
|
|
290
|
-
):
|
|
278
|
+
def add_store(self, store: "StoreType", alias: str = "default", **store_options: Any):
|
|
291
279
|
"""
|
|
292
280
|
Adds a task store to this scheduler.
|
|
293
281
|
|
|
@@ -424,9 +412,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
424
412
|
"max_instances": max_instances,
|
|
425
413
|
"next_run_time": next_run_time,
|
|
426
414
|
}
|
|
427
|
-
task_kwargs = {
|
|
428
|
-
key: value for key, value in task_struct.items() if value is not undefined
|
|
429
|
-
}
|
|
415
|
+
task_kwargs = {key: value for key, value in task_struct.items() if value is not undefined}
|
|
430
416
|
task = Task(self, **task_kwargs)
|
|
431
417
|
|
|
432
418
|
with self.store_lock:
|
|
@@ -540,13 +526,9 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
540
526
|
trigger = self.create_trigger(trigger, trigger_args)
|
|
541
527
|
now = datetime.now(self.timezone)
|
|
542
528
|
next_run_time = trigger.get_next_trigger_time(None, now)
|
|
543
|
-
return self.update_task(
|
|
544
|
-
task_id, store, trigger=trigger, next_run_time=next_run_time
|
|
545
|
-
)
|
|
529
|
+
return self.update_task(task_id, store, trigger=trigger, next_run_time=next_run_time)
|
|
546
530
|
|
|
547
|
-
def pause_task(
|
|
548
|
-
self, task_id: Union[int, str], store: Optional[str] = None
|
|
549
|
-
) -> "TaskType":
|
|
531
|
+
def pause_task(self, task_id: Union[int, str], store: Optional[str] = None) -> "TaskType":
|
|
550
532
|
"""
|
|
551
533
|
Causes the given task not to be executed until it is explicitly resumed.
|
|
552
534
|
|
|
@@ -600,9 +582,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
600
582
|
|
|
601
583
|
return tasks
|
|
602
584
|
|
|
603
|
-
def get_task(
|
|
604
|
-
self, task_id: str, store: Optional[str] = None
|
|
605
|
-
) -> Union["TaskType", None]:
|
|
585
|
+
def get_task(self, task_id: str, store: Optional[str] = None) -> Union["TaskType", None]:
|
|
606
586
|
"""
|
|
607
587
|
Returms the Task that matches the given task_id.
|
|
608
588
|
|
|
@@ -835,15 +815,13 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
835
815
|
replace_existing: The flag indicating the replacement of the task.
|
|
836
816
|
"""
|
|
837
817
|
replacements = {}
|
|
838
|
-
for key, value in self.task_defaults.
|
|
818
|
+
for key, value in self.task_defaults.model_dump(exclude_none=True).items():
|
|
839
819
|
replacements[key] = value
|
|
840
820
|
|
|
841
821
|
# Calculate the next run time if there is none defined
|
|
842
822
|
if not getattr(task, "next_run_time", None):
|
|
843
823
|
now = datetime.now(self.timezone)
|
|
844
|
-
replacements["next_run_time"] = task.trigger.get_next_trigger_time(
|
|
845
|
-
None, now
|
|
846
|
-
)
|
|
824
|
+
replacements["next_run_time"] = task.trigger.get_next_trigger_time(None, now)
|
|
847
825
|
|
|
848
826
|
# Apply replacements
|
|
849
827
|
task._update(**replacements)
|
|
@@ -876,9 +854,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
876
854
|
try:
|
|
877
855
|
module_path, class_name = module_name.rsplit(":", 1)
|
|
878
856
|
except ValueError as err:
|
|
879
|
-
raise ImportError(
|
|
880
|
-
"%s doesn't look like a module path" % module_name
|
|
881
|
-
) from err
|
|
857
|
+
raise ImportError("%s doesn't look like a module path" % module_name) from err
|
|
882
858
|
|
|
883
859
|
module = import_module(module_path)
|
|
884
860
|
|
|
@@ -910,9 +886,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
910
886
|
f"The {format(_type)} entry point does not point to a {format(_type)} class."
|
|
911
887
|
) from None
|
|
912
888
|
else:
|
|
913
|
-
raise LookupError(
|
|
914
|
-
f"No {_type} by the name '{alias}' was found."
|
|
915
|
-
) from None
|
|
889
|
+
raise LookupError(f"No {_type} by the name '{alias}' was found.") from None
|
|
916
890
|
|
|
917
891
|
return plugin_cls(**constructor_args)
|
|
918
892
|
|
|
@@ -964,9 +938,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
964
938
|
self.logger.warning(
|
|
965
939
|
f"Error getting due tasks from the store {store_alias}: {e}."
|
|
966
940
|
)
|
|
967
|
-
retry_wakeup_time = now + timedelta(
|
|
968
|
-
seconds=self.store_retry_interval
|
|
969
|
-
)
|
|
941
|
+
retry_wakeup_time = now + timedelta(seconds=self.store_retry_interval)
|
|
970
942
|
if not next_wakeup_time or next_wakeup_time > retry_wakeup_time:
|
|
971
943
|
next_wakeup_time = retry_wakeup_time
|
|
972
944
|
continue
|
|
@@ -982,9 +954,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
982
954
|
continue
|
|
983
955
|
|
|
984
956
|
run_times = task.get_run_times(now)
|
|
985
|
-
run_times =
|
|
986
|
-
run_times[-1:] if run_times and task.coalesce else run_times
|
|
987
|
-
)
|
|
957
|
+
run_times = run_times[-1:] if run_times and task.coalesce else run_times
|
|
988
958
|
|
|
989
959
|
if run_times:
|
|
990
960
|
try:
|
|
@@ -1014,9 +984,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
1014
984
|
)
|
|
1015
985
|
events.append(event)
|
|
1016
986
|
|
|
1017
|
-
next_run = task.trigger.get_next_trigger_time(
|
|
1018
|
-
run_times[-1], now
|
|
1019
|
-
)
|
|
987
|
+
next_run = task.trigger.get_next_trigger_time(run_times[-1], now)
|
|
1020
988
|
if next_run:
|
|
1021
989
|
task._update(next_run_time=next_run)
|
|
1022
990
|
store.update_task(task)
|
|
@@ -1039,9 +1007,7 @@ class BaseScheduler(BaseStateExtra, ABC):
|
|
|
1039
1007
|
wait_seconds = None
|
|
1040
1008
|
self.logger.debug("No tasks. Waiting until task is added.")
|
|
1041
1009
|
else:
|
|
1042
|
-
wait_seconds = min(
|
|
1043
|
-
max(timedelta_seconds(next_wakeup_time - now), 0), TIMEOUT_MAX
|
|
1044
|
-
)
|
|
1010
|
+
wait_seconds = min(max(timedelta_seconds(next_wakeup_time - now), 0), TIMEOUT_MAX)
|
|
1045
1011
|
self.logger.debug(
|
|
1046
1012
|
f"Next wakeup is due at {next_wakeup_time} (in {wait_seconds} seconds)."
|
|
1047
1013
|
)
|
|
@@ -190,9 +190,7 @@ def get_callable_name(func: Any) -> Any:
|
|
|
190
190
|
return func.__name__
|
|
191
191
|
return func.__class__.__name__
|
|
192
192
|
|
|
193
|
-
raise TypeError(
|
|
194
|
-
"Unable to determine a name for %r -- maybe it is not a callable?" % func
|
|
195
|
-
)
|
|
193
|
+
raise TypeError("Unable to determine a name for %r -- maybe it is not a callable?" % func)
|
|
196
194
|
|
|
197
195
|
|
|
198
196
|
def obj_to_ref(obj: Any) -> str:
|
|
@@ -316,8 +314,7 @@ def check_callable_args(func: Callable[..., Any], args: Any, kwargs: Any) -> Non
|
|
|
316
314
|
|
|
317
315
|
if unsatisfied_args:
|
|
318
316
|
raise ValueError(
|
|
319
|
-
"The following arguments have not been supplied: %s"
|
|
320
|
-
% ", ".join(unsatisfied_args)
|
|
317
|
+
"The following arguments have not been supplied: %s" % ", ".join(unsatisfied_args)
|
|
321
318
|
)
|
|
322
319
|
|
|
323
320
|
if unsatisfied_kwargs:
|
|
@@ -329,8 +326,7 @@ def check_callable_args(func: Callable[..., Any], args: Any, kwargs: Any) -> Non
|
|
|
329
326
|
if not has_varargs and unmatched_args:
|
|
330
327
|
raise ValueError(
|
|
331
328
|
"The list of positional arguments is longer than the target callable can handle "
|
|
332
|
-
"(allowed: %d, given in args: %d)"
|
|
333
|
-
% (len(args) - len(unmatched_args), len(args))
|
|
329
|
+
"(allowed: %d, given in args: %d)" % (len(args) - len(unmatched_args), len(args))
|
|
334
330
|
)
|
|
335
331
|
|
|
336
332
|
if not has_var_kwargs and unmatched_kwargs:
|
|
@@ -73,7 +73,7 @@ Source = "https://github.com/dymmond/asyncz"
|
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
[tool.hatch.envs.default]
|
|
76
|
-
dependencies = ["ruff", "pre-commit>=2.17.0,<3.0.0", "twine"]
|
|
76
|
+
dependencies = ["ruff", "pre-commit>=2.17.0,<3.0.0", "twine", "ipdb", "pdbpp"]
|
|
77
77
|
|
|
78
78
|
[project.optional-dependencies]
|
|
79
79
|
testing = [
|
|
@@ -95,11 +95,12 @@ lint = "ruff check --fix --line-length 99 asyncz tests docs_src {args}"
|
|
|
95
95
|
build_with_check = "hatch build; twine check dist/*"
|
|
96
96
|
|
|
97
97
|
[tool.hatch.envs.test]
|
|
98
|
-
|
|
98
|
+
features = ["testing"]
|
|
99
99
|
|
|
100
100
|
[tool.hatch.envs.test.scripts]
|
|
101
101
|
# needs docker services running
|
|
102
|
-
test = "pytest --disable-pytest-warnings
|
|
102
|
+
test = "pytest --disable-pytest-warnings {args}"
|
|
103
|
+
test_man = "pytest --disable-pytest-warnings -s -vv {args}"
|
|
103
104
|
coverage = "pytest --cov=asyncz --cov=tests --cov-report=term-missing:skip-covered --cov-report=html tests {args}"
|
|
104
105
|
check_types = "mypy -p asyncz"
|
|
105
106
|
|
asyncz-0.7.0/asyncz/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.7.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|