kisa-utils 0.40.0__py3-none-any.whl → 0.42.0__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.
- kisa_utils/__init__.py +4 -2
- kisa_utils/cache.py +2 -2
- kisa_utils/db.py +111 -14
- kisa_utils/queues/__init__.py +2 -0
- kisa_utils/queues/callables/__init__.py +4 -0
- kisa_utils/{queues.py → queues/callables/executorQueues.py} +17 -17
- kisa_utils/queues/persistent.py +96 -0
- kisa_utils/storage.py +9 -1
- {kisa_utils-0.40.0.dist-info → kisa_utils-0.42.0.dist-info}/METADATA +1 -1
- {kisa_utils-0.40.0.dist-info → kisa_utils-0.42.0.dist-info}/RECORD +13 -10
- kisa_utils-0.42.0.dist-info/top_level.txt +1 -0
- kisa_utils-0.40.0.dist-info/top_level.txt +0 -4
- /kisa_utils/{enqueue.py → queues/callables/enqueueFunctionCalls.py} +0 -0
- {kisa_utils-0.40.0.dist-info → kisa_utils-0.42.0.dist-info}/WHEEL +0 -0
kisa_utils/__init__.py
CHANGED
|
@@ -11,11 +11,13 @@ from kisa_utils import codes
|
|
|
11
11
|
from kisa_utils import log
|
|
12
12
|
from kisa_utils import token
|
|
13
13
|
from kisa_utils import threads
|
|
14
|
-
from kisa_utils import
|
|
14
|
+
from kisa_utils.queues.callables import executorQueues
|
|
15
15
|
from kisa_utils import cache
|
|
16
16
|
from kisa_utils import response
|
|
17
17
|
from kisa_utils import permissions
|
|
18
18
|
from kisa_utils import functionUtils
|
|
19
19
|
from kisa_utils import servers
|
|
20
|
-
from kisa_utils import enqueue
|
|
21
20
|
from kisa_utils import dataStructures
|
|
21
|
+
|
|
22
|
+
from kisa_utils import queues
|
|
23
|
+
from kisa_utils.queues.callables import enqueueFunctionCalls
|
kisa_utils/cache.py
CHANGED
|
@@ -6,7 +6,7 @@ this module is reponsible to creating and managing named caches for KISA
|
|
|
6
6
|
|
|
7
7
|
import time
|
|
8
8
|
from . import threads
|
|
9
|
-
from . import
|
|
9
|
+
from .queues.callables import executorQueues
|
|
10
10
|
from . import db
|
|
11
11
|
from typing import Callable
|
|
12
12
|
|
|
@@ -43,7 +43,7 @@ class Cache:
|
|
|
43
43
|
if not loopThreadReply['status']:
|
|
44
44
|
raise CacheException(f'cache main thread: {loopThreadReply["log"]}')
|
|
45
45
|
|
|
46
|
-
queueReply =
|
|
46
|
+
queueReply = executorQueues.create(f'_cache:{name}', self.__readQueue)
|
|
47
47
|
if not queueReply['status']:
|
|
48
48
|
raise CacheException(f'cache queue thread: {queueReply["log"]}')
|
|
49
49
|
|
kisa_utils/db.py
CHANGED
|
@@ -56,6 +56,7 @@ TRIGGERS:dict = {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
JSON_SEPARATOR = '::'
|
|
59
|
+
JSON_ARRAY_APPEND_SYMBOL = '+' # arr[+]=N => arr.append(N)
|
|
59
60
|
|
|
60
61
|
RAM_DB_PATHS:list[str] = [':memory:', ':ram:',':RAM:']
|
|
61
62
|
|
|
@@ -508,24 +509,116 @@ class Api:
|
|
|
508
509
|
|
|
509
510
|
return tables
|
|
510
511
|
|
|
511
|
-
def
|
|
512
|
+
def __getJSONListIndices(self, jsonPathSection:str) -> Response:
|
|
513
|
+
'''
|
|
514
|
+
get key and indices of a json path
|
|
515
|
+
Returns:
|
|
516
|
+
Response.data ->
|
|
517
|
+
```
|
|
518
|
+
{
|
|
519
|
+
'key': str, # if array is a key in a dict, then this is set, otherwise its an empty string
|
|
520
|
+
'indices': list[int] # contains all indices
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
'''
|
|
524
|
+
data = KDict({
|
|
525
|
+
'key': '',
|
|
526
|
+
'indices': [],
|
|
527
|
+
})
|
|
528
|
+
|
|
529
|
+
if '[' not in jsonPathSection:
|
|
530
|
+
return Ok(data)
|
|
531
|
+
|
|
532
|
+
if jsonPathSection.count('[') != jsonPathSection.count(']') or jsonPathSection.index('[') > jsonPathSection.index(']'):
|
|
533
|
+
return Error(f'malformed array indexing found: `{jsonPathSection}`')
|
|
534
|
+
|
|
535
|
+
targetIndex = jsonPathSection.index('[')
|
|
536
|
+
data.key = jsonPathSection[:targetIndex].strip()
|
|
537
|
+
|
|
538
|
+
section = jsonPathSection[targetIndex:]
|
|
539
|
+
while '[' in section:
|
|
540
|
+
if section.count('[') != section.count(']') or section.index('[') > section.index(']'):
|
|
541
|
+
return Error(f'malformed array indexing found: `{jsonPathSection}`')
|
|
542
|
+
|
|
543
|
+
startIndex, endIndex = section.index('['), section.index(']')
|
|
544
|
+
|
|
545
|
+
try:
|
|
546
|
+
index = section[startIndex+1:endIndex]
|
|
547
|
+
index = int(index)
|
|
548
|
+
except:
|
|
549
|
+
index = index.strip()
|
|
550
|
+
if index != JSON_ARRAY_APPEND_SYMBOL:
|
|
551
|
+
return Error(f'malformed array index found: `{jsonPathSection}`->`{section[startIndex+1:endIndex]}`')
|
|
552
|
+
|
|
553
|
+
if JSON_ARRAY_APPEND_SYMBOL in data.indices:
|
|
554
|
+
return Error(f'index `{JSON_ARRAY_APPEND_SYMBOL}` should be the last index: `{jsonPathSection}`->`{section[startIndex+1:endIndex]}`')
|
|
555
|
+
|
|
556
|
+
data.indices.append(index)
|
|
557
|
+
|
|
558
|
+
section = section[endIndex+1:]
|
|
559
|
+
|
|
560
|
+
return Ok(data)
|
|
561
|
+
|
|
562
|
+
def __formRootPathFields(self, root:dict|list, keys:list, value:Any) -> Response:
|
|
512
563
|
for key in keys[:-1]:
|
|
564
|
+
if not (resp := self.__getJSONListIndices(key)):
|
|
565
|
+
return resp
|
|
513
566
|
|
|
514
|
-
if
|
|
515
|
-
key = key[:-4]
|
|
516
|
-
root = root.setdefault(key, [])
|
|
517
|
-
else:
|
|
567
|
+
if not resp.data.indices: # dict object
|
|
518
568
|
root = root.setdefault(key, {})
|
|
569
|
+
else: # list object
|
|
570
|
+
if resp.data.key and isinstance(root, dict):
|
|
571
|
+
root = root.setdefault(resp.data.key, [])
|
|
572
|
+
|
|
573
|
+
if not isinstance(root, list):
|
|
574
|
+
return Error(f'indexing non-array: `{key}`')
|
|
575
|
+
|
|
576
|
+
while resp.data.indices:
|
|
577
|
+
_index = index = resp.data.indices.pop(0)
|
|
578
|
+
if _index == JSON_ARRAY_APPEND_SYMBOL:
|
|
579
|
+
return Error(f'append index `{_index}` should be at the end: `{key}`, index `{_index}({index})`')
|
|
580
|
+
if index < 0:
|
|
581
|
+
index = len(root) + index
|
|
582
|
+
|
|
583
|
+
if not (0<= index < len(root)):
|
|
584
|
+
return Error(f'array-index out of bounds: `{key}`, index `{_index}({index})`')
|
|
519
585
|
|
|
520
|
-
|
|
586
|
+
root = root[index]
|
|
521
587
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
root[
|
|
588
|
+
key = keys[-1]
|
|
589
|
+
|
|
590
|
+
if not (resp := self.__getJSONListIndices(key)):
|
|
591
|
+
return resp
|
|
592
|
+
|
|
593
|
+
if not resp.data.indices: # dict object
|
|
594
|
+
root[key] = value
|
|
595
|
+
else: # list object
|
|
596
|
+
if resp.data.key and isinstance(root, dict):
|
|
597
|
+
root = root.setdefault(resp.data.key, [])
|
|
598
|
+
|
|
599
|
+
if not isinstance(root, list):
|
|
600
|
+
return Error(f'indexing non-array: `{key}`')
|
|
601
|
+
|
|
602
|
+
while len(resp.data.indices):
|
|
603
|
+
_index = index = resp.data.indices.pop(0)
|
|
604
|
+
if _index != JSON_ARRAY_APPEND_SYMBOL:
|
|
605
|
+
if index < 0:
|
|
606
|
+
index = len(root) + index
|
|
607
|
+
|
|
608
|
+
if not (0<= index < len(root)):
|
|
609
|
+
return Error(f'array-index out of bounds: `{key}`, index `{_index}({index})`')
|
|
610
|
+
elif resp.data.indices:
|
|
611
|
+
return Error(f'append index `{_index}` should be at the end: `{key}`, index `{_index}({index})`')
|
|
612
|
+
|
|
613
|
+
if resp.data.indices:
|
|
614
|
+
root = root[index]
|
|
615
|
+
else:
|
|
616
|
+
if _index != JSON_ARRAY_APPEND_SYMBOL:
|
|
617
|
+
root[index] = value
|
|
618
|
+
else:
|
|
619
|
+
root.append(value)
|
|
620
|
+
|
|
621
|
+
return Ok()
|
|
529
622
|
|
|
530
623
|
def __getRootAndPath(self, string, separator:str=JSON_SEPARATOR):
|
|
531
624
|
index = string.index(separator)
|
|
@@ -857,6 +950,7 @@ class Api:
|
|
|
857
950
|
|
|
858
951
|
rootResult = rootResult[0]
|
|
859
952
|
rootResult = storage.decodeJSON(rootResult)
|
|
953
|
+
# print('>>> ',rootResult,'<<<')
|
|
860
954
|
|
|
861
955
|
if isinstance(rootResult, list):
|
|
862
956
|
if self.__transactionMode: self.__transactionData['update']['failed'] += 1
|
|
@@ -868,7 +962,9 @@ class Api:
|
|
|
868
962
|
|
|
869
963
|
json_roots[root] = rootResult
|
|
870
964
|
|
|
871
|
-
self.__formRootPathFields(json_roots[root], path.split(JSON_SEPARATOR), columnData[index])
|
|
965
|
+
if not (resp := self.__formRootPathFields(json_roots[root], path.split(JSON_SEPARATOR), columnData[index])):
|
|
966
|
+
reply['log'] = resp.log
|
|
967
|
+
return reply if not self.__returnKISAResponse else resp
|
|
872
968
|
|
|
873
969
|
_columns.append(f'{root}=?')
|
|
874
970
|
|
|
@@ -876,6 +972,7 @@ class Api:
|
|
|
876
972
|
columns = _columns
|
|
877
973
|
values += conditionData
|
|
878
974
|
|
|
975
|
+
|
|
879
976
|
if not condition:
|
|
880
977
|
if self.__transactionMode: self.__transactionData['update']['failed'] += 1
|
|
881
978
|
reply['log'] = 'please provide an update condition. use `1` if you want all data updated'
|
|
@@ -5,14 +5,14 @@ this module is reponsible to creating and managing named queues for KISA
|
|
|
5
5
|
'''
|
|
6
6
|
|
|
7
7
|
from queue import Queue as pyQueue
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from ...structures import validator as structureValidator
|
|
9
|
+
from ... import threads
|
|
10
10
|
from typing import Callable, Any
|
|
11
11
|
|
|
12
|
-
class
|
|
12
|
+
class ExecutorQueueException(Exception):
|
|
13
13
|
pass
|
|
14
14
|
|
|
15
|
-
class
|
|
15
|
+
class ExecutorQueue:
|
|
16
16
|
__ACTIVE_QUEUES = {}
|
|
17
17
|
|
|
18
18
|
def __init__(self, name:str, executor:Callable, inputDefinitions:dict={}) -> None:
|
|
@@ -39,25 +39,25 @@ class Queue:
|
|
|
39
39
|
inputDefinitions['kwargs'] = inputDefinitions.get('kwargs',{})
|
|
40
40
|
|
|
41
41
|
if name in activeQueues:
|
|
42
|
-
raise
|
|
42
|
+
raise ExecutorQueueException(f'a queue already named `{name}` exists')
|
|
43
43
|
|
|
44
44
|
if not callable(executor):
|
|
45
|
-
raise
|
|
45
|
+
raise ExecutorQueueException('given `executor` is not a function/callable')
|
|
46
46
|
|
|
47
47
|
executorName = executor.__name__
|
|
48
48
|
if executorName.startswith('<'):
|
|
49
|
-
raise
|
|
49
|
+
raise ExecutorQueueException('lambda functions are not allowed')
|
|
50
50
|
|
|
51
51
|
if not (
|
|
52
52
|
isinstance(inputDefinitions, dict) and \
|
|
53
53
|
('args' in inputDefinitions) and isinstance(inputDefinitions['args'],(tuple,list)) and\
|
|
54
54
|
('kwargs' in inputDefinitions) and isinstance(inputDefinitions['kwargs'],dict) \
|
|
55
55
|
):
|
|
56
|
-
raise
|
|
56
|
+
raise ExecutorQueueException('invalid `inputDefinitions` given')
|
|
57
57
|
|
|
58
58
|
for kwarg in inputDefinitions['kwargs']:
|
|
59
59
|
if not isinstance(kwarg,str):
|
|
60
|
-
raise
|
|
60
|
+
raise ExecutorQueueException('all keys in inputDefinitions->kwargs must be strings')
|
|
61
61
|
|
|
62
62
|
self.executor = executor
|
|
63
63
|
self.inputDefinitions = inputDefinitions
|
|
@@ -112,7 +112,7 @@ def nameIsRegistered(name:str) -> bool:
|
|
|
112
112
|
Args:
|
|
113
113
|
name(str): the queue name
|
|
114
114
|
'''
|
|
115
|
-
return name in
|
|
115
|
+
return name in ExecutorQueue._Queue__ACTIVE_QUEUES
|
|
116
116
|
|
|
117
117
|
def create(name:str, executor:Callable, inputDefinitions:dict={}) -> dict:
|
|
118
118
|
'''
|
|
@@ -148,16 +148,16 @@ def create(name:str, executor:Callable, inputDefinitions:dict={}) -> dict:
|
|
|
148
148
|
inputDefinitions['kwargs'] = inputDefinitions.get('kwargs',None) or {}
|
|
149
149
|
|
|
150
150
|
if nameIsRegistered(name):
|
|
151
|
-
if inputDefinitions!=
|
|
151
|
+
if inputDefinitions!=ExecutorQueue._Queue__ACTIVE_QUEUES[name].inputDefinitions:
|
|
152
152
|
reply['log'] = f'a queue with the name `{name}` already exisits and has different inputDefinitions'
|
|
153
153
|
else:
|
|
154
154
|
reply['status'] = True
|
|
155
|
-
reply['queue'] =
|
|
155
|
+
reply['queue'] = ExecutorQueue._Queue__ACTIVE_QUEUES[name]
|
|
156
156
|
|
|
157
157
|
return reply
|
|
158
158
|
|
|
159
159
|
try:
|
|
160
|
-
queue =
|
|
160
|
+
queue = ExecutorQueue(name, executor, inputDefinitions)
|
|
161
161
|
except Exception as e:
|
|
162
162
|
reply['log'] = f'{e}'
|
|
163
163
|
return reply
|
|
@@ -181,7 +181,7 @@ def push(name:str, *args:tuple, **kwargs:dict) -> dict:
|
|
|
181
181
|
'''
|
|
182
182
|
reply = {'status':False, 'log':''}
|
|
183
183
|
|
|
184
|
-
queue =
|
|
184
|
+
queue = ExecutorQueue._Queue__ACTIVE_QUEUES.get(name,None)
|
|
185
185
|
|
|
186
186
|
if not queue:
|
|
187
187
|
reply['log'] = f'could not find queue named `{name}`'
|
|
@@ -189,13 +189,13 @@ def push(name:str, *args:tuple, **kwargs:dict) -> dict:
|
|
|
189
189
|
|
|
190
190
|
return queue.push(*args, **kwargs)
|
|
191
191
|
|
|
192
|
-
def get(name:str) ->
|
|
192
|
+
def get(name:str) -> ExecutorQueue | None:
|
|
193
193
|
'''
|
|
194
194
|
get queue instance using its name
|
|
195
195
|
Args:
|
|
196
196
|
name(str): the queue name
|
|
197
197
|
'''
|
|
198
|
-
return
|
|
198
|
+
return ExecutorQueue._Queue__ACTIVE_QUEUES.get(name,None)
|
|
199
199
|
|
|
200
200
|
if __name__=='__main__':
|
|
201
201
|
def addNumbers(a:int,b:int):
|
|
@@ -204,7 +204,7 @@ if __name__=='__main__':
|
|
|
204
204
|
queueReply = create('testQueue',addNumbers,{'args':(int,int)})
|
|
205
205
|
print(queueReply)
|
|
206
206
|
# queue = queueReply['queue']
|
|
207
|
-
queue:
|
|
207
|
+
queue:ExecutorQueue = get('testQueue')
|
|
208
208
|
|
|
209
209
|
for i in range(15):
|
|
210
210
|
print(queue.push(i,10))
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from kisa_utils.db import Handle
|
|
2
|
+
from kisa_utils.queues.callables import queueCallsInThreads
|
|
3
|
+
from kisa_utils.response import Response, Error, Ok
|
|
4
|
+
from kisa_utils.dataStructures import KDict
|
|
5
|
+
from kisa_utils.storage import Path
|
|
6
|
+
|
|
7
|
+
class __PersistentQueueSingleton(type):
|
|
8
|
+
_instances = {}
|
|
9
|
+
|
|
10
|
+
def __call__(cls, *args, **kwargs):
|
|
11
|
+
if not args:
|
|
12
|
+
raise Exception(f'invalid instantiation of {cls}')
|
|
13
|
+
id = args[0]
|
|
14
|
+
|
|
15
|
+
if not id.isalnum():
|
|
16
|
+
raise ValueError('persistent queue ID should be an alphanumeric value ie a-zA-Z0-9 with no special characters or spaces')
|
|
17
|
+
|
|
18
|
+
if id not in cls._instances:
|
|
19
|
+
cls._instances[id] = super().__call__(*args, **kwargs)
|
|
20
|
+
|
|
21
|
+
return cls._instances[id]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class PersistentQueue(metaclass=__PersistentQueueSingleton):
|
|
25
|
+
__openedQueues:dict = {} # name: PersistentQueue
|
|
26
|
+
|
|
27
|
+
__allowedDataTypes = str|int|float|dict|KDict|list|tuple|set
|
|
28
|
+
|
|
29
|
+
__defaultDirectoryName:str = '.kisaPersistentQueues'
|
|
30
|
+
__defaultStorageLocation:str = Path.join(Path.HOME, __defaultDirectoryName)
|
|
31
|
+
|
|
32
|
+
def __init__(self, id:str, /, *, storageLocation:str=''):
|
|
33
|
+
'''
|
|
34
|
+
create a new thread-safe PersistentQueue
|
|
35
|
+
Args:
|
|
36
|
+
id(str): the Queue ID. queue sharing an ID will all reference the same underwlying queue
|
|
37
|
+
storageLocation(str): if provided, the location to store the queue. if not provided, data is stored in the default location. use `obj.defaultStorageLocation` to get the default storage directory
|
|
38
|
+
'''
|
|
39
|
+
|
|
40
|
+
if storageLocation:
|
|
41
|
+
if not Path.exists(storageLocation):
|
|
42
|
+
raise Exception(f'could not find storage directory: `{storageLocation}`')
|
|
43
|
+
else:
|
|
44
|
+
storageLocation = self.__defaultStorageLocation
|
|
45
|
+
if not Path.exists(storageLocation) and not Path.createDirectory(storageLocation):
|
|
46
|
+
raise Exception(f'failed to create storage directory: `{storageLocation}`')
|
|
47
|
+
|
|
48
|
+
self.__length:int = 0
|
|
49
|
+
self.id = id
|
|
50
|
+
|
|
51
|
+
# ensure thread safety throughout the running program
|
|
52
|
+
self.append = queueCallsInThreads(self.append, group=self.id)
|
|
53
|
+
self.peek = queueCallsInThreads(self.peek, group=self.id)
|
|
54
|
+
self.pop = queueCallsInThreads(self.pop, group=self.id)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def defaultStorageLocation(self):
|
|
59
|
+
'''
|
|
60
|
+
get the default storage location
|
|
61
|
+
'''
|
|
62
|
+
return self.__defaultStorageLocation
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def allowedDataTypes(self):
|
|
66
|
+
'''
|
|
67
|
+
get data types allowed in the queue
|
|
68
|
+
'''
|
|
69
|
+
return self.__allowedDataTypes
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def length(self) -> int:
|
|
73
|
+
'''
|
|
74
|
+
get number of items in the queue
|
|
75
|
+
'''
|
|
76
|
+
return self.__length
|
|
77
|
+
|
|
78
|
+
def append(self, data:__allowedDataTypes, /) -> Response:
|
|
79
|
+
'''
|
|
80
|
+
append to the queue
|
|
81
|
+
Args:
|
|
82
|
+
data(__allowedDataTypes): the data to insert, use `obj.allowedDataTypes` to get the list of allowed data types
|
|
83
|
+
'''
|
|
84
|
+
...
|
|
85
|
+
|
|
86
|
+
def peek(self, index:int, /) -> Response:
|
|
87
|
+
'''
|
|
88
|
+
get data at `index` without popping it from the queue
|
|
89
|
+
'''
|
|
90
|
+
...
|
|
91
|
+
|
|
92
|
+
def pop(self, /, *, index:int = 0) -> Response:
|
|
93
|
+
'''
|
|
94
|
+
get data at `index` and remove it from the queue
|
|
95
|
+
'''
|
|
96
|
+
...
|
kisa_utils/storage.py
CHANGED
|
@@ -5,7 +5,15 @@ from kisa_utils.response import Response, Error, Ok
|
|
|
5
5
|
encodeJSON = json.JSONEncoder().encode
|
|
6
6
|
decodeJSON = json.JSONDecoder().decode
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class _Meta(type):
|
|
9
|
+
@property
|
|
10
|
+
def HOME(cls):
|
|
11
|
+
'''
|
|
12
|
+
get user's home directory
|
|
13
|
+
'''
|
|
14
|
+
return os.path.expanduser('~')
|
|
15
|
+
|
|
16
|
+
class Path(metaclass=_Meta):
|
|
9
17
|
join = os.path.join
|
|
10
18
|
directoryName = os.path.dirname
|
|
11
19
|
|
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
kisa_utils/__init__.py,sha256
|
|
2
|
-
kisa_utils/cache.py,sha256=
|
|
1
|
+
kisa_utils/__init__.py,sha256=-g5gBmI4gV840-Brg1V1aZ_R_r3n_csB-PlRRdUV_UQ,745
|
|
2
|
+
kisa_utils/cache.py,sha256=WOL3e0wvoyESXTtlbVnUg9TYUoLzg64sLP9J4b4ti9k,7377
|
|
3
3
|
kisa_utils/codes.py,sha256=PV_S53Skggf4XetOdYoIKtEmM8cpN5wZwUlxje70WZY,904
|
|
4
4
|
kisa_utils/config.py,sha256=NfluzGKTh66qfNtC-Ae0zNb1XzMTgU2Me9Vi82R9c1E,2285
|
|
5
5
|
kisa_utils/dataStructures.py,sha256=ZgLpttJ66jfpU1NWzLDD1Czqxzj6sWereffgTQWhlV8,2679
|
|
6
6
|
kisa_utils/dates.py,sha256=zxe4n0PdKReZjK5ZkvnCZtJ55lk5oqu9oS8VX_nLozw,13966
|
|
7
|
-
kisa_utils/db.py,sha256=
|
|
7
|
+
kisa_utils/db.py,sha256=cYlUXDkVCTotsa4pFmoYFkrwPHDEYYeSWJVgIHYRhFQ,53792
|
|
8
8
|
kisa_utils/encryption.py,sha256=nFzNpzWV_D9uSEq4FsgCnlS7FQtqWP9fvM_81rsfcLo,4218
|
|
9
|
-
kisa_utils/enqueue.py,sha256=VIliaMvw4MUdOqts0dXdZCYNxs-QrOVjIRAR3scGrRM,11786
|
|
10
9
|
kisa_utils/figures.py,sha256=pYIpQzu1OXRSsY1d98GhgPifnIRmgl-r7S32ai-Ms0c,3731
|
|
11
10
|
kisa_utils/functionUtils.py,sha256=PlXjnmU1uJWNdISlJJ3SCgavTsgNBoebaa9dtWSFhRA,6553
|
|
12
11
|
kisa_utils/log.py,sha256=0TYdxcIBts026RCSuVIQBcZ-CW1ES7n3M1nEIjmeLTM,2295
|
|
13
|
-
kisa_utils/queues.py,sha256=9QqPtDujw6tbWk7uUiXrsd0rVBTIkzeQw9b45l5Fo3k,6502
|
|
14
12
|
kisa_utils/remote.py,sha256=0RDrfC4RUW4m6JLziC0_EXJYqzWp38Rw8NDroJ0MuqI,2149
|
|
15
13
|
kisa_utils/response.py,sha256=asETUBkeF5OlSTwa-coa7lZDCKmQlHCmHf6eaZFl8CU,4560
|
|
16
14
|
kisa_utils/standardize.py,sha256=nt-uzHQFoKxGscD_MpDYXw65Teg3724whAqa6Kh_zhE,2231
|
|
17
|
-
kisa_utils/storage.py,sha256=
|
|
15
|
+
kisa_utils/storage.py,sha256=6NdEVrHMS7WB_vmCwiGigIinu-EjxalFJhk1kj-_vWs,5990
|
|
18
16
|
kisa_utils/threads.py,sha256=qQqsf64YHMyLpboq5AEXKxYqf3iXUhxiJe6Ymg-vlxI,12840
|
|
19
17
|
kisa_utils/token.py,sha256=Y2qglWYWpmHxoXBh-TH0r1as0uPV5LLqMNcunLvM4vM,7850
|
|
20
18
|
kisa_utils/permissions/__config__.py,sha256=i3ELkOydDnjKx2ozQTxLZdZ8DXSeUncnl2kRxANjFmM,613
|
|
21
19
|
kisa_utils/permissions/__init__.py,sha256=q7LGl26f-MPXkLS6nxBKDotW3xdB8y7pI5S_Oo5fPOw,47976
|
|
20
|
+
kisa_utils/queues/__init__.py,sha256=VvhceyN5qeiMel1JFQwLRuVk48oBXaWvDtriCubDOms,48
|
|
21
|
+
kisa_utils/queues/persistent.py,sha256=FTIdz1iPrBnICZ3XYuRDtfXonZP83GuCpsNkPUQi2Lg,3269
|
|
22
|
+
kisa_utils/queues/callables/__init__.py,sha256=OJL3AQnaAS1Eek4H6WBH3WefA2wf-x03cwFmRSK8hoU,141
|
|
23
|
+
kisa_utils/queues/callables/enqueueFunctionCalls.py,sha256=VIliaMvw4MUdOqts0dXdZCYNxs-QrOVjIRAR3scGrRM,11786
|
|
24
|
+
kisa_utils/queues/callables/executorQueues.py,sha256=x6bAqxBSZRZ_kL8CK1lSN6JYAYFLxzM84LC1RmwaOLw,6626
|
|
22
25
|
kisa_utils/servers/__init__.py,sha256=lPqDyGTrFo0qwPZ2WA9Xtcpc5D8AIU4huqgFx1iZf68,19
|
|
23
26
|
kisa_utils/servers/flask.py,sha256=XZYY1pWnP1mSvaS5Uv8G3EFJV5BJBQtU2gDbO8suvLc,40422
|
|
24
27
|
kisa_utils/structures/__init__.py,sha256=JBU1j3A42jQ62ALKnsS1Hav9YXcYwjDw1wQJtohXPbU,83
|
|
25
28
|
kisa_utils/structures/utils.py,sha256=665rXIapGwFqejizeJwy3DryeskCQOdgP25BCdLkGvk,2898
|
|
26
29
|
kisa_utils/structures/validator.py,sha256=JhD9jcfbjTwBr_7OfuNaJd_cYr7wR2emFhsCEo5MCHQ,4323
|
|
27
|
-
kisa_utils-0.
|
|
28
|
-
kisa_utils-0.
|
|
29
|
-
kisa_utils-0.
|
|
30
|
-
kisa_utils-0.
|
|
30
|
+
kisa_utils-0.42.0.dist-info/METADATA,sha256=_yhF_JWGl4md4JW9DhH26RPDUoi4LDcSwDw4yez2yfg,477
|
|
31
|
+
kisa_utils-0.42.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
32
|
+
kisa_utils-0.42.0.dist-info/top_level.txt,sha256=GFOLXZYqpBG9xtscGa2uGJAEiZ5NwsqHBH9NylnB29M,11
|
|
33
|
+
kisa_utils-0.42.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
kisa_utils
|
|
File without changes
|
|
File without changes
|