streamlit-octostar-utils 0.5.4.dev5__tar.gz → 0.5.5.dev1__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.
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/PKG-INFO +2 -1
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/pyproject.toml +2 -1
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/nifi.py +168 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/LICENSE +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/README.md +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/celery.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/contents.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/fastapi.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parallelism.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/combine_fields.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/entities_parser.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/generics.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/info.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/linkchart_functions.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/matches.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/parameters.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/rules.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/api_crafter/parser/signals.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/core/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/core/dict.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/core/filetypes.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/core/threading/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/core/threading/key_queue.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/core/timestamp.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/nlp/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/nlp/custom_recognizers.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/nlp/language.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/nlp/ner.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/octostar/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/octostar/client.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/octostar/context.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/octostar/permissions.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/ontology/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/ontology/inheritance.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/ontology/relationships.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/ontology/validation.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/style/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/style/common.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/threading/__init__.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/threading/async_task_manager.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/threading/session_callback_manager.py +0 -0
- {streamlit_octostar_utils-0.5.4.dev5 → streamlit_octostar_utils-0.5.5.dev1}/streamlit_octostar_utils/threading/session_state_hot_swapper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: streamlit-octostar-utils
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.5.dev1
|
|
4
4
|
Summary:
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -26,6 +26,7 @@ Requires-Dist: numpy (>=1.20.0)
|
|
|
26
26
|
Requires-Dist: octostar-streamlit (>=0.1.25,<0.2.0)
|
|
27
27
|
Requires-Dist: pottery (>=3.0.0,<4.0.0)
|
|
28
28
|
Requires-Dist: presidio-analyzer (>=2.2.0,<3.0.0) ; extra == "nlp"
|
|
29
|
+
Requires-Dist: psutil (>=5.9.0)
|
|
29
30
|
Requires-Dist: py3langid (>=0.2.0,<0.3.0) ; extra == "nlp"
|
|
30
31
|
Requires-Dist: pydantic (>=2.6.4,<3.0.0)
|
|
31
32
|
Requires-Dist: python-multipart (>=0.0.9,<0.0.10)
|
|
@@ -5,7 +5,7 @@ include = '\.pyi?$'
|
|
|
5
5
|
|
|
6
6
|
[tool.poetry]
|
|
7
7
|
name = "streamlit-octostar-utils"
|
|
8
|
-
version = "0.5.
|
|
8
|
+
version = "0.5.5-dev.1"
|
|
9
9
|
description = ""
|
|
10
10
|
license = "MIT"
|
|
11
11
|
authors = ["Octostar"]
|
|
@@ -37,6 +37,7 @@ numpy = ">=1.20.0"
|
|
|
37
37
|
scipy = "^1.10.0"
|
|
38
38
|
rapidfuzz = "^3.5.0"
|
|
39
39
|
celery = "^5.3.0"
|
|
40
|
+
psutil = ">=5.9.0"
|
|
40
41
|
redis = ">=4.0.0,<5.0.0"
|
|
41
42
|
pottery = "^3.0.0"
|
|
42
43
|
slowapi = "^0.1.9"
|
|
@@ -54,6 +54,144 @@ OS_RESERVED_FIELDS = [
|
|
|
54
54
|
MAX_IN_MEMORY_SIZE_BYTES = 5_242_880
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
class NifiPriority:
|
|
58
|
+
COMPONENT_WIDTHS = (10, 10, 1, 20)
|
|
59
|
+
SEPARATOR = "."
|
|
60
|
+
MAX_FRAGMENT_DEPTH = 9
|
|
61
|
+
BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
|
62
|
+
BASE = len(BASE62_CHARS)
|
|
63
|
+
_BASE62_SET = frozenset(BASE62_CHARS)
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def _normalize_component(value, width):
|
|
67
|
+
if value is None:
|
|
68
|
+
return "z" * width
|
|
69
|
+
s = str(value)
|
|
70
|
+
invalid = set(s) - NifiPriority._BASE62_SET
|
|
71
|
+
if invalid:
|
|
72
|
+
raise ValueError(f"Invalid base62 character(s): {sorted(invalid)!r}")
|
|
73
|
+
if len(s) > width:
|
|
74
|
+
return "z" * width
|
|
75
|
+
return s.rjust(width, "0")
|
|
76
|
+
|
|
77
|
+
def __init__(self, op_reserved=None, user_prio=None, fragment_prio=0, entity_timestamp=0):
|
|
78
|
+
w = self.COMPONENT_WIDTHS
|
|
79
|
+
self.op_reserved = self._normalize_component(op_reserved, w[0])
|
|
80
|
+
self.user_prio = self._normalize_component(user_prio, w[1])
|
|
81
|
+
self.fragment_prio = int(fragment_prio)
|
|
82
|
+
self.entity_timestamp = int(entity_timestamp)
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def _encode_base62(value, width):
|
|
86
|
+
chars = NifiPriority.BASE62_CHARS
|
|
87
|
+
base = NifiPriority.BASE
|
|
88
|
+
if value < 0:
|
|
89
|
+
value = 0
|
|
90
|
+
if value == 0:
|
|
91
|
+
return "0" * width
|
|
92
|
+
result = []
|
|
93
|
+
v = value
|
|
94
|
+
while v > 0:
|
|
95
|
+
result.append(chars[v % base])
|
|
96
|
+
v //= base
|
|
97
|
+
result.reverse()
|
|
98
|
+
s = "".join(result)
|
|
99
|
+
if len(s) > width:
|
|
100
|
+
return chars[-1] * width
|
|
101
|
+
return s.rjust(width, "0")
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def _decode_base62(s):
|
|
105
|
+
chars = NifiPriority.BASE62_CHARS
|
|
106
|
+
result = 0
|
|
107
|
+
for c in s:
|
|
108
|
+
idx = chars.find(c)
|
|
109
|
+
if idx < 0:
|
|
110
|
+
raise ValueError(f"Invalid base62 character: {c!r}")
|
|
111
|
+
result = result * NifiPriority.BASE + idx
|
|
112
|
+
return result
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def from_string(cls, s):
|
|
116
|
+
if not s or cls.SEPARATOR not in s:
|
|
117
|
+
return cls()
|
|
118
|
+
parts = s.split(cls.SEPARATOR)
|
|
119
|
+
if len(parts) != 4:
|
|
120
|
+
return cls()
|
|
121
|
+
try:
|
|
122
|
+
for part in parts:
|
|
123
|
+
if set(part) - cls._BASE62_SET:
|
|
124
|
+
return cls()
|
|
125
|
+
return cls(
|
|
126
|
+
op_reserved=parts[0],
|
|
127
|
+
user_prio=parts[1],
|
|
128
|
+
fragment_prio=cls._decode_base62(parts[2]),
|
|
129
|
+
entity_timestamp=cls._decode_base62(parts[3]),
|
|
130
|
+
)
|
|
131
|
+
except (ValueError, TypeError):
|
|
132
|
+
return cls()
|
|
133
|
+
|
|
134
|
+
@classmethod
|
|
135
|
+
def from_dict(cls, d):
|
|
136
|
+
if not d:
|
|
137
|
+
return cls()
|
|
138
|
+
return cls(
|
|
139
|
+
op_reserved=d.get("op_reserved"),
|
|
140
|
+
user_prio=d.get("user_prio"),
|
|
141
|
+
fragment_prio=d.get("fragment_prio", 0),
|
|
142
|
+
entity_timestamp=d.get("entity_timestamp", 0),
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
@classmethod
|
|
146
|
+
def from_entity(cls, entity):
|
|
147
|
+
existing = entity.request.get("priority", {})
|
|
148
|
+
prio = cls.from_dict(existing)
|
|
149
|
+
prio.fragment_prio = cls.compute_fragment_depth(entity)
|
|
150
|
+
ts_str = entity.request.get("entity_timestamp")
|
|
151
|
+
if ts_str:
|
|
152
|
+
try:
|
|
153
|
+
dt = string_to_datetime(ts_str)
|
|
154
|
+
prio.entity_timestamp = int(dt.timestamp() * 1000)
|
|
155
|
+
except Exception:
|
|
156
|
+
prio.entity_timestamp = 0
|
|
157
|
+
else:
|
|
158
|
+
prio.entity_timestamp = 0
|
|
159
|
+
return prio
|
|
160
|
+
|
|
161
|
+
@staticmethod
|
|
162
|
+
def compute_fragment_depth(entity):
|
|
163
|
+
stack = entity.request.get("config", {}).get("fragment", {}).get("fragments_stack", [])
|
|
164
|
+
depth = 0
|
|
165
|
+
for key in stack:
|
|
166
|
+
try:
|
|
167
|
+
info = NifiFragmenter.get_fragment_info(entity, key)
|
|
168
|
+
if info.get("index", 0) != 0:
|
|
169
|
+
depth += 1
|
|
170
|
+
else:
|
|
171
|
+
break
|
|
172
|
+
except (KeyError, RuntimeError):
|
|
173
|
+
break
|
|
174
|
+
return min(depth, 9)
|
|
175
|
+
|
|
176
|
+
def to_string(self):
|
|
177
|
+
w = self.COMPONENT_WIDTHS
|
|
178
|
+
return self.SEPARATOR.join([
|
|
179
|
+
self.op_reserved,
|
|
180
|
+
self.user_prio,
|
|
181
|
+
self._encode_base62(self.fragment_prio, w[2]),
|
|
182
|
+
self._encode_base62(self.entity_timestamp, w[3]),
|
|
183
|
+
])
|
|
184
|
+
|
|
185
|
+
def to_dict(self):
|
|
186
|
+
return {
|
|
187
|
+
"op_reserved": self.op_reserved,
|
|
188
|
+
"user_prio": self.user_prio,
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
def apply_to_entity(self, entity):
|
|
192
|
+
entity.request["priority"] = self.to_dict()
|
|
193
|
+
|
|
194
|
+
|
|
57
195
|
class NifiProxyEntityModel(BaseModel):
|
|
58
196
|
entity_id: str
|
|
59
197
|
entity_type: str
|
|
@@ -86,6 +224,7 @@ class NifiEntityModel(BaseModel):
|
|
|
86
224
|
exception: dict = Field(default_factory=dict)
|
|
87
225
|
last_processor_name: Optional[str] = None
|
|
88
226
|
fallback_os_workspace: Optional[str] = None
|
|
227
|
+
priority: dict = Field(default_factory=dict)
|
|
89
228
|
|
|
90
229
|
class RecordModel(BaseModel):
|
|
91
230
|
model_config = ConfigDict(extra="allow")
|
|
@@ -528,6 +667,8 @@ class NifiContextManager(object):
|
|
|
528
667
|
key=lambda x: string_to_datetime(x.request.get("entity_timestamp")),
|
|
529
668
|
)
|
|
530
669
|
entities = list({e.record["entity_id"]: e for e in entities}.values())
|
|
670
|
+
for entity in entities:
|
|
671
|
+
NifiPriority.from_entity(entity).apply_to_entity(entity)
|
|
531
672
|
entities = [
|
|
532
673
|
(
|
|
533
674
|
jsondict_hash(NifiContextManager._config_get(entity, processor_name)),
|
|
@@ -602,6 +743,9 @@ class NifiContextManager(object):
|
|
|
602
743
|
)
|
|
603
744
|
self.out_entities = list({e.record["entity_id"]: e for e in all_entities}.values())
|
|
604
745
|
self.sync_entities()
|
|
746
|
+
for entity in self.out_entities:
|
|
747
|
+
prio = NifiPriority.from_entity(entity)
|
|
748
|
+
entity.request["nifi_attributes"]["priority"] = prio.to_string()
|
|
605
749
|
return [entity for entity in self.jsonify(self.out_entities)["content"]]
|
|
606
750
|
|
|
607
751
|
def raise_exception(self, entity, exc):
|
|
@@ -1020,6 +1164,29 @@ class NifiEntity(object):
|
|
|
1020
1164
|
options={"verify_signature": False},
|
|
1021
1165
|
)
|
|
1022
1166
|
|
|
1167
|
+
@property
|
|
1168
|
+
def priority(self):
|
|
1169
|
+
return NifiPriority.from_entity(self)
|
|
1170
|
+
|
|
1171
|
+
@priority.setter
|
|
1172
|
+
def priority(self, value):
|
|
1173
|
+
if isinstance(value, NifiPriority):
|
|
1174
|
+
self.request["priority"] = value.to_dict()
|
|
1175
|
+
elif isinstance(value, dict):
|
|
1176
|
+
self.request["priority"] = value
|
|
1177
|
+
else:
|
|
1178
|
+
raise TypeError("priority must be a NifiPriority or dict")
|
|
1179
|
+
|
|
1180
|
+
def set_user_priority(self, value):
|
|
1181
|
+
prio = self.priority
|
|
1182
|
+
prio.user_prio = NifiPriority._normalize_component(value, NifiPriority.COMPONENT_WIDTHS[1])
|
|
1183
|
+
self.priority = prio
|
|
1184
|
+
|
|
1185
|
+
def set_op_priority(self, value):
|
|
1186
|
+
prio = self.priority
|
|
1187
|
+
prio.op_reserved = NifiPriority._normalize_component(value, NifiPriority.COMPONENT_WIDTHS[0])
|
|
1188
|
+
self.priority = prio
|
|
1189
|
+
|
|
1023
1190
|
def update_last_timestamp(self):
|
|
1024
1191
|
self.record["os_last_updated_at"] = now()
|
|
1025
1192
|
|
|
@@ -1211,6 +1378,7 @@ class NifiEntity(object):
|
|
|
1211
1378
|
"exception": {},
|
|
1212
1379
|
"last_processor_name": None,
|
|
1213
1380
|
"fallback_os_workspace": self.request["fallback_os_workspace"],
|
|
1381
|
+
"priority": deepcopy(self.request.get("priority", {})),
|
|
1214
1382
|
}
|
|
1215
1383
|
child_entity = NifiEntity(
|
|
1216
1384
|
self.context,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|