asyncz 0.13.2__tar.gz → 0.13.3__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.13.2 → asyncz-0.13.3}/PKG-INFO +4 -3
- asyncz-0.13.3/asyncz/__init__.py +1 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/stores/redis.py +10 -10
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/cron/expressions.py +3 -3
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/cron/trigger.py +2 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/interval.py +1 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/pyproject.toml +14 -2
- asyncz-0.13.2/asyncz/__init__.py +0 -1
- {asyncz-0.13.2 → asyncz-0.13.3}/.gitignore +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/LICENSE +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/README.md +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/datastructures.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/enums.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/events/__init__.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/events/base.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/events/constants.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/exceptions.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/executors/__init__.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/executors/asyncio.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/executors/base.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/executors/debug.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/executors/pool.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/executors/process_pool.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/executors/types.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/file_locking.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/locks.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/protocols.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/py.typed +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/schedulers/__init__.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/schedulers/asgi.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/schedulers/asyncio.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/schedulers/base.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/schedulers/datastructures.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/schedulers/defaults.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/schedulers/types.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/schedulers/utils.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/state.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/stores/__init__.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/stores/base.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/stores/file.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/stores/memory.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/stores/mongo.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/stores/sqlalchemy.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/stores/types.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/tasks/__init__.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/tasks/base.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/tasks/types.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/__init__.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/base.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/combination.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/cron/__init__.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/cron/constants.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/cron/fields.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/cron/types.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/date.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/shutdown.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/triggers/types.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/typing.py +0 -0
- {asyncz-0.13.2 → asyncz-0.13.3}/asyncz/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: asyncz
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.3
|
|
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/
|
|
@@ -45,17 +45,18 @@ Provides-Extra: loguru
|
|
|
45
45
|
Requires-Dist: loguru<0.8.0,>=0.7.0; extra == 'loguru'
|
|
46
46
|
Provides-Extra: testing
|
|
47
47
|
Requires-Dist: esmerald>=3.7.5; extra == 'testing'
|
|
48
|
+
Requires-Dist: freezegun; extra == 'testing'
|
|
48
49
|
Requires-Dist: httpx; extra == 'testing'
|
|
49
50
|
Requires-Dist: lilya; extra == 'testing'
|
|
50
51
|
Requires-Dist: loguru<0.8.0,>=0.7.0; extra == 'testing'
|
|
51
52
|
Requires-Dist: mypy<2.0.0,>=0.982; extra == 'testing'
|
|
52
53
|
Requires-Dist: pymongo<5.0.0,>=4.3.3; extra == 'testing'
|
|
53
|
-
Requires-Dist: pytest-asyncio<
|
|
54
|
+
Requires-Dist: pytest-asyncio<2.0.0,>=1.0; extra == 'testing'
|
|
54
55
|
Requires-Dist: pytest-cov<7.0.0,>=2.12.0; extra == 'testing'
|
|
55
56
|
Requires-Dist: pytest-loguru<1,>=0.2.0; extra == 'testing'
|
|
56
57
|
Requires-Dist: pytest<9.0.0,>=7.1.3; extra == 'testing'
|
|
57
58
|
Requires-Dist: pytz>=2022.6; extra == 'testing'
|
|
58
|
-
Requires-Dist: redis<
|
|
59
|
+
Requires-Dist: redis<7.0.0,>=4.4.0; extra == 'testing'
|
|
59
60
|
Requires-Dist: sqlalchemy; extra == 'testing'
|
|
60
61
|
Requires-Dist: starlette; extra == 'testing'
|
|
61
62
|
Requires-Dist: tzlocal; extra == 'testing'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.13.3"
|
|
@@ -67,10 +67,10 @@ class RedisStore(BaseStore):
|
|
|
67
67
|
|
|
68
68
|
def get_due_tasks(self, now: datetime) -> list["TaskType"]:
|
|
69
69
|
timestamp = datetime_to_utc_timestamp(now)
|
|
70
|
-
ids: list[str] = self.redis.zrangebyscore(self.run_times_key, 0, timestamp)
|
|
70
|
+
ids: list[str] = self.redis.zrangebyscore(self.run_times_key, 0, timestamp)
|
|
71
71
|
if not ids:
|
|
72
72
|
return []
|
|
73
|
-
states: list[Any] = self.redis.hmget(self.tasks_key, ids)
|
|
73
|
+
states: list[Any] = self.redis.hmget(self.tasks_key, ids)
|
|
74
74
|
return self.rebuild_tasks(zip(ids, states))
|
|
75
75
|
|
|
76
76
|
def rebuild_tasks(self, states: Iterable[tuple[str, Any]]) -> list["TaskType"]:
|
|
@@ -90,7 +90,7 @@ class RedisStore(BaseStore):
|
|
|
90
90
|
with self.redis.pipeline() as pipe:
|
|
91
91
|
pipe.hdel(self.tasks_key, *failed_task_ids)
|
|
92
92
|
pipe.zrem(self.run_times_key, *failed_task_ids)
|
|
93
|
-
pipe.execute()
|
|
93
|
+
pipe.execute()
|
|
94
94
|
|
|
95
95
|
return tasks
|
|
96
96
|
|
|
@@ -101,7 +101,7 @@ class RedisStore(BaseStore):
|
|
|
101
101
|
return None
|
|
102
102
|
|
|
103
103
|
def get_all_tasks(self) -> list["TaskType"]:
|
|
104
|
-
states: list[tuple[str, Any]] = self.redis.hgetall(self.tasks_key)
|
|
104
|
+
states: list[tuple[str, Any]] = self.redis.hgetall(self.tasks_key)
|
|
105
105
|
tasks = self.rebuild_tasks(states.items())
|
|
106
106
|
paused_sort_key = datetime(9999, 12, 31, tzinfo=tz.utc)
|
|
107
107
|
return sorted(tasks, key=lambda task: task.next_run_time or paused_sort_key)
|
|
@@ -116,7 +116,7 @@ class RedisStore(BaseStore):
|
|
|
116
116
|
pipe.hset(
|
|
117
117
|
self.tasks_key,
|
|
118
118
|
task.id,
|
|
119
|
-
self.conditional_encrypt(pickle.dumps(task.__getstate__(), self.pickle_protocol)),
|
|
119
|
+
self.conditional_encrypt(pickle.dumps(task.__getstate__(), self.pickle_protocol)),
|
|
120
120
|
)
|
|
121
121
|
|
|
122
122
|
if task.next_run_time:
|
|
@@ -124,7 +124,7 @@ class RedisStore(BaseStore):
|
|
|
124
124
|
self.run_times_key,
|
|
125
125
|
{task.id: datetime_to_utc_timestamp(task.next_run_time)},
|
|
126
126
|
)
|
|
127
|
-
pipe.execute()
|
|
127
|
+
pipe.execute()
|
|
128
128
|
|
|
129
129
|
def update_task(self, task: "TaskType") -> None:
|
|
130
130
|
assert task.id
|
|
@@ -135,7 +135,7 @@ class RedisStore(BaseStore):
|
|
|
135
135
|
pipe.hset(
|
|
136
136
|
self.tasks_key,
|
|
137
137
|
task.id,
|
|
138
|
-
self.conditional_encrypt(pickle.dumps(task.__getstate__(), self.pickle_protocol)),
|
|
138
|
+
self.conditional_encrypt(pickle.dumps(task.__getstate__(), self.pickle_protocol)),
|
|
139
139
|
)
|
|
140
140
|
if task.next_run_time:
|
|
141
141
|
pipe.zadd(
|
|
@@ -145,7 +145,7 @@ class RedisStore(BaseStore):
|
|
|
145
145
|
else:
|
|
146
146
|
pipe.zrem(self.run_times_key, task.id)
|
|
147
147
|
|
|
148
|
-
pipe.execute()
|
|
148
|
+
pipe.execute()
|
|
149
149
|
|
|
150
150
|
def delete_task(self, task_id: str) -> None:
|
|
151
151
|
if not self.redis.hexists(self.tasks_key, task_id):
|
|
@@ -154,13 +154,13 @@ class RedisStore(BaseStore):
|
|
|
154
154
|
with self.redis.pipeline() as pipe:
|
|
155
155
|
pipe.hdel(self.tasks_key, task_id)
|
|
156
156
|
pipe.zrem(self.run_times_key, task_id)
|
|
157
|
-
pipe.execute()
|
|
157
|
+
pipe.execute()
|
|
158
158
|
|
|
159
159
|
def remove_all_tasks(self) -> None:
|
|
160
160
|
with self.redis.pipeline() as pipe:
|
|
161
161
|
pipe.delete(self.tasks_key)
|
|
162
162
|
pipe.delete(self.run_times_key)
|
|
163
|
-
pipe.execute()
|
|
163
|
+
pipe.execute()
|
|
164
164
|
|
|
165
165
|
def shutdown(self) -> None:
|
|
166
166
|
self.redis.connection_pool.disconnect()
|
|
@@ -54,7 +54,7 @@ class AllExpression(BaseExpression):
|
|
|
54
54
|
|
|
55
55
|
def __str__(self) -> str:
|
|
56
56
|
if self.step:
|
|
57
|
-
return "
|
|
57
|
+
return f"*/{self.step}"
|
|
58
58
|
return "*"
|
|
59
59
|
|
|
60
60
|
def __repr__(self) -> str:
|
|
@@ -131,12 +131,12 @@ class RangeExpression(AllExpression):
|
|
|
131
131
|
|
|
132
132
|
def __str__(self) -> str:
|
|
133
133
|
if self.last != self.first and self.last is not None:
|
|
134
|
-
range = "
|
|
134
|
+
range = f"{self.first}-{self.last}"
|
|
135
135
|
else:
|
|
136
136
|
range = str(self.first)
|
|
137
137
|
|
|
138
138
|
if self.step:
|
|
139
|
-
return "
|
|
139
|
+
return f"{range}/{self.step}"
|
|
140
140
|
return range
|
|
141
141
|
|
|
142
142
|
def __repr__(self) -> str:
|
|
@@ -223,6 +223,7 @@ class CronTrigger(BaseTrigger):
|
|
|
223
223
|
def get_next_trigger_time(
|
|
224
224
|
self, timezone: tzinfo, previous_time: Optional[datetime], now: Optional[datetime] = None
|
|
225
225
|
) -> Union[datetime, None]:
|
|
226
|
+
timezone = self.timezone or timezone
|
|
226
227
|
if now is None:
|
|
227
228
|
now = datetime.now(timezone)
|
|
228
229
|
start_at_field = (
|
|
@@ -246,6 +247,7 @@ class CronTrigger(BaseTrigger):
|
|
|
246
247
|
|
|
247
248
|
fieldnum = 0
|
|
248
249
|
next_date = datetime_ceil(start_at)
|
|
250
|
+
|
|
249
251
|
while 0 <= fieldnum < len(self.fields):
|
|
250
252
|
field = self.fields[fieldnum]
|
|
251
253
|
curr_value = field.get_value(next_date)
|
|
@@ -68,6 +68,7 @@ class IntervalTrigger(BaseTrigger):
|
|
|
68
68
|
previous_time: Optional[datetime],
|
|
69
69
|
now: Union[datetime, None] = None,
|
|
70
70
|
) -> Union[datetime, None]:
|
|
71
|
+
timezone = self.timezone or timezone
|
|
71
72
|
if now is None:
|
|
72
73
|
now = datetime.now(timezone)
|
|
73
74
|
next_trigger_time: Optional[datetime]
|
|
@@ -73,9 +73,9 @@ testing = [
|
|
|
73
73
|
"pymongo>=4.3.3,<5.0.0",
|
|
74
74
|
"pytest>=7.1.3,<9.0.0",
|
|
75
75
|
"pytest-cov >=2.12.0,<7.0.0",
|
|
76
|
-
"pytest-asyncio >=
|
|
76
|
+
"pytest-asyncio >=1.0,<2.0.0",
|
|
77
77
|
"pytest-loguru>=0.2.0,<1",
|
|
78
|
-
"redis>=4.4.0,<
|
|
78
|
+
"redis>=4.4.0,<7.0.0",
|
|
79
79
|
"mypy>=0.982,<2.0.0",
|
|
80
80
|
"esmerald>=3.7.5",
|
|
81
81
|
"starlette",
|
|
@@ -83,6 +83,7 @@ testing = [
|
|
|
83
83
|
"sqlalchemy",
|
|
84
84
|
"httpx",
|
|
85
85
|
"pytz>=2022.6",
|
|
86
|
+
"freezegun"
|
|
86
87
|
]
|
|
87
88
|
|
|
88
89
|
[tool.hatch.envs.default.scripts]
|
|
@@ -124,6 +125,12 @@ dependencies = [
|
|
|
124
125
|
build = "mkdocs build"
|
|
125
126
|
serve = "mkdocs serve --dev-addr localhost:8000"
|
|
126
127
|
|
|
128
|
+
[tool.hatch.envs.hatch-static-analysis]
|
|
129
|
+
# disables custom ruff rules, required to align with pre-commit
|
|
130
|
+
config-path = "none"
|
|
131
|
+
dependencies = ["ruff==0.12.5"]
|
|
132
|
+
|
|
133
|
+
|
|
127
134
|
[tool.hatch.version]
|
|
128
135
|
path = "asyncz/__init__.py"
|
|
129
136
|
|
|
@@ -187,6 +194,11 @@ module = [
|
|
|
187
194
|
ignore_missing_imports = true
|
|
188
195
|
ignore_errors = true
|
|
189
196
|
|
|
197
|
+
[[tool.mypy.overrides]]
|
|
198
|
+
module = "tests.*"
|
|
199
|
+
ignore_errors = true
|
|
200
|
+
|
|
201
|
+
|
|
190
202
|
[tool.pytest.ini_options]
|
|
191
203
|
addopts = ["--strict-config", "--strict-markers"]
|
|
192
204
|
xfail_strict = true
|
asyncz-0.13.2/asyncz/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.13.2"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|