asyncz 0.6.0__tar.gz → 0.7.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.6.0 → asyncz-0.7.0}/PKG-INFO +42 -65
  2. {asyncz-0.6.0 → asyncz-0.7.0}/README.md +25 -25
  3. asyncz-0.7.0/asyncz/__init__.py +1 -0
  4. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/contrib/esmerald/scheduler.py +9 -9
  5. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/executors/base.py +6 -4
  6. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/schedulers/base.py +51 -23
  7. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/stores/redis.py +15 -8
  8. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/interval.py +14 -3
  9. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/utils.py +18 -20
  10. {asyncz-0.6.0 → asyncz-0.7.0}/pyproject.toml +37 -30
  11. asyncz-0.6.0/asyncz/__init__.py +0 -1
  12. {asyncz-0.6.0 → asyncz-0.7.0}/.gitignore +0 -0
  13. {asyncz-0.6.0 → asyncz-0.7.0}/LICENSE +0 -0
  14. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/_mapping.py +0 -0
  15. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/contrib/__init__.py +0 -0
  16. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/contrib/esmerald/__init__.py +0 -0
  17. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/contrib/esmerald/decorator.py +0 -0
  18. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/datastructures.py +0 -0
  19. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/enums.py +0 -0
  20. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/events/__init__.py +0 -0
  21. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/events/base.py +0 -0
  22. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/events/constants.py +0 -0
  23. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/exceptions.py +0 -0
  24. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/executors/__init__.py +0 -0
  25. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/executors/asyncio.py +0 -0
  26. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/executors/debug.py +0 -0
  27. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/executors/pool.py +0 -0
  28. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/executors/types.py +0 -0
  29. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/py.typed +0 -0
  30. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/schedulers/__init__.py +0 -0
  31. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/schedulers/asyncio.py +0 -0
  32. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/schedulers/datastructures.py +0 -0
  33. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/schedulers/types.py +0 -0
  34. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/schedulers/utils.py +0 -0
  35. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/state.py +0 -0
  36. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/stores/__init__.py +0 -0
  37. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/stores/base.py +0 -0
  38. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/stores/memory.py +0 -0
  39. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/stores/mongo.py +0 -0
  40. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/stores/types.py +0 -0
  41. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/tasks/__init__.py +0 -0
  42. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/tasks/base.py +0 -0
  43. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/tasks/types.py +0 -0
  44. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/__init__.py +0 -0
  45. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/base.py +0 -0
  46. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/combination.py +0 -0
  47. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/cron/__init__.py +0 -0
  48. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/cron/constants.py +0 -0
  49. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/cron/expressions.py +0 -0
  50. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/cron/fields.py +0 -0
  51. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/cron/trigger.py +0 -0
  52. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/cron/types.py +0 -0
  53. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/date.py +0 -0
  54. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/triggers/types.py +0 -0
  55. {asyncz-0.6.0 → asyncz-0.7.0}/asyncz/typing.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: asyncz
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: The scheduler that nobody wants but every application needs.
5
- Project-URL: Homepage, https://github.com/tarsil/asyncz
6
- Project-URL: Documentation, https://asyncz.tarsild.io/
7
- Project-URL: Changelog, https://asyncz.tarsild.io/release-notes/
5
+ Project-URL: Homepage, https://github.com/dymmond/asyncz
6
+ Project-URL: Documentation, https://asyncz.dymmond.com/
7
+ Project-URL: Changelog, https://asyncz.dymmond.com/release-notes/
8
8
  Project-URL: Funding, https://github.com/sponsors/tarsil
9
- Project-URL: Source, https://github.com/tarsil/asyncz
9
+ Project-URL: Source, https://github.com/dymmond/asyncz
10
10
  Author-email: Tiago Silva <tiago.arasilva@gmail.com>
11
11
  License-Expression: MIT
12
12
  License-File: LICENSE
@@ -37,43 +37,20 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
37
37
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
38
  Classifier: Typing :: Typed
39
39
  Requires-Python: >=3.8
40
- Requires-Dist: asyncio<4.0.0,>=3.4.3
40
+ Requires-Dist: backports-zoneinfo; python_version < '3.9'
41
41
  Requires-Dist: loguru<0.8.0,>=0.7.0
42
42
  Requires-Dist: pydantic<3.0.0,>=2.5.3
43
- Requires-Dist: pytz>=2022.6
44
- Requires-Dist: tzlocal<5.0,>=4.2
45
- Provides-Extra: all
46
- Requires-Dist: asyncio<4.0.0,>=3.4.3; extra == 'all'
47
- Requires-Dist: pytz>=2022.6; extra == 'all'
48
- Requires-Dist: tzlocal<5.0,>=4.2; extra == 'all'
49
- Provides-Extra: dev
50
- Requires-Dist: autoflake<3.0.0,>=1.4.0; extra == 'dev'
51
- Requires-Dist: black==24.4.2; extra == 'dev'
52
- Requires-Dist: flake8<8.0.0,>=3.8.3; extra == 'dev'
53
- Requires-Dist: ipdb>=0.13.13; extra == 'dev'
54
- Requires-Dist: isort<6.0.0,>=5.0.6; extra == 'dev'
55
- Requires-Dist: mypy<2.0.0,>=0.982; extra == 'dev'
56
- Requires-Dist: pdbpp; extra == 'dev'
57
- Requires-Dist: pre-commit<3.0.0,>=2.17.0; extra == 'dev'
58
- Requires-Dist: watchfiles<0.22.0,>=0.16.1; extra == 'dev'
59
- Provides-Extra: doc
60
- Requires-Dist: mdx-include<2.0.0,>=1.4.2; extra == 'doc'
61
- Requires-Dist: mkautodoc<0.3.0,>=0.2.0; extra == 'doc'
62
- Requires-Dist: mkdocs-markdownextradata-plugin<0.3.0,>=0.2.5; extra == 'doc'
63
- Requires-Dist: mkdocs-material<10.0.0,>=9.0.13; extra == 'doc'
64
- Requires-Dist: mkdocs<2.0.0,>=1.1.2; extra == 'doc'
65
- Requires-Dist: mkdocstrings<0.30.0,>=0.20.0; extra == 'doc'
66
- Requires-Dist: pyyaml<7.0.0,>=6.0; extra == 'doc'
67
- Provides-Extra: test
68
- Requires-Dist: mock>=4.0.3; extra == 'test'
69
- Requires-Dist: pymongo<5.0.0,>=4.3.3; extra == 'test'
70
- Requires-Dist: pytest-asyncio<1.0.0,>=0.19.0; extra == 'test'
71
- Requires-Dist: pytest-cov<6.0.0,>=2.12.0; extra == 'test'
72
- Requires-Dist: pytest-loguru<1,>=0.2.0; extra == 'test'
73
- Requires-Dist: pytest<9.0.0,>=7.1.3; extra == 'test'
74
- Requires-Dist: redis<6.0.0,>=4.4.0; extra == 'test'
75
- Requires-Dist: requests<3.0.0,>=2.27.0; extra == 'test'
76
- Requires-Dist: ruff<1.0.0,>=0.0.256; extra == 'test'
43
+ Requires-Dist: tzlocal<6.0,>=4.0
44
+ Provides-Extra: testing
45
+ Requires-Dist: esmerald; extra == 'testing'
46
+ Requires-Dist: mypy<2.0.0,>=0.982; extra == 'testing'
47
+ Requires-Dist: pymongo<5.0.0,>=4.3.3; extra == 'testing'
48
+ Requires-Dist: pytest-asyncio<1.0.0,>=0.19.0; extra == 'testing'
49
+ Requires-Dist: pytest-cov<6.0.0,>=2.12.0; extra == 'testing'
50
+ Requires-Dist: pytest-loguru<1,>=0.2.0; extra == 'testing'
51
+ Requires-Dist: pytest<9.0.0,>=7.1.3; extra == 'testing'
52
+ Requires-Dist: pytz>=2022.6; extra == 'testing'
53
+ Requires-Dist: redis<6.0.0,>=4.4.0; extra == 'testing'
77
54
  Description-Content-Type: text/markdown
78
55
 
79
56
  # Asyncz
@@ -87,8 +64,8 @@ Description-Content-Type: text/markdown
87
64
  </p>
88
65
 
89
66
  <p align="center">
90
- <a href="https://github.com/tarsil/asyncz/workflows/Test%20Suite/badge.svg?event=push&branch=main" target="_blank">
91
- <img src="https://github.com/tarsil/asyncz/workflows/Test%20Suite/badge.svg?event=push&branch=main" alt="Test Suite">
67
+ <a href="https://github.com/dymmond/asyncz/workflows/Test%20Suite/badge.svg?event=push&branch=main" target="_blank">
68
+ <img src="https://github.com/dymmond/asyncz/workflows/Test%20Suite/badge.svg?event=push&branch=main" alt="Test Suite">
92
69
  </a>
93
70
 
94
71
  <a href="https://pypi.org/project/asyncz" target="_blank">
@@ -102,9 +79,9 @@ Description-Content-Type: text/markdown
102
79
 
103
80
  ---
104
81
 
105
- **Documentation**: [https://asyncz.tarsild.io](https://asyncz.tarsild.io) 📚
82
+ **Documentation**: [https://asyncz.dymmond.com](https://asyncz.dymmond.com) 📚
106
83
 
107
- **Source Code**: [https://github.com/tarsil/asyncz](https://github.com/tarsil/asyncz)
84
+ **Source Code**: [https://github.com/dymmond/asyncz](https://github.com/dymmond/asyncz)
108
85
 
109
86
  ---
110
87
 
@@ -146,16 +123,16 @@ completely indepent from any framework as well as inside ASGI frameworks such as
146
123
 
147
124
  Asyncz comes with special support to [Esmerald](https://esmerald.dymmond.com) for the simple reason that the author is
148
125
  the same but it can be added more support. If you are interested in adding support to your favourite frameworks then
149
- see the [contributing](https://asyncz.tarsild.io/contributing.md) section.
126
+ see the [contributing](https://asyncz.dymmond.com/contributing.md) section.
150
127
 
151
128
  ## Concepts
152
129
 
153
130
  Like APScheduler, Asyncz also brings four kinds of components:
154
131
 
155
- * [Schedulers](https://asyncz.tarsild.io/schedulers.md)
156
- * [Triggers](https://asyncz.tarsild.io/triggers.md)
157
- * [Stores](https://asyncz.tarsild.io/stores.md)
158
- * [Executors](https://asyncz.tarsild.io/executors.md)
132
+ * [Schedulers](https://asyncz.dymmond.com/schedulers.md)
133
+ * [Triggers](https://asyncz.dymmond.com/triggers.md)
134
+ * [Stores](https://asyncz.dymmond.com/stores.md)
135
+ * [Executors](https://asyncz.dymmond.com/executors.md)
159
136
 
160
137
  ## Requirements
161
138
 
@@ -174,28 +151,28 @@ $ pip install asyncz
174
151
 
175
152
  ## The right decisions
176
153
 
177
- How do you know if you are choosing the right [scheduler](https://asyncz.tarsild.io/schedulers.md),
178
- [triggers](https://asyncz.tarsild.io/triggers.md), [stores](https://asyncz.tarsild.io/stores.md)
179
- and [executors](https://asyncz.tarsild.io/executors.md)?
154
+ How do you know if you are choosing the right [scheduler](https://asyncz.dymmond.com/schedulers.md),
155
+ [triggers](https://asyncz.dymmond.com/triggers.md), [stores](https://asyncz.dymmond.com/stores.md)
156
+ and [executors](https://asyncz.dymmond.com/executors.md)?
180
157
 
181
158
  Well, Asyncz is intentionally designed for specific systems and already helps you out with some of
182
159
  those questions.
183
160
 
184
- * **Schedulers** - Natively only supports the [AsyncIOScheduler](https://asyncz.tarsild.io/schedulers.md#asyncioscheduler).
161
+ * **Schedulers** - Natively only supports the [AsyncIOScheduler](https://asyncz.dymmond.com/schedulers.md#asyncioscheduler).
185
162
  * **Triggers** - Here it will depend of the periocidity of our tasks. Example:
186
- * [CronTrigger](https://asyncz.tarsild.io/triggers.md#crontrigger) - UNIX like cron and gives you the same feeling as
163
+ * [CronTrigger](https://asyncz.dymmond.com/triggers.md#crontrigger) - UNIX like cron and gives you the same feeling as
187
164
  scheduling a task on a native UNIX like based system.
188
- * [DateTrigger](https://asyncz.tarsild.io/triggers.md#datetrigger) - When you need to run a task once on a specific
165
+ * [DateTrigger](https://asyncz.dymmond.com/triggers.md#datetrigger) - When you need to run a task once on a specific
189
166
  point of time.
190
- * [IntervalTrigger](https://asyncz.tarsild.io/triggers.md#intervaltrigger) - When you need to run tasks in specific
167
+ * [IntervalTrigger](https://asyncz.dymmond.com/triggers.md#intervaltrigger) - When you need to run tasks in specific
191
168
  intervals of time.
192
- * [OrTrigger](https://asyncz.tarsild.io/triggers.md#ortrigger)/[AndTrigger](https://asyncz.tarsild.io/triggers.md#andtrigger) - If you would
169
+ * [OrTrigger](https://asyncz.dymmond.com/triggers.md#ortrigger)/[AndTrigger](https://asyncz.dymmond.com/triggers.md#andtrigger) - If you would
193
170
  like to combine more than one trigger (cron, interval and date) together.
194
- * **Stores** - Natively only supports [redis](https://asyncz.tarsild.io/stores.md#redisstore),
195
- [mongo](https://asyncz.tarsild.io/stores.md#mongodbstore) and [memory](https://asyncz.tarsild.io/stores.md#memorystore).
196
- * **Executors** - Natively only supports [AsyncIOExecutor](https://asyncz.tarsild.io/executors.md#asyncioexecutor),
197
- [ThreadPoolExecutor](https://asyncz.tarsild.io/executors.md#threadpoolexecutor) and
198
- [ProcessPoolExecutor](https://asyncz.tarsild.io/executors.md#processpoolexecutor).
171
+ * **Stores** - Natively only supports [redis](https://asyncz.dymmond.com/stores.md#redisstore),
172
+ [mongo](https://asyncz.dymmond.com/stores.md#mongodbstore) and [memory](https://asyncz.dymmond.com/stores.md#memorystore).
173
+ * **Executors** - Natively only supports [AsyncIOExecutor](https://asyncz.dymmond.com/executors.md#asyncioexecutor),
174
+ [ThreadPoolExecutor](https://asyncz.dymmond.com/executors.md#threadpoolexecutor) and
175
+ [ProcessPoolExecutor](https://asyncz.dymmond.com/executors.md#processpoolexecutor).
199
176
 
200
177
  Sometimes having a lot of options makes the decision making very hard and Asyncz is intentionally
201
178
  designed and driven to simplify and for specific use cases but is not limited to those. In every
@@ -222,7 +199,7 @@ scheduler = AsyncIOScheduler()
222
199
  ```
223
200
 
224
201
  Initialize the rest of the application after the `scheduler` initialisation.
225
- More [details](https://asyncz.tarsild.io/schedulers.md) can be found with more thorough explanations.
202
+ More [details](https://asyncz.dymmond.com/schedulers.md) can be found with more thorough explanations.
226
203
 
227
204
  This is in simple terms and in a nutshell how to start with Asyncz quickly. For more information,
228
205
  details and examples how to leverage Asyncz simply navigate through the documentation and have
@@ -230,11 +207,11 @@ fun 😁🎉.
230
207
 
231
208
  ## ASGI support
232
209
 
233
- Asyncz currently supports the [Esmerald framework](https://asyncz.tarsild.io/contrib/esmerald/index.md)
210
+ Asyncz currently supports the [Esmerald framework](https://asyncz.dymmond.com/contrib/esmerald/index.md)
234
211
  and brings some batteries that are currently used by the framework and leveraging Asyncz.
235
212
 
236
213
  If you wish to have support to any other framework such as FastAPI, Starlite, Starlette or
237
- literally any other, check the [contributing](https://asyncz.tarsild.io/contributing.md) section and see how you can
214
+ literally any other, check the [contributing](https://asyncz.dymmond.com/contributing.md) section and see how you can
238
215
  do it.
239
216
 
240
217
  ## Sponsors
@@ -9,8 +9,8 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="https://github.com/tarsil/asyncz/workflows/Test%20Suite/badge.svg?event=push&branch=main" target="_blank">
13
- <img src="https://github.com/tarsil/asyncz/workflows/Test%20Suite/badge.svg?event=push&branch=main" alt="Test Suite">
12
+ <a href="https://github.com/dymmond/asyncz/workflows/Test%20Suite/badge.svg?event=push&branch=main" target="_blank">
13
+ <img src="https://github.com/dymmond/asyncz/workflows/Test%20Suite/badge.svg?event=push&branch=main" alt="Test Suite">
14
14
  </a>
15
15
 
16
16
  <a href="https://pypi.org/project/asyncz" target="_blank">
@@ -24,9 +24,9 @@
24
24
 
25
25
  ---
26
26
 
27
- **Documentation**: [https://asyncz.tarsild.io](https://asyncz.tarsild.io) 📚
27
+ **Documentation**: [https://asyncz.dymmond.com](https://asyncz.dymmond.com) 📚
28
28
 
29
- **Source Code**: [https://github.com/tarsil/asyncz](https://github.com/tarsil/asyncz)
29
+ **Source Code**: [https://github.com/dymmond/asyncz](https://github.com/dymmond/asyncz)
30
30
 
31
31
  ---
32
32
 
@@ -68,16 +68,16 @@ completely indepent from any framework as well as inside ASGI frameworks such as
68
68
 
69
69
  Asyncz comes with special support to [Esmerald](https://esmerald.dymmond.com) for the simple reason that the author is
70
70
  the same but it can be added more support. If you are interested in adding support to your favourite frameworks then
71
- see the [contributing](https://asyncz.tarsild.io/contributing.md) section.
71
+ see the [contributing](https://asyncz.dymmond.com/contributing.md) section.
72
72
 
73
73
  ## Concepts
74
74
 
75
75
  Like APScheduler, Asyncz also brings four kinds of components:
76
76
 
77
- * [Schedulers](https://asyncz.tarsild.io/schedulers.md)
78
- * [Triggers](https://asyncz.tarsild.io/triggers.md)
79
- * [Stores](https://asyncz.tarsild.io/stores.md)
80
- * [Executors](https://asyncz.tarsild.io/executors.md)
77
+ * [Schedulers](https://asyncz.dymmond.com/schedulers.md)
78
+ * [Triggers](https://asyncz.dymmond.com/triggers.md)
79
+ * [Stores](https://asyncz.dymmond.com/stores.md)
80
+ * [Executors](https://asyncz.dymmond.com/executors.md)
81
81
 
82
82
  ## Requirements
83
83
 
@@ -96,28 +96,28 @@ $ pip install asyncz
96
96
 
97
97
  ## The right decisions
98
98
 
99
- How do you know if you are choosing the right [scheduler](https://asyncz.tarsild.io/schedulers.md),
100
- [triggers](https://asyncz.tarsild.io/triggers.md), [stores](https://asyncz.tarsild.io/stores.md)
101
- and [executors](https://asyncz.tarsild.io/executors.md)?
99
+ How do you know if you are choosing the right [scheduler](https://asyncz.dymmond.com/schedulers.md),
100
+ [triggers](https://asyncz.dymmond.com/triggers.md), [stores](https://asyncz.dymmond.com/stores.md)
101
+ and [executors](https://asyncz.dymmond.com/executors.md)?
102
102
 
103
103
  Well, Asyncz is intentionally designed for specific systems and already helps you out with some of
104
104
  those questions.
105
105
 
106
- * **Schedulers** - Natively only supports the [AsyncIOScheduler](https://asyncz.tarsild.io/schedulers.md#asyncioscheduler).
106
+ * **Schedulers** - Natively only supports the [AsyncIOScheduler](https://asyncz.dymmond.com/schedulers.md#asyncioscheduler).
107
107
  * **Triggers** - Here it will depend of the periocidity of our tasks. Example:
108
- * [CronTrigger](https://asyncz.tarsild.io/triggers.md#crontrigger) - UNIX like cron and gives you the same feeling as
108
+ * [CronTrigger](https://asyncz.dymmond.com/triggers.md#crontrigger) - UNIX like cron and gives you the same feeling as
109
109
  scheduling a task on a native UNIX like based system.
110
- * [DateTrigger](https://asyncz.tarsild.io/triggers.md#datetrigger) - When you need to run a task once on a specific
110
+ * [DateTrigger](https://asyncz.dymmond.com/triggers.md#datetrigger) - When you need to run a task once on a specific
111
111
  point of time.
112
- * [IntervalTrigger](https://asyncz.tarsild.io/triggers.md#intervaltrigger) - When you need to run tasks in specific
112
+ * [IntervalTrigger](https://asyncz.dymmond.com/triggers.md#intervaltrigger) - When you need to run tasks in specific
113
113
  intervals of time.
114
- * [OrTrigger](https://asyncz.tarsild.io/triggers.md#ortrigger)/[AndTrigger](https://asyncz.tarsild.io/triggers.md#andtrigger) - If you would
114
+ * [OrTrigger](https://asyncz.dymmond.com/triggers.md#ortrigger)/[AndTrigger](https://asyncz.dymmond.com/triggers.md#andtrigger) - If you would
115
115
  like to combine more than one trigger (cron, interval and date) together.
116
- * **Stores** - Natively only supports [redis](https://asyncz.tarsild.io/stores.md#redisstore),
117
- [mongo](https://asyncz.tarsild.io/stores.md#mongodbstore) and [memory](https://asyncz.tarsild.io/stores.md#memorystore).
118
- * **Executors** - Natively only supports [AsyncIOExecutor](https://asyncz.tarsild.io/executors.md#asyncioexecutor),
119
- [ThreadPoolExecutor](https://asyncz.tarsild.io/executors.md#threadpoolexecutor) and
120
- [ProcessPoolExecutor](https://asyncz.tarsild.io/executors.md#processpoolexecutor).
116
+ * **Stores** - Natively only supports [redis](https://asyncz.dymmond.com/stores.md#redisstore),
117
+ [mongo](https://asyncz.dymmond.com/stores.md#mongodbstore) and [memory](https://asyncz.dymmond.com/stores.md#memorystore).
118
+ * **Executors** - Natively only supports [AsyncIOExecutor](https://asyncz.dymmond.com/executors.md#asyncioexecutor),
119
+ [ThreadPoolExecutor](https://asyncz.dymmond.com/executors.md#threadpoolexecutor) and
120
+ [ProcessPoolExecutor](https://asyncz.dymmond.com/executors.md#processpoolexecutor).
121
121
 
122
122
  Sometimes having a lot of options makes the decision making very hard and Asyncz is intentionally
123
123
  designed and driven to simplify and for specific use cases but is not limited to those. In every
@@ -144,7 +144,7 @@ scheduler = AsyncIOScheduler()
144
144
  ```
145
145
 
146
146
  Initialize the rest of the application after the `scheduler` initialisation.
147
- More [details](https://asyncz.tarsild.io/schedulers.md) can be found with more thorough explanations.
147
+ More [details](https://asyncz.dymmond.com/schedulers.md) can be found with more thorough explanations.
148
148
 
149
149
  This is in simple terms and in a nutshell how to start with Asyncz quickly. For more information,
150
150
  details and examples how to leverage Asyncz simply navigate through the documentation and have
@@ -152,11 +152,11 @@ fun 😁🎉.
152
152
 
153
153
  ## ASGI support
154
154
 
155
- Asyncz currently supports the [Esmerald framework](https://asyncz.tarsild.io/contrib/esmerald/index.md)
155
+ Asyncz currently supports the [Esmerald framework](https://asyncz.dymmond.com/contrib/esmerald/index.md)
156
156
  and brings some batteries that are currently used by the framework and leveraging Asyncz.
157
157
 
158
158
  If you wish to have support to any other framework such as FastAPI, Starlite, Starlette or
159
- literally any other, check the [contributing](https://asyncz.tarsild.io/contributing.md) section and see how you can
159
+ literally any other, check the [contributing](https://asyncz.dymmond.com/contributing.md) section and see how you can
160
160
  do it.
161
161
 
162
162
  ## Sponsors
@@ -0,0 +1 @@
1
+ __version__ = "0.7.0"
@@ -18,7 +18,6 @@ except ImportError:
18
18
 
19
19
  if TYPE_CHECKING:
20
20
  from esmerald.applications import Esmerald
21
- from pydantic.typing import AnyCallable
22
21
 
23
22
 
24
23
  class EsmeraldScheduler:
@@ -93,14 +92,15 @@ class EsmeraldScheduler:
93
92
  """
94
93
  Registers the scheduler events in the Esmerald application.
95
94
  """
95
+ if app.on_startup is not None:
96
+ app.on_startup.append(self.handler.start)
97
+ else:
98
+ app.on_startup = [self.handler.start]
96
99
 
97
- @app.on_event("startup")
98
- def start_scheduler() -> None:
99
- self.handler.start()
100
-
101
- @app.on_event("shutdown")
102
- def stop_scheduler() -> None:
103
- self.handler.shutdown()
100
+ if app.on_shutdown is not None:
101
+ app.on_shutdown.append(self.handler.shutdown)
102
+ else:
103
+ app.on_shutdown = [self.handler.shutdown]
104
104
 
105
105
  def get_scheduler(
106
106
  self,
@@ -208,7 +208,7 @@ class Task:
208
208
  except Exception as e:
209
209
  raise ImproperlyConfigured(str(e)) from e
210
210
 
211
- def __call__(self, fn: "AnyCallable") -> None:
211
+ def __call__(self, fn: Any) -> None:
212
212
  """
213
213
  Tricking the object into think it's being instantiated by in reality
214
214
  is just returning itself.
@@ -3,12 +3,12 @@ import traceback
3
3
  from abc import ABC, abstractmethod
4
4
  from collections import defaultdict
5
5
  from datetime import datetime, timedelta
6
+ from datetime import timezone as tz
6
7
  from traceback import format_tb
7
8
  from typing import TYPE_CHECKING, Any, List, Optional, Union
8
9
 
9
10
  from loguru import logger
10
11
  from loguru._logger import Logger
11
- from pytz import utc
12
12
 
13
13
  from asyncz.events import TaskExecutionEvent
14
14
  from asyncz.events.constants import TASK_ERROR, TASK_EXECUTED, TASK_MISSED
@@ -97,7 +97,9 @@ class BaseExecutor(BaseStateExtra, ABC):
97
97
  if self.instances[task_id] == 0:
98
98
  del self.instances[task_id]
99
99
 
100
- self.logger.opt(exception=True).error(f"Error running task {task_id}", exc_info=True)
100
+ self.logger.opt(exception=True).error(
101
+ f"Error running task {task_id}", exc_info=True
102
+ )
101
103
 
102
104
 
103
105
  def run_task(
@@ -118,7 +120,7 @@ def run_task(
118
120
  events = []
119
121
  for run_time in run_times:
120
122
  if getattr(task, "mistrigger_grace_time", None) is not None:
121
- difference = datetime.now(utc) - run_time
123
+ difference = datetime.now(tz.utc) - run_time
122
124
  grace_time = timedelta(seconds=task.mistrigger_grace_time)
123
125
  if difference > grace_time:
124
126
  events.append(
@@ -182,7 +184,7 @@ async def run_coroutine_task(
182
184
  events = []
183
185
  for run_time in run_times:
184
186
  if getattr(task, "mistrigger_grace_time", None) is not None:
185
- difference = datetime.now(utc) - run_time
187
+ difference = datetime.now(tz.utc) - run_time
186
188
  grace_time = timedelta(seconds=task.mistrigger_grace_time)
187
189
  if difference > grace_time:
188
190
  events.append(
@@ -1,5 +1,6 @@
1
1
  import sys
2
2
  from abc import ABC, abstractmethod
3
+ from collections.abc import MutableMapping
3
4
  from datetime import datetime, timedelta
4
5
  from importlib import import_module
5
6
  from threading import RLock
@@ -9,6 +10,7 @@ from loguru import logger
9
10
  from tzlocal import get_localzone
10
11
 
11
12
  from asyncz._mapping import AsynczObjectMapping
13
+ from asyncz.enums import PluginInstance, SchedulerState
12
14
  from asyncz.events.base import SchedulerEvent, TaskEvent, TaskSubmissionEvent
13
15
  from asyncz.events.constants import (
14
16
  ALL_EVENTS,
@@ -36,21 +38,21 @@ from asyncz.exceptions import (
36
38
  )
37
39
  from asyncz.executors.base import BaseExecutor
38
40
  from asyncz.executors.pool import ThreadPoolExecutor
41
+ from asyncz.schedulers.datastructures import TaskDefaultStruct
42
+ from asyncz.state import BaseStateExtra
39
43
  from asyncz.stores.base import BaseStore
40
44
  from asyncz.stores.memory import MemoryStore
41
45
  from asyncz.tasks import Task
42
46
  from asyncz.triggers.base import BaseTrigger
43
47
  from asyncz.typing import undefined
44
- from asyncz.utils import TIMEOUT_MAX, maybe_ref, timedelta_seconds, to_bool, to_int, to_timezone
45
-
46
- try:
47
- from collections.abc import MutableMapping
48
- except ImportError:
49
- from collections.abc import MutableMapping
50
-
51
- from asyncz.enums import PluginInstance, SchedulerState
52
- from asyncz.schedulers.datastructures import TaskDefaultStruct
53
- from asyncz.state import BaseStateExtra
48
+ from asyncz.utils import (
49
+ TIMEOUT_MAX,
50
+ maybe_ref,
51
+ timedelta_seconds,
52
+ to_bool,
53
+ to_int,
54
+ to_timezone,
55
+ )
54
56
 
55
57
  DictAny = Dict[Any, Any]
56
58
 
@@ -179,7 +181,9 @@ class BaseScheduler(BaseStateExtra, ABC):
179
181
  self.real_add_task(task, store_alias, replace_existing)
180
182
  del self.pending_tasks[:]
181
183
 
182
- self.state = SchedulerState.STATE_PAUSED if paused else SchedulerState.STATE_RUNNING
184
+ self.state = (
185
+ SchedulerState.STATE_PAUSED if paused else SchedulerState.STATE_RUNNING
186
+ )
183
187
  self.logger.info("Scheduler started.")
184
188
  self.dispatch_event(SchedulerEvent(code=SCHEDULER_START))
185
189
 
@@ -281,7 +285,9 @@ class BaseScheduler(BaseStateExtra, ABC):
281
285
 
282
286
  self.dispatch_event(SchedulerEvent(code=EXECUTOR_REMOVED, alias=alias))
283
287
 
284
- def add_store(self, store: "StoreType", alias: str = "default", **store_options: Any):
288
+ def add_store(
289
+ self, store: "StoreType", alias: str = "default", **store_options: Any
290
+ ):
285
291
  """
286
292
  Adds a task store to this scheduler.
287
293
 
@@ -418,7 +424,9 @@ class BaseScheduler(BaseStateExtra, ABC):
418
424
  "max_instances": max_instances,
419
425
  "next_run_time": next_run_time,
420
426
  }
421
- task_kwargs = {key: value for key, value in task_struct.items() if value is not undefined}
427
+ task_kwargs = {
428
+ key: value for key, value in task_struct.items() if value is not undefined
429
+ }
422
430
  task = Task(self, **task_kwargs)
423
431
 
424
432
  with self.store_lock:
@@ -532,9 +540,13 @@ class BaseScheduler(BaseStateExtra, ABC):
532
540
  trigger = self.create_trigger(trigger, trigger_args)
533
541
  now = datetime.now(self.timezone)
534
542
  next_run_time = trigger.get_next_trigger_time(None, now)
535
- return self.update_task(task_id, store, trigger=trigger, next_run_time=next_run_time)
543
+ return self.update_task(
544
+ task_id, store, trigger=trigger, next_run_time=next_run_time
545
+ )
536
546
 
537
- def pause_task(self, task_id: Union[int, str], store: Optional[str] = None) -> "TaskType":
547
+ def pause_task(
548
+ self, task_id: Union[int, str], store: Optional[str] = None
549
+ ) -> "TaskType":
538
550
  """
539
551
  Causes the given task not to be executed until it is explicitly resumed.
540
552
 
@@ -588,7 +600,9 @@ class BaseScheduler(BaseStateExtra, ABC):
588
600
 
589
601
  return tasks
590
602
 
591
- def get_task(self, task_id: str, store: Optional[str] = None) -> Union["TaskType", None]:
603
+ def get_task(
604
+ self, task_id: str, store: Optional[str] = None
605
+ ) -> Union["TaskType", None]:
592
606
  """
593
607
  Returms the Task that matches the given task_id.
594
608
 
@@ -827,7 +841,9 @@ class BaseScheduler(BaseStateExtra, ABC):
827
841
  # Calculate the next run time if there is none defined
828
842
  if not getattr(task, "next_run_time", None):
829
843
  now = datetime.now(self.timezone)
830
- replacements["next_run_time"] = task.trigger.get_next_trigger_time(None, now)
844
+ replacements["next_run_time"] = task.trigger.get_next_trigger_time(
845
+ None, now
846
+ )
831
847
 
832
848
  # Apply replacements
833
849
  task._update(**replacements)
@@ -860,7 +876,9 @@ class BaseScheduler(BaseStateExtra, ABC):
860
876
  try:
861
877
  module_path, class_name = module_name.rsplit(":", 1)
862
878
  except ValueError as err:
863
- raise ImportError("%s doesn't look like a module path" % module_name) from err
879
+ raise ImportError(
880
+ "%s doesn't look like a module path" % module_name
881
+ ) from err
864
882
 
865
883
  module = import_module(module_path)
866
884
 
@@ -892,7 +910,9 @@ class BaseScheduler(BaseStateExtra, ABC):
892
910
  f"The {format(_type)} entry point does not point to a {format(_type)} class."
893
911
  ) from None
894
912
  else:
895
- raise LookupError(f"No {_type} by the name '{alias}' was found.") from None
913
+ raise LookupError(
914
+ f"No {_type} by the name '{alias}' was found."
915
+ ) from None
896
916
 
897
917
  return plugin_cls(**constructor_args)
898
918
 
@@ -944,7 +964,9 @@ class BaseScheduler(BaseStateExtra, ABC):
944
964
  self.logger.warning(
945
965
  f"Error getting due tasks from the store {store_alias}: {e}."
946
966
  )
947
- retry_wakeup_time = now + timedelta(seconds=self.store_retry_interval)
967
+ retry_wakeup_time = now + timedelta(
968
+ seconds=self.store_retry_interval
969
+ )
948
970
  if not next_wakeup_time or next_wakeup_time > retry_wakeup_time:
949
971
  next_wakeup_time = retry_wakeup_time
950
972
  continue
@@ -960,7 +982,9 @@ class BaseScheduler(BaseStateExtra, ABC):
960
982
  continue
961
983
 
962
984
  run_times = task.get_run_times(now)
963
- run_times = run_times[-1:] if run_times and task.coalesce else run_times
985
+ run_times = (
986
+ run_times[-1:] if run_times and task.coalesce else run_times
987
+ )
964
988
 
965
989
  if run_times:
966
990
  try:
@@ -990,7 +1014,9 @@ class BaseScheduler(BaseStateExtra, ABC):
990
1014
  )
991
1015
  events.append(event)
992
1016
 
993
- next_run = task.trigger.get_next_trigger_time(run_times[-1], now)
1017
+ next_run = task.trigger.get_next_trigger_time(
1018
+ run_times[-1], now
1019
+ )
994
1020
  if next_run:
995
1021
  task._update(next_run_time=next_run)
996
1022
  store.update_task(task)
@@ -1013,7 +1039,9 @@ class BaseScheduler(BaseStateExtra, ABC):
1013
1039
  wait_seconds = None
1014
1040
  self.logger.debug("No tasks. Waiting until task is added.")
1015
1041
  else:
1016
- wait_seconds = min(max(timedelta_seconds(next_wakeup_time - now), 0), TIMEOUT_MAX)
1042
+ wait_seconds = min(
1043
+ max(timedelta_seconds(next_wakeup_time - now), 0), TIMEOUT_MAX
1044
+ )
1017
1045
  self.logger.debug(
1018
1046
  f"Next wakeup is due at {next_wakeup_time} (in {wait_seconds} seconds)."
1019
1047
  )
@@ -1,9 +1,8 @@
1
1
  import pickle
2
2
  from datetime import datetime
3
+ from datetime import timezone as tz
3
4
  from typing import Any, List, Optional, Union
4
5
 
5
- from pytz import utc
6
-
7
6
  from asyncz.exceptions import AsynczException, ConflictIdError, TaskLookupError
8
7
  from asyncz.stores.base import BaseStore
9
8
  from asyncz.tasks import Task
@@ -79,7 +78,9 @@ class RedisStore(BaseStore):
79
78
  try:
80
79
  tasks.append(self.rebuild_task(state))
81
80
  except BaseException:
82
- self.logger.exception(f"Unable to restore task '{task_id}'. Removing it...")
81
+ self.logger.exception(
82
+ f"Unable to restore task '{task_id}'. Removing it..."
83
+ )
83
84
  failed_task_ids.append(task_id)
84
85
 
85
86
  if failed_task_ids:
@@ -98,7 +99,7 @@ class RedisStore(BaseStore):
98
99
  def get_all_tasks(self) -> List["TaskType"]:
99
100
  states = self.redis.hgetall(self.tasks_key)
100
101
  tasks = self.rebuild_tasks(states.items())
101
- paused_sort_key = datetime(9999, 12, 31, tzinfo=utc)
102
+ paused_sort_key = datetime(9999, 12, 31, tzinfo=tz.utc)
102
103
  return sorted(tasks, key=lambda task: task.next_run_time or paused_sort_key)
103
104
 
104
105
  def add_task(self, task: "TaskType"):
@@ -108,12 +109,15 @@ class RedisStore(BaseStore):
108
109
  with self.redis.pipeline() as pipe:
109
110
  pipe.multi()
110
111
  pipe.hset(
111
- self.tasks_key, task.id, pickle.dumps(task.__getstate__(), self.pickle_protocol)
112
+ self.tasks_key,
113
+ task.id,
114
+ pickle.dumps(task.__getstate__(), self.pickle_protocol),
112
115
  )
113
116
 
114
117
  if task.next_run_time:
115
118
  pipe.zadd(
116
- self.run_times_key, {task.id: datetime_to_utc_timestamp(task.next_run_time)}
119
+ self.run_times_key,
120
+ {task.id: datetime_to_utc_timestamp(task.next_run_time)},
117
121
  )
118
122
  pipe.execute()
119
123
 
@@ -123,11 +127,14 @@ class RedisStore(BaseStore):
123
127
 
124
128
  with self.redis.pipeline() as pipe:
125
129
  pipe.hset(
126
- self.tasks_key, task.id, pickle.dumps(task.__getstate__(), self.pickle_protocol)
130
+ self.tasks_key,
131
+ task.id,
132
+ pickle.dumps(task.__getstate__(), self.pickle_protocol),
127
133
  )
128
134
  if task.next_run_time:
129
135
  pipe.zadd(
130
- self.run_times_key, {task.id: datetime_to_utc_timestamp(task.next_run_time)}
136
+ self.run_times_key,
137
+ {task.id: datetime_to_utc_timestamp(task.next_run_time)},
131
138
  )
132
139
  else:
133
140
  pipe.zrem(self.run_times_key, task.id)
@@ -6,7 +6,13 @@ from tzlocal import get_localzone
6
6
 
7
7
  from asyncz.datastructures import IntervalState
8
8
  from asyncz.triggers.base import BaseTrigger
9
- from asyncz.utils import datetime_repr, normalize, timedelta_seconds, to_datetime, to_timezone
9
+ from asyncz.utils import (
10
+ datetime_repr,
11
+ normalize,
12
+ timedelta_seconds,
13
+ to_datetime,
14
+ to_timezone,
15
+ )
10
16
 
11
17
 
12
18
  class IntervalTrigger(BaseTrigger):
@@ -73,7 +79,9 @@ class IntervalTrigger(BaseTrigger):
73
79
  next_trigger_time = self.start_at
74
80
  else:
75
81
  time_difference_seconds = timedelta_seconds(now - self.start_at)
76
- next_interval_number = int(ceil(time_difference_seconds / self.interval_size))
82
+ next_interval_number = int(
83
+ ceil(time_difference_seconds / self.interval_size)
84
+ )
77
85
  next_trigger_time = self.start_at + self.interval * next_interval_number
78
86
 
79
87
  if self.jitter is not None:
@@ -98,7 +106,10 @@ class IntervalTrigger(BaseTrigger):
98
106
  return f"interval[{self.interval}]"
99
107
 
100
108
  def __repr__(self) -> str:
101
- options = ["interval=%r" % self.interval, "start_at=%r" % datetime_repr(self.start_at)]
109
+ options = [
110
+ "interval=%r" % self.interval,
111
+ "start_at=%r" % datetime_repr(self.start_at),
112
+ ]
102
113
  if self.end_at:
103
114
  options.append("end_at=%r" % datetime_repr(self.end_at))
104
115
  if self.jitter:
@@ -3,17 +3,20 @@ import re
3
3
  from asyncio import iscoroutinefunction
4
4
  from calendar import timegm
5
5
  from datetime import date, datetime, time, timedelta, tzinfo
6
+ from datetime import timezone as dttz
6
7
  from functools import partial
7
8
  from typing import Any, Callable, Union
8
9
 
9
- from pytz import FixedOffset, timezone, utc
10
-
11
10
  from asyncz.exceptions import AsynczException, AsynczLookupError
12
11
 
13
12
  try:
14
13
  from threading import TIMEOUT_MAX
15
14
  except ImportError:
16
15
  TIMEOUT_MAX = 4294967
16
+ try:
17
+ from zoneinfo import ZoneInfo
18
+ except ImportError:
19
+ from backports.zoneinfo import ZoneInfo
17
20
 
18
21
  BOOL_VALIDATION = {
19
22
  "true": ["true", "yes", "on", "y", "t", "1", True],
@@ -61,22 +64,13 @@ def to_bool(value: str) -> bool:
61
64
  return False
62
65
 
63
66
 
64
- def to_timezone(value: Any) -> timezone:
67
+ def to_timezone(value: Any) -> tzinfo:
65
68
  """
66
69
  Converts a value to timezone object.
67
70
  """
68
71
  if isinstance(value, str):
69
- return timezone(value)
72
+ return ZoneInfo(value)
70
73
  if isinstance(value, tzinfo):
71
- if not hasattr(value, "localize") or not hasattr(value, "normalize"):
72
- raise TypeError("Only timezones from the pytz library are supported.")
73
- if value.tzname(None) == "local":
74
- raise ValueError(
75
- "Unable to determine the name of the local timezone -- you must explicitly "
76
- "specify the name of the local timezone. Please refrain from using timezones like "
77
- "BST to prevent problems with daylight saving time. Instead, use a locale based "
78
- "timezone name (such as Europe/London)."
79
- )
80
74
  return value
81
75
  if value is not None:
82
76
  raise TypeError("Expected tzinfo, got %s instead" % value.__class__.__name__)
@@ -109,11 +103,11 @@ def to_datetime(
109
103
  tzname = values.pop("timezone")
110
104
 
111
105
  if tzname == "Z":
112
- tz = utc
106
+ tz = dttz.utc
113
107
  elif tzname:
114
108
  hours, minutes = (int(x) for x in tzname[1:].split(":"))
115
109
  sign = 1 if tzname[0] == "+" else -1
116
- tz = FixedOffset(sign * (hours * 60 + minutes))
110
+ tz = dttz(sign * timedelta(hours=hours, minutes=minutes))
117
111
 
118
112
  values = {k: int(v or 0) for k, v in values.items()}
119
113
  _datetime = datetime(**values) # type: ignore
@@ -132,7 +126,7 @@ def to_datetime(
132
126
  )
133
127
 
134
128
  if isinstance(tz, str):
135
- tz = timezone(tz)
129
+ tz = ZoneInfo(tz)
136
130
 
137
131
  return localize(_datetime, tz)
138
132
 
@@ -150,7 +144,7 @@ def utc_timestamp_to_datetime(timestamp: Union[int, float]) -> datetime:
150
144
  Converts the given timestamp to a datetime instance.
151
145
  """
152
146
  if timestamp is not None:
153
- return datetime.fromtimestamp(timestamp, utc)
147
+ return datetime.fromtimestamp(timestamp, dttz.utc)
154
148
 
155
149
 
156
150
  def timedelta_seconds(delta: Any) -> Any:
@@ -196,7 +190,9 @@ def get_callable_name(func: Any) -> Any:
196
190
  return func.__name__
197
191
  return func.__class__.__name__
198
192
 
199
- raise TypeError("Unable to determine a name for %r -- maybe it is not a callable?" % func)
193
+ raise TypeError(
194
+ "Unable to determine a name for %r -- maybe it is not a callable?" % func
195
+ )
200
196
 
201
197
 
202
198
  def obj_to_ref(obj: Any) -> str:
@@ -320,7 +316,8 @@ def check_callable_args(func: Callable[..., Any], args: Any, kwargs: Any) -> Non
320
316
 
321
317
  if unsatisfied_args:
322
318
  raise ValueError(
323
- "The following arguments have not been supplied: %s" % ", ".join(unsatisfied_args)
319
+ "The following arguments have not been supplied: %s"
320
+ % ", ".join(unsatisfied_args)
324
321
  )
325
322
 
326
323
  if unsatisfied_kwargs:
@@ -332,7 +329,8 @@ def check_callable_args(func: Callable[..., Any], args: Any, kwargs: Any) -> Non
332
329
  if not has_varargs and unmatched_args:
333
330
  raise ValueError(
334
331
  "The list of positional arguments is longer than the target callable can handle "
335
- "(allowed: %d, given in args: %d)" % (len(args) - len(unmatched_args), len(args))
332
+ "(allowed: %d, given in args: %d)"
333
+ % (len(args) - len(unmatched_args), len(args))
336
334
  )
337
335
 
338
336
  if not has_var_kwargs and unmatched_kwargs:
@@ -39,11 +39,10 @@ classifiers = [
39
39
  "Topic :: Internet :: WWW/HTTP",
40
40
  ]
41
41
  dependencies = [
42
- "asyncio>=3.4.3,<4.0.0",
43
42
  "loguru>=0.7.0,<0.8.0",
44
43
  "pydantic>=2.5.3,<3.0.0",
45
- "pytz>=2022.6",
46
- "tzlocal>=4.2,<5.0",
44
+ "tzlocal>=4.0,<6.0",
45
+ 'backports.zoneinfo;python_version<"3.9"',
47
46
  ]
48
47
  keywords = [
49
48
  "api",
@@ -66,39 +65,47 @@ keywords = [
66
65
  ]
67
66
 
68
67
  [project.urls]
69
- Homepage = "https://github.com/tarsil/asyncz"
70
- Documentation = "https://asyncz.tarsild.io/"
71
- Changelog = "https://asyncz.tarsild.io/release-notes/"
68
+ Homepage = "https://github.com/dymmond/asyncz"
69
+ Documentation = "https://asyncz.dymmond.com/"
70
+ Changelog = "https://asyncz.dymmond.com/release-notes/"
72
71
  Funding = "https://github.com/sponsors/tarsil"
73
- Source = "https://github.com/tarsil/asyncz"
72
+ Source = "https://github.com/dymmond/asyncz"
73
+
74
+
75
+ [tool.hatch.envs.default]
76
+ dependencies = ["ruff", "pre-commit>=2.17.0,<3.0.0", "twine"]
74
77
 
75
78
  [project.optional-dependencies]
76
- test = [
77
- # "esmerald==0.4.2",
78
- "mock>=4.0.3",
79
+ testing = [
79
80
  "pymongo>=4.3.3,<5.0.0",
80
81
  "pytest>=7.1.3,<9.0.0",
81
82
  "pytest-cov >=2.12.0,<6.0.0",
82
83
  "pytest-asyncio >=0.19.0,<1.0.0",
83
84
  "pytest-loguru>=0.2.0,<1",
84
85
  "redis>=4.4.0,<6.0.0",
85
- "requests >=2.27.0,<3.0.0",
86
- "ruff>=0.0.256,<1.0.0",
87
- ]
88
-
89
- dev = [
90
- "autoflake>=1.4.0,<3.0.0",
91
- "black==24.4.2",
92
- "flake8>=3.8.3,<8.0.0",
93
- "ipdb>=0.13.13",
94
- "pdbpp",
95
- "isort>=5.0.6,<6.0.0",
96
86
  "mypy>=0.982,<2.0.0",
97
- "pre-commit>=2.17.0,<3.0.0",
98
- "watchfiles>=0.16.1,<0.22.0",
87
+ "esmerald",
88
+ "pytz>=2022.6",
99
89
  ]
100
90
 
101
- doc = [
91
+ [tool.hatch.envs.default.scripts]
92
+ clean_pyc = "find . -type f -name \"*.pyc\" -delete"
93
+ clean_pycache = "find . -type d -name \"*__pycache__*\" -delete"
94
+ lint = "ruff check --fix --line-length 99 asyncz tests docs_src {args}"
95
+ build_with_check = "hatch build; twine check dist/*"
96
+
97
+ [tool.hatch.envs.test]
98
+ dependencies = ["asyncz[testing]"]
99
+
100
+ [tool.hatch.envs.test.scripts]
101
+ # needs docker services running
102
+ test = "pytest --disable-pytest-warnings -s -vv {args}"
103
+ coverage = "pytest --cov=asyncz --cov=tests --cov-report=term-missing:skip-covered --cov-report=html tests {args}"
104
+ check_types = "mypy -p asyncz"
105
+
106
+
107
+ [tool.hatch.envs.docs]
108
+ dependencies = [
102
109
  "mkautodoc >=0.2.0,<0.3.0",
103
110
  "mkdocs >=1.1.2,<2.0.0",
104
111
  "mkdocs-material >=9.0.13,<10.0.0",
@@ -107,16 +114,13 @@ doc = [
107
114
  "mkdocstrings>=0.20.0,<0.30.0",
108
115
  "pyyaml >=6.0,<7.0.0",
109
116
  ]
110
-
111
- all = ["asyncio>=3.4.3,<4.0.0", "pytz>=2022.6", "tzlocal>=4.2,<5.0"]
117
+ [tool.hatch.envs.docs.scripts]
118
+ build = "mkdocs build"
119
+ serve = "mkdocs serve --dev-addr localhost:8000"
112
120
 
113
121
  [tool.hatch.version]
114
122
  path = "asyncz/__init__.py"
115
123
 
116
- [tool.isort]
117
- profile = "black"
118
- known_third_party = ["asyncz", "pydantic", "starlette"]
119
-
120
124
  [tool.mypy]
121
125
  warn_unused_configs = true
122
126
  warn_unreachable = true
@@ -137,6 +141,9 @@ ignore = ["E501", "B008", "C901", "B026"]
137
141
 
138
142
  exclude = ["docs_src/*"]
139
143
 
144
+ [tool.ruff.lint.isort]
145
+ known-third-party = ["esmerald", "pydantic", "starlette"]
146
+
140
147
  [[tool.mypy.overrides]]
141
148
  module = "asyncz.tests.*"
142
149
  ignore_missing_imports = true
@@ -1 +0,0 @@
1
- __version__ = "0.6.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