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.
Files changed (55) hide show
  1. {asyncz-0.7.0 → asyncz-0.8.0}/PKG-INFO +1 -1
  2. asyncz-0.8.0/asyncz/__init__.py +1 -0
  3. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/_mapping.py +1 -1
  4. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/asyncio.py +7 -2
  5. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/base.py +15 -49
  6. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/utils.py +3 -7
  7. {asyncz-0.7.0 → asyncz-0.8.0}/pyproject.toml +4 -3
  8. asyncz-0.7.0/asyncz/__init__.py +0 -1
  9. {asyncz-0.7.0 → asyncz-0.8.0}/.gitignore +0 -0
  10. {asyncz-0.7.0 → asyncz-0.8.0}/LICENSE +0 -0
  11. {asyncz-0.7.0 → asyncz-0.8.0}/README.md +0 -0
  12. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/contrib/__init__.py +0 -0
  13. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/contrib/esmerald/__init__.py +0 -0
  14. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/contrib/esmerald/decorator.py +0 -0
  15. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/contrib/esmerald/scheduler.py +0 -0
  16. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/datastructures.py +0 -0
  17. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/enums.py +0 -0
  18. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/events/__init__.py +0 -0
  19. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/events/base.py +0 -0
  20. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/events/constants.py +0 -0
  21. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/exceptions.py +0 -0
  22. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/__init__.py +0 -0
  23. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/asyncio.py +0 -0
  24. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/base.py +0 -0
  25. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/debug.py +0 -0
  26. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/pool.py +0 -0
  27. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/executors/types.py +0 -0
  28. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/py.typed +0 -0
  29. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/__init__.py +0 -0
  30. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/datastructures.py +0 -0
  31. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/types.py +0 -0
  32. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/schedulers/utils.py +0 -0
  33. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/state.py +0 -0
  34. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/__init__.py +0 -0
  35. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/base.py +0 -0
  36. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/memory.py +0 -0
  37. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/mongo.py +0 -0
  38. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/redis.py +0 -0
  39. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/stores/types.py +0 -0
  40. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/tasks/__init__.py +0 -0
  41. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/tasks/base.py +0 -0
  42. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/tasks/types.py +0 -0
  43. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/__init__.py +0 -0
  44. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/base.py +0 -0
  45. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/combination.py +0 -0
  46. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/__init__.py +0 -0
  47. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/constants.py +0 -0
  48. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/expressions.py +0 -0
  49. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/fields.py +0 -0
  50. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/trigger.py +0 -0
  51. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/cron/types.py +0 -0
  52. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/date.py +0 -0
  53. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/interval.py +0 -0
  54. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/triggers/types.py +0 -0
  55. {asyncz-0.7.0 → asyncz-0.8.0}/asyncz/typing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: asyncz
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: The scheduler that nobody wants but every application needs.
5
5
  Project-URL: Homepage, https://github.com/dymmond/asyncz
6
6
  Project-URL: Documentation, https://asyncz.dymmond.com/
@@ -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
- "mongo": "asyncz.stores.mongo:MongoDBStore",
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 = 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", None))
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.dict(exclude_none=True).items():
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
- dependencies = ["asyncz[testing]"]
98
+ features = ["testing"]
99
99
 
100
100
  [tool.hatch.envs.test.scripts]
101
101
  # needs docker services running
102
- test = "pytest --disable-pytest-warnings -s -vv {args}"
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
 
@@ -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