appier 1.34.1__py2.py3-none-any.whl → 1.34.3__py2.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.
appier/asgi.py CHANGED
@@ -135,11 +135,13 @@ class ASGIApp(object):
135
135
  event = await receive()
136
136
 
137
137
  if event["type"] == "lifespan.startup":
138
- self.start()
138
+ if not self.is_started():
139
+ self.start()
139
140
  await send(dict(type="lifespan.startup.complete"))
140
141
 
141
142
  elif event["type"] == "lifespan.shutdown":
142
- self.stop()
143
+ if not self.is_stopped():
144
+ self.stop()
143
145
  await send(dict(type="lifespan.shutdown.complete"))
144
146
  running = False
145
147
 
appier/base.py CHANGED
@@ -94,7 +94,7 @@ NAME = "appier"
94
94
  """ The name to be used to describe the framework while working
95
95
  on its own environment, this is just a descriptive value """
96
96
 
97
- VERSION = "1.34.1"
97
+ VERSION = "1.34.3"
98
98
  """ The version of the framework that is currently installed
99
99
  this value may be used for debugging/diagnostic purposes """
100
100
 
@@ -945,6 +945,7 @@ class App(
945
945
  self.host = host
946
946
  self.port = port
947
947
  self.ssl = ssl
948
+
948
949
  self.start()
949
950
 
950
951
  method = getattr(self, "serve_" + server)
@@ -2327,7 +2328,7 @@ class App(
2327
2328
  thread.daemon = True
2328
2329
  thread.start()
2329
2330
 
2330
- def cron(self, job, cron):
2331
+ def cron(self, job, cron, id=None, description=None):
2331
2332
  """
2332
2333
  Schedule the provided method for regular execution using
2333
2334
  the provided Cron like string.
@@ -2341,6 +2342,11 @@ class App(
2341
2342
  :type cron: String/SchedulerDate
2342
2343
  :param cron: The cron like string that is going to be used to
2343
2344
  define the execution time of the provided method.
2345
+ :type id: String
2346
+ :param id: The unique identifier for the task to be created.
2347
+ :type description: String
2348
+ :param description: The description for the task to be created
2349
+ that describes the goal of the task.
2344
2350
  :rtype: SchedulerTask
2345
2351
  :return: The task that has been scheduled for execution at the
2346
2352
  provided time.
@@ -2349,7 +2355,7 @@ class App(
2349
2355
  if self._cron == None:
2350
2356
  self._cron = scheduler.CronScheduler(self)
2351
2357
  self._cron.start()
2352
- return self._cron.schedule(job, cron)
2358
+ return self._cron.schedule(job, cron, id=id, description=description)
2353
2359
 
2354
2360
  def chunks(self, data, size=32768):
2355
2361
  for index in range(0, len(data), size):
@@ -3649,6 +3655,15 @@ class App(
3649
3655
  return False
3650
3656
  return self.level < logging.INFO
3651
3657
 
3658
+ def is_running(self):
3659
+ return self.status == RUNNING
3660
+
3661
+ def is_started(self):
3662
+ return self.is_running()
3663
+
3664
+ def is_stopped(self):
3665
+ return self.status == STOPPED
3666
+
3652
3667
  def serialize(self, value):
3653
3668
  if value in legacy.STRINGS:
3654
3669
  return value
appier/base.pyi CHANGED
@@ -59,6 +59,14 @@ class App:
59
59
  **kwargs
60
60
  ) -> str: ...
61
61
  def cron(self, job: JobFunction, cron: Cron) -> SchedulerTask: ...
62
+ def is_loaded(self) -> bool: ...
63
+ def is_parent(self) -> bool: ...
64
+ def is_child(self) -> bool: ...
65
+ def is_main(self) -> bool: ...
66
+ def is_devel(self) -> bool: ...
67
+ def is_running(self) -> bool: ...
68
+ def is_started(self) -> bool: ...
69
+ def is_stopped(self) -> bool: ...
62
70
  def url_for(
63
71
  self,
64
72
  type: str,
appier/scheduler.py CHANGED
@@ -29,6 +29,7 @@ __license__ = "Apache License, Version 2.0"
29
29
  """ The license for the module """
30
30
 
31
31
  import time
32
+ import uuid
32
33
  import heapq
33
34
  import datetime
34
35
  import logging
@@ -143,7 +144,7 @@ class CronScheduler(Scheduler):
143
144
 
144
145
  self.timeout = max(0, timestamp - current_ts())
145
146
 
146
- def schedule(self, job, cron, now=None):
147
+ def schedule(self, job, cron, id=None, description=None, now=None):
147
148
  """
148
149
  Schedules the provided job function for execution according
149
150
  to the provided cron string.
@@ -156,13 +157,18 @@ class CronScheduler(Scheduler):
156
157
  :param job: The function to be executed as the job.
157
158
  :type cron: String/SchedulerDate
158
159
  :param cron: The cron like string defining the schedule.
160
+ :type id: String
161
+ :param id: The unique identifier for the task to be created.
162
+ :type description: String
163
+ :param description: The description for the task to be created
164
+ that describes the goal of the task.
159
165
  :type now: datetime
160
166
  :param now: Optional time reference for the job scheduling.
161
167
  :rtype: SchedulerTask
162
168
  :return: The task object that was created for the job.
163
169
  """
164
170
 
165
- task = SchedulerTask(job, cron)
171
+ task = SchedulerTask(job, cron, id=id, description=description)
166
172
  heapq.heappush(self._tasks, (task.next_timestamp(now=now), task))
167
173
  self.awake()
168
174
  return task
@@ -181,16 +187,18 @@ class CronScheduler(Scheduler):
181
187
 
182
188
  class SchedulerTask(object):
183
189
 
184
- def __init__(self, job, cron):
190
+ def __init__(self, job, cron, id=None, description=None):
185
191
  self.job = job
186
192
  self.date = SchedulerDate.from_cron(cron)
193
+ self.id = str(uuid.uuid4()) if id == None else id
194
+ self.description = description
187
195
  self._enabled = True
188
196
 
189
197
  def __repr__(self):
190
- return "<SchedulerTask: %s, %s>" % (self.job, self.date)
198
+ return "<SchedulerTask: [%s] %s, %s>" % (self.id[:-12], self.job, self.date)
191
199
 
192
200
  def __str__(self):
193
- return "<SchedulerTask: %s, %s>" % (self.job, self.date)
201
+ return "<SchedulerTask: [%s] %s, %s>" % (self.id[:-12], self.job, self.date)
194
202
 
195
203
  def __eq__(self, other):
196
204
  if isinstance(other, self.__class__):
@@ -216,6 +224,10 @@ class SchedulerTask(object):
216
224
  def enabled(self):
217
225
  return self._enabled
218
226
 
227
+ @property
228
+ def cron(self):
229
+ return self.date.into_cron()
230
+
219
231
 
220
232
  class SchedulerDate(object):
221
233
 
@@ -229,10 +241,10 @@ class SchedulerDate(object):
229
241
  self.days_of_week = self._parse_field(days_of_week, 0, 6)
230
242
 
231
243
  def __repr__(self):
232
- return "<SchedulerDate: %s>" % self.next_run()
244
+ return "<SchedulerDate: %s, %s>" % (self.into_cron(), self.next_run())
233
245
 
234
246
  def __str__(self):
235
- return "<SchedulerDate: %s>" % self.next_run()
247
+ return "<SchedulerDate: %s, %s>" % (self.into_cron(), self.next_run())
236
248
 
237
249
  @classmethod
238
250
  def from_cron(cls, cron):
@@ -241,6 +253,17 @@ class SchedulerDate(object):
241
253
  values = (value.strip().split(",") for value in cron.split(" "))
242
254
  return cls(*values)
243
255
 
256
+ def into_cron(self):
257
+ return " ".join(
258
+ [
259
+ self._into_cron_field(self.minutes, 0, 59),
260
+ self._into_cron_field(self.hours, 0, 23),
261
+ self._into_cron_field(self.days_of_month, 1, 31),
262
+ self._into_cron_field(self.months, 1, 12),
263
+ self._into_cron_field(self.days_of_week, 0, 6),
264
+ ]
265
+ )
266
+
244
267
  def next_timestamp(self, now=None):
245
268
  date = self.next_run(now=now)
246
269
  return legacy.to_timestamp(date)
@@ -301,6 +324,11 @@ class SchedulerDate(object):
301
324
  else:
302
325
  return set((int(field),))
303
326
 
327
+ def _into_cron_field(self, field, min_value, max_value):
328
+ if field == set(range(min_value, max_value + 1)):
329
+ return "*"
330
+ return ",".join(str(v) for v in sorted(field))
331
+
304
332
 
305
333
  class Cron(object):
306
334
  pass
appier/scheduler.pyi CHANGED
@@ -29,7 +29,12 @@ class CronScheduler(Scheduler):
29
29
  def __init__(self, owner: App | None, timeout: float = ..., daemon: bool = ...): ...
30
30
  def tick(self, now_ts: float | None = ...): ...
31
31
  def schedule(
32
- self, job: JobFunction, cron: Cron, now: datetime | None = ...
32
+ self,
33
+ job: JobFunction,
34
+ cron: Cron,
35
+ id: str | None = ...,
36
+ description: str | None = ...,
37
+ now: datetime | None = ...,
33
38
  ) -> SchedulerTask: ...
34
39
  def next_run(self) -> datetime | None: ...
35
40
  def next_timestamp(self) -> float | None: ...
@@ -38,13 +43,21 @@ class SchedulerTask(object):
38
43
  job: JobFunction
39
44
  date: SchedulerDate
40
45
 
41
- def __init__(self, job: JobFunction, cron: Cron): ...
46
+ def __init__(
47
+ self,
48
+ job: JobFunction,
49
+ cron: Cron,
50
+ id: str | None = ...,
51
+ description: str | None = ...,
52
+ ): ...
42
53
  def enable(self): ...
43
54
  def disable(self): ...
44
55
  def next_run(self, now: datetime | None = ...) -> datetime: ...
45
56
  def next_timestamp(self, now: datetime | None = ...) -> float: ...
46
57
  @property
47
58
  def enabled(self) -> bool: ...
59
+ @property
60
+ def cron(self) -> str: ...
48
61
 
49
62
  class SchedulerDate(object):
50
63
  minutes: set[int]
@@ -63,8 +76,12 @@ class SchedulerDate(object):
63
76
  ): ...
64
77
  @classmethod
65
78
  def from_cron(cls, cron: Cron) -> SchedulerDate: ...
79
+ def into_cron(self) -> str: ...
66
80
  def next_timestamp(self, now: datetime | None = None) -> float: ...
67
81
  def next_run(self, now: datetime | None = None) -> datetime: ...
68
82
  def _parse_field(
69
83
  self, field: CronField, min_value: int, max_value: int
70
84
  ) -> set[int]: ...
85
+ def _into_cron_field(
86
+ self, field: set[int], min_value: int, max_value: int
87
+ ) -> str: ...
appier/test/scheduler.py CHANGED
@@ -164,6 +164,12 @@ class CronSchedulerTest(unittest.TestCase):
164
164
 
165
165
  class SchedulerDateTest(unittest.TestCase):
166
166
 
167
+ def test_repr(self):
168
+ date = appier.SchedulerDate.from_cron("11")
169
+ self.assertEqual(
170
+ repr(date), "<SchedulerDate: 11 * * * *, %s>" % str(date.next_run())
171
+ )
172
+
167
173
  def test_from_cron(self):
168
174
  date = appier.SchedulerDate.from_cron("11")
169
175
  self.assertEqual(date.minutes, set((11,)))
@@ -172,6 +178,25 @@ class SchedulerDateTest(unittest.TestCase):
172
178
  self.assertEqual(date.months, set(range(1, 13)))
173
179
  self.assertEqual(date.days_of_week, set(range(0, 7)))
174
180
 
181
+ def test_into_cron(self):
182
+ date = appier.SchedulerDate.from_cron("11")
183
+ self.assertEqual(date.into_cron(), "11 * * * *")
184
+
185
+ date = appier.SchedulerDate.from_cron("11 3")
186
+ self.assertEqual(date.into_cron(), "11 3 * * *")
187
+
188
+ date = appier.SchedulerDate.from_cron("11 3 10")
189
+ self.assertEqual(date.into_cron(), "11 3 10 * *")
190
+
191
+ date = appier.SchedulerDate.from_cron("11 3 10 5")
192
+ self.assertEqual(date.into_cron(), "11 3 10 5 *")
193
+
194
+ date = appier.SchedulerDate.from_cron("11 3 10 5 2")
195
+ self.assertEqual(date.into_cron(), "11 3 10 5 2")
196
+
197
+ date = appier.SchedulerDate.from_cron("* 3 10 5 2")
198
+ self.assertEqual(date.into_cron(), "* 3 10 5 2")
199
+
175
200
  def test_next_run(self):
176
201
  date = appier.SchedulerDate.from_cron("11")
177
202
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: appier
3
- Version: 1.34.1
3
+ Version: 1.34.3
4
4
  Summary: Appier Framework
5
5
  Home-page: http://appier.hive.pt
6
6
  Author: Hive Solutions Lda.
@@ -1,13 +1,13 @@
1
1
  appier/__init__.py,sha256=-Xd1j5egjwXV6yoKAkcPVWIZEnpPK_SJTTmQjDrW93E,9413
2
2
  appier/amqp.py,sha256=etYxUlfaK27Og_9FJ6qCgNLSYhnz9XgVhIhSmD2ITW4,3852
3
3
  appier/api.py,sha256=s5ZJs0tgR3wktAhLZ7Vuhbd_4lWPsGJSEx0ptkqLxvM,14369
4
- appier/asgi.py,sha256=sKQH9K_QEDPbBSk3AWcvHo7Lfl5yawIo6NcM0z1qQCw,12100
4
+ appier/asgi.py,sha256=XqlXJ5QEyWyZBqFU9ubEx-jNehicihKcACR4Hy2A2nE,12194
5
5
  appier/async_neo.py,sha256=gQpyT1-nZE6Uynh5FEmFl5kfXkxChdUsgiKgwlaNw5E,5446
6
6
  appier/async_old.py,sha256=m3BFqHVPCRuIZ9L2sGYhCQPEwuCNKBO2y7SKM0dbtj8,9194
7
7
  appier/asynchronous.py,sha256=a1LQa3wbGMaXELhF7W71dRr1klPOj6x-ST9EInvPhtU,1757
8
8
  appier/asynchronous.pyi,sha256=5CpLkpKcUq09woMOVYwpl24Pli0A8Xu6nXoT20xDQ-o,104
9
- appier/base.py,sha256=zVLPCB134n1QkVGriSLnkn-VXvGobhtT9aATVxxoh6A,270121
10
- appier/base.pyi,sha256=Vx8idYnMvP3nLwGdd2LJKGc0RFpT6iav77YMcBpcr4o,2515
9
+ appier/base.py,sha256=Hjb9dtAp7Ux_3R4hClJNghjZjN7wXpfaoDYPMGbcjFA,270630
10
+ appier/base.pyi,sha256=Uk9nLTDpI5Z51AatN1AtBuGJ7w5CtZpJHXywg1z_Rv4,2818
11
11
  appier/bus.py,sha256=AMC2UXlaf6rzhzlIyTHkzbfb6tdfPBiOii4lpl9AAwg,7670
12
12
  appier/bus.pyi,sha256=W6_MIBpvDq468wfT5XM2WpPuR3O49QiZMOSCdMsJWos,182
13
13
  appier/cache.py,sha256=V1nhf4aHJpUlcFtxVsd-2tGCt1BarkxvHWwVwuhc4Ao,10689
@@ -48,8 +48,8 @@ appier/preferences.pyi,sha256=uYVgvDq2f4KWlLRY-C8bi6xry_utFKDeToGHH5aptxc,197
48
48
  appier/queuing.py,sha256=6AJlRVdd5JunzChu8Q1U-9Biq4vQUHTuJFC8qs2wzCs,8097
49
49
  appier/redisdb.py,sha256=5inJMQqHVkfsGoqoRGYzewlgooDZD2uwOtlPXHX17V0,3504
50
50
  appier/request.py,sha256=vNiRdBZXgboMx_d3xkGHlJf3f7ifejgKyhYZ4Pr9GlE,31450
51
- appier/scheduler.py,sha256=8PcdJQqgbUOrkRfy-2-3N987lGpIUPO9fNYm9QtSjE0,9741
52
- appier/scheduler.pyi,sha256=JHqH-DSKFZL1uXJTpWFTVHykRT8QRGrVdYCi0nyhjrQ,2132
51
+ appier/scheduler.py,sha256=7R1iTA6KSFKUwhjw-PWqhPPNKaaRi9qUTLwcyqO5tXk,10962
52
+ appier/scheduler.pyi,sha256=y-PL_t6gm6f8wwhfrpfIP0P8pljBGTljy-zRMBP_Ihw,2530
53
53
  appier/serialize.py,sha256=LiR1ZbAiC_I3lhlQToPK_u2DC2r04Gl9OEQTayW4Rlg,6669
54
54
  appier/session.py,sha256=6rcwFdsu--7gFLr6mJJh3EFSZ_A3Oe8u7olAvTw2sUk,20380
55
55
  appier/session.pyi,sha256=JBYcT1wZ9mKBBk9iTw2GDJENB8PWFzxXjIr9oXKe85Q,239
@@ -84,7 +84,7 @@ appier/test/part.py,sha256=yHQxg2hdfojJMO2Fs0NLvYTX3uCJ6xwgsD4VaKV04ak,3352
84
84
  appier/test/preferences.py,sha256=QyqoBddOCAmhkcgUYAJ5RgypqrkGL6x6s6a0jsIwE9w,2890
85
85
  appier/test/queuing.py,sha256=Lq7gI5QkZfXPf_MUzmRd6LHHknf9EryF-MauWjDLJn0,5710
86
86
  appier/test/request.py,sha256=h3DdvhEMARpYTp7eRcJ3-qLQyG-a8PHqSnWY52BiOeU,8176
87
- appier/test/scheduler.py,sha256=VlbwpoYYI5hgqlpjcyVcMnSHnLGCCCeMi6kyPD7YxV4,7440
87
+ appier/test/scheduler.py,sha256=j-0byKZZfD36EenJg8kVm55plZ5p1lTLz9GsOT0FDxE,8384
88
88
  appier/test/serialize.py,sha256=roX01n86AQfnPxzPVdIjdIUQWC_x0C_HE3hNgF37ci8,2120
89
89
  appier/test/session.py,sha256=KdiYLLB5autIEu1sHwOuYJXVd0y6RMPgg0ITBuRTMfA,4419
90
90
  appier/test/smtp.py,sha256=XJNa0ZTmabdrX8MfVMgcqBxabvBfHgIimvozdziP4_E,1826
@@ -92,8 +92,8 @@ appier/test/structures.py,sha256=MRjUFRlnJi-i7YGWW5y792JbJwicNvOIzVAS220tgeQ,836
92
92
  appier/test/typesf.py,sha256=KHumQFzx7wPZSCb8_mpIwobhIy2Fh_0XYviwPjXMbKI,9680
93
93
  appier/test/util.py,sha256=SSHuBAZQ0TcXLDYI0xUvmwId5nndDZb88s_5Y-Hqibw,46884
94
94
  appier/test/validation.py,sha256=riOCsGKob1P5jnbcB5qGZ45ApimNAVS0byg9v_uUdrk,4952
95
- appier-1.34.1.dist-info/LICENSE,sha256=Pd-b5cKP4n2tFDpdx27qJSIq0d1ok0oEcGTlbtL6QMU,11560
96
- appier-1.34.1.dist-info/METADATA,sha256=dRqRvcjfXhCFhtijkY6V7HqZ_JcrIr5CKUjhYm2ZdxQ,1920
97
- appier-1.34.1.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
98
- appier-1.34.1.dist-info/top_level.txt,sha256=Z2e_Y1ya06a554WwQZkfNRiaaQxqsdaPtBzrck384Lo,7
99
- appier-1.34.1.dist-info/RECORD,,
95
+ appier-1.34.3.dist-info/LICENSE,sha256=Pd-b5cKP4n2tFDpdx27qJSIq0d1ok0oEcGTlbtL6QMU,11560
96
+ appier-1.34.3.dist-info/METADATA,sha256=6fMXpRxLPtO0Ur-t0Mqj2gNZBFPWJ4mRGMvCSPnI6Ug,1920
97
+ appier-1.34.3.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
98
+ appier-1.34.3.dist-info/top_level.txt,sha256=Z2e_Y1ya06a554WwQZkfNRiaaQxqsdaPtBzrck384Lo,7
99
+ appier-1.34.3.dist-info/RECORD,,