kisa-utils 0.42.9__py3-none-any.whl → 0.42.10__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.
@@ -7,6 +7,8 @@ from kisa_utils import dates
7
7
  from kisa_utils.functionUtils import enforceRequirements
8
8
  from kisa_utils.structures.utils import Value
9
9
 
10
+ from typing import Callable
11
+
10
12
  class __PersistentQueueSingleton(type):
11
13
  _instances = {}
12
14
 
@@ -26,7 +28,6 @@ class __PersistentQueueSingleton(type):
26
28
 
27
29
  return cls._instances[idKey]
28
30
 
29
-
30
31
  class PersistentQueue(metaclass=__PersistentQueueSingleton):
31
32
  __openedQueues:dict = {} # name: PersistentQueue
32
33
 
@@ -81,7 +82,8 @@ class PersistentQueue(metaclass=__PersistentQueueSingleton):
81
82
  self.append = queueCallsInThreads(self.append, group=self.id)
82
83
  self.peek = queueCallsInThreads(self.peek, group=self.id)
83
84
  self.pop = queueCallsInThreads(self.pop, group=self.id)
84
-
85
+ self.process = queueCallsInThreads(self.process, group=self.id)
86
+
85
87
  self.__load__ = queueCallsInThreads(self.__load__, group = "pqueue__load__")
86
88
 
87
89
  if not (resp := self.__load__()):
@@ -162,6 +164,7 @@ class PersistentQueue(metaclass=__PersistentQueueSingleton):
162
164
  self.__length += 1
163
165
  return Ok(self.__length)
164
166
 
167
+ @enforceRequirements
165
168
  def peek(self, index:int, /) -> Response:
166
169
  '''
167
170
  get data at `index` without popping it from the queue
@@ -182,6 +185,7 @@ class PersistentQueue(metaclass=__PersistentQueueSingleton):
182
185
 
183
186
  return Ok(data)
184
187
 
188
+ @enforceRequirements
185
189
  def pop(self, index:int = 0, /) -> Response:
186
190
  '''
187
191
  get data at `index` and remove it from the queue
@@ -206,3 +210,93 @@ class PersistentQueue(metaclass=__PersistentQueueSingleton):
206
210
  self.__length -= 1
207
211
 
208
212
  return Ok(data)
213
+
214
+ @enforceRequirements
215
+ def process(self, index:int, handler:Callable[...,Response], /, *, popOnHandlerSuccess:bool=True, popOnHandlerError:bool=False) -> Response:
216
+ '''
217
+ process item at `index` by passing it as an argument to `handler`
218
+ Args:
219
+ index(int): the index to process
220
+ handler(Callable): a function/method that takes a single argument and returns a `Response` object
221
+ popOnHandlerSuccess(bool): a bool indicating if the item should be poppoed if `handler` returns as `Ok` object
222
+ popOnHandlerError(bool): a bool indicating if the item should be poppoed if `handler` returns as `Error` object
223
+
224
+ Returns:
225
+ `Ok` object with a KDict containing the processed item along with if or not it was popped if all goes well, `Error` object otherwise
226
+ '''
227
+
228
+ if not (resp := self.peek(index)):
229
+ return resp
230
+
231
+ item = resp.data
232
+ try:
233
+ handlerResp = handler(item)
234
+ except Exception as e:
235
+ return Error(str(e))
236
+
237
+ if not isinstance(handlerResp, Response):
238
+ return Error(f'{handler.__name__} did not return a {Response} object!')
239
+
240
+ popped:bool = False
241
+
242
+ if handlerResp and popOnHandlerSuccess:
243
+ if not (resp := self.pop(index)):
244
+ ...
245
+ popped = True
246
+
247
+ if not handlerResp and popOnHandlerError and not popped:
248
+ if not (resp := self.pop(index)):
249
+ ...
250
+ popped = True
251
+
252
+ if (popOnHandlerSuccess or popOnHandlerError) and not popped:
253
+ # what do we do in such a case?
254
+ ...
255
+
256
+ return Ok(KDict({
257
+ 'item': item,
258
+ 'popped': popped
259
+ }))
260
+
261
+ @enforceRequirements
262
+ def processAll(self, handler:Callable[...,Response], /, *, popOnHandlerSuccess:bool=True, popOnHandlerError:bool=False) -> Response:
263
+ '''
264
+ process item at `index` by passing it as an argument to `handler`
265
+ Args:
266
+ handler(Callable): a function/method that takes a single argument and returns a `Response` object
267
+ popOnHandlerSuccess(bool): a bool indicating if the item should be poppoed if `handler` returns as `Ok` object
268
+ popOnHandlerError(bool): a bool indicating if the item should be poppoed if `handler` returns as `Error` object
269
+
270
+ Returns:
271
+ `Ok` object with a KDict containing processedCount,PoppedCount,failedCount,failedLogs if all goes well, `Error` object otherwise
272
+ '''
273
+
274
+ index = 0
275
+
276
+ results = KDict({
277
+ 'processedCount': 0,
278
+ 'PoppedCount': 0,
279
+ 'failedCount': 0,
280
+ 'failedLogs': [],
281
+ })
282
+
283
+ while index < len(self):
284
+ if not (resp := self.process(index, handler, popOnHandlerSuccess=popOnHandlerSuccess, popOnHandlerError=popOnHandlerError)):
285
+ results.processedCount += 1
286
+ results.failedCount += 1
287
+ index += 1
288
+ results.failedLogs.append(KDict({
289
+ 'item': self.peek(index).data,
290
+ 'error': resp.log
291
+ }))
292
+ continue
293
+
294
+ results.processedCount += 1
295
+
296
+ popped = resp.data.popped
297
+ if popped:
298
+ results.PoppedCount += 1
299
+ else:
300
+ index += 1
301
+
302
+ return Ok(results)
@@ -3,7 +3,7 @@ this modules handle data structure validation to ensure that
3
3
  data is passed in expected formats/structures
4
4
  '''
5
5
 
6
- from typing import Any, get_args, get_origin
6
+ from typing import Any, get_args, get_origin, Callable
7
7
  from types import UnionType
8
8
  from kisa_utils.structures.utils import Value
9
9
  from kisa_utils.response import Response, Ok, Error
@@ -54,6 +54,14 @@ def validate(instance:Any, structure:Any, path:str='$') -> dict:
54
54
  result['status'] = True
55
55
  return result
56
56
  else:
57
+ if isinstance(structure, Callable):
58
+ if not callable(instance):
59
+ result['log'] = f'E07: types not similar:: {path}, expected a Callable but got {str(type(instance))[7:-1]}'
60
+ else:
61
+ result['status'] = True
62
+
63
+ return result
64
+
57
65
  # checking in both directions as dict and KDict can fail when you check
58
66
  # `isinstance(dict, KDict)` but will pass when the arguments switch positions
59
67
  if (not isinstance(instance,type(structure))) and (not isinstance(structure, type(instance))):
kisa_utils/threads.py CHANGED
@@ -43,8 +43,8 @@ class Group:
43
43
  add a function to the group
44
44
  Args:
45
45
  function(Callable): the function to be run
46
- args(tuple): arguments and key-word arguments to be passsed to `function`
47
- kwargs(dict): arguments and key-word arguments to be passsed to `function`
46
+ args(tuple): arguments to be passsed to `function`
47
+ kwargs(dict): key-word arguments to be passsed to `function`
48
48
  '''
49
49
  if not callable(function):
50
50
  return Error(f'`{function}` is not callable')
@@ -120,8 +120,8 @@ def runOnce(function:Callable, *args:tuple, **kwargs:dict) -> Response:
120
120
  run a task in a separate thread
121
121
  Args:
122
122
  function(Callable): the function to be run
123
- args(tuple): arguments and key-word arguments to be passsed to `function`
124
- kwargs(dict): arguments and key-word arguments to be passsed to `function`
123
+ args(tuple): arguments to be passsed to `function`
124
+ kwargs(dict): key-word arguments to be passsed to `function`
125
125
  '''
126
126
  __initExecutor()
127
127
 
@@ -147,8 +147,8 @@ def runEvery(function:Callable, duration:float, *args:tuple, **kwargs:dict) -> d
147
147
  Args:
148
148
  function(Callable): the function to call every `duration`
149
149
  duration(float): the time(in SECONDS) after which to run `function` periodically
150
- args(tuple): arguments and key-word arguments to be passsed to `function`
151
- kwargs(dict): arguments and key-word arguments to be passsed to `function`
150
+ args(tuple): arguments to be passsed to `function`
151
+ kwargs(dict): key-word arguments to be passsed to `function`
152
152
 
153
153
  Returns:
154
154
  dict in form
@@ -227,8 +227,8 @@ def runAt(function:Callable, timesOfDay:list[tuple[int,int]], weekDays:list[int]
227
227
  weekDays(list[int]): a list of `ints` each ranging `0-6, inclusive` indicating a day of the week where `0=sunday` and `6=saturday`
228
228
  tzHoursFromUTC(float): hours to add/subtract from UTC. this allows for `timesOfDay` to be seen in a particular timezone.
229
229
  the default value is `+3.00` ie `EAT` so times in `timesOfDay` are in EAT
230
- args(tuple): arguments and key-word arguments to be passsed to `function`
231
- kwargs(dict): arguments and key-word arguments to be passsed to `function`
230
+ args(tuple): arguments to be passsed to `function`
231
+ kwargs(dict): key-word arguments to be passsed to `function`
232
232
 
233
233
  '''
234
234
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kisa-utils
3
- Version: 0.42.9
3
+ Version: 0.42.10
4
4
  Summary: Utility functions and modules for KISA Developers
5
5
  Author: Tom Bukenya
6
6
  Author-email: glayn2bukman@gmail.com
@@ -13,12 +13,12 @@ kisa_utils/remote.py,sha256=0RDrfC4RUW4m6JLziC0_EXJYqzWp38Rw8NDroJ0MuqI,2149
13
13
  kisa_utils/response.py,sha256=asETUBkeF5OlSTwa-coa7lZDCKmQlHCmHf6eaZFl8CU,4560
14
14
  kisa_utils/standardize.py,sha256=nt-uzHQFoKxGscD_MpDYXw65Teg3724whAqa6Kh_zhE,2231
15
15
  kisa_utils/storage.py,sha256=6NdEVrHMS7WB_vmCwiGigIinu-EjxalFJhk1kj-_vWs,5990
16
- kisa_utils/threads.py,sha256=qQqsf64YHMyLpboq5AEXKxYqf3iXUhxiJe6Ymg-vlxI,12840
16
+ kisa_utils/threads.py,sha256=8h_sfCNcjFHl0nDj__sK2O3RjKlgO2d_gkJbs9_y2pI,12692
17
17
  kisa_utils/token.py,sha256=Y2qglWYWpmHxoXBh-TH0r1as0uPV5LLqMNcunLvM4vM,7850
18
18
  kisa_utils/permissions/__config__.py,sha256=i3ELkOydDnjKx2ozQTxLZdZ8DXSeUncnl2kRxANjFmM,613
19
19
  kisa_utils/permissions/__init__.py,sha256=iAsGEf5Ktw3gPJ5ZKL8BnuqX8e_S4QgsCVgfaRYi4Qg,48068
20
20
  kisa_utils/queues/__init__.py,sha256=VvhceyN5qeiMel1JFQwLRuVk48oBXaWvDtriCubDOms,48
21
- kisa_utils/queues/persistent.py,sha256=KueLVqkVcTqvVe5yt9DEM_PvtUEannukixRS8icONTI,6872
21
+ kisa_utils/queues/persistent.py,sha256=b731r1NJkOxlJdkYoxDx2Ojf8loTCY87sd-1_xWn_L4,10431
22
22
  kisa_utils/queues/callables/__init__.py,sha256=OJL3AQnaAS1Eek4H6WBH3WefA2wf-x03cwFmRSK8hoU,141
23
23
  kisa_utils/queues/callables/enqueueFunctionCalls.py,sha256=VIliaMvw4MUdOqts0dXdZCYNxs-QrOVjIRAR3scGrRM,11786
24
24
  kisa_utils/queues/callables/executorQueues.py,sha256=x6bAqxBSZRZ_kL8CK1lSN6JYAYFLxzM84LC1RmwaOLw,6626
@@ -26,8 +26,8 @@ kisa_utils/servers/__init__.py,sha256=lPqDyGTrFo0qwPZ2WA9Xtcpc5D8AIU4huqgFx1iZf6
26
26
  kisa_utils/servers/flask.py,sha256=XZYY1pWnP1mSvaS5Uv8G3EFJV5BJBQtU2gDbO8suvLc,40422
27
27
  kisa_utils/structures/__init__.py,sha256=JBU1j3A42jQ62ALKnsS1Hav9YXcYwjDw1wQJtohXPbU,83
28
28
  kisa_utils/structures/utils.py,sha256=665rXIapGwFqejizeJwy3DryeskCQOdgP25BCdLkGvk,2898
29
- kisa_utils/structures/validator.py,sha256=JhD9jcfbjTwBr_7OfuNaJd_cYr7wR2emFhsCEo5MCHQ,4323
30
- kisa_utils-0.42.9.dist-info/METADATA,sha256=ggmPfO1oysfdUkAExab5IOmqtA6pgvrD5O_orx1WzaU,477
31
- kisa_utils-0.42.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
32
- kisa_utils-0.42.9.dist-info/top_level.txt,sha256=GFOLXZYqpBG9xtscGa2uGJAEiZ5NwsqHBH9NylnB29M,11
33
- kisa_utils-0.42.9.dist-info/RECORD,,
29
+ kisa_utils/structures/validator.py,sha256=oCSgY_itst6bZdC5g8yVU4-lSH2xnUsOx3X-oPyV7nA,4626
30
+ kisa_utils-0.42.10.dist-info/METADATA,sha256=jBt00_w057kBpif03lmw0wd7xtEmYntfDE-WbigtgQ8,478
31
+ kisa_utils-0.42.10.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
32
+ kisa_utils-0.42.10.dist-info/top_level.txt,sha256=GFOLXZYqpBG9xtscGa2uGJAEiZ5NwsqHBH9NylnB29M,11
33
+ kisa_utils-0.42.10.dist-info/RECORD,,