osbot-utils 1.56.0__py3-none-any.whl → 1.58.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.
- osbot_utils/helpers/flows/Flow.py +36 -8
- osbot_utils/helpers/flows/Flow__Events.py +8 -0
- osbot_utils/helpers/flows/Task.py +3 -1
- osbot_utils/helpers/flows/models/Flow__Event_Type.py +2 -0
- osbot_utils/utils/Objects.py +2 -1
- osbot_utils/version +1 -1
- {osbot_utils-1.56.0.dist-info → osbot_utils-1.58.0.dist-info}/METADATA +2 -2
- {osbot_utils-1.56.0.dist-info → osbot_utils-1.58.0.dist-info}/RECORD +10 -10
- {osbot_utils-1.56.0.dist-info → osbot_utils-1.58.0.dist-info}/LICENSE +0 -0
- {osbot_utils-1.56.0.dist-info → osbot_utils-1.58.0.dist-info}/WHEEL +0 -0
@@ -2,6 +2,8 @@ import asyncio
|
|
2
2
|
import logging
|
3
3
|
import typing
|
4
4
|
|
5
|
+
from osbot_utils.helpers.Dependency_Manager import Dependency_Manager
|
6
|
+
|
5
7
|
from osbot_utils.base_classes.Type_Safe import Type_Safe
|
6
8
|
from osbot_utils.helpers.CFormat import CFormat, f_dark_grey, f_magenta, f_bold
|
7
9
|
from osbot_utils.helpers.flows.models.Flow__Config import Flow__Config
|
@@ -33,8 +35,23 @@ class Flow(Type_Safe):
|
|
33
35
|
logger : Python_Logger
|
34
36
|
cformat : CFormat
|
35
37
|
executed_tasks : typing.List
|
38
|
+
resolved_args : tuple
|
39
|
+
resolved_kwargs : dict
|
40
|
+
|
41
|
+
def add_flow_artifact(self, description=None, key=None, data=None, artifact_type=None): # todo: figure out how to make this work since at the moment most are showing an unknown type
|
42
|
+
result_data = dict(flow_run_id = self.flow_id,
|
43
|
+
description = description or 'description' ,
|
44
|
+
key = key or 'an-artifact-key' ,
|
45
|
+
data = data or {"link": "https://www.google.com", "link_text": "link to Google"}, # test data to see if it worksw
|
46
|
+
type = artifact_type or "link" ) # type clashed with built-in type
|
36
47
|
|
48
|
+
flow_events.on__new_artifact(self, result_data )
|
37
49
|
|
50
|
+
def add_flow_result(self, key, description):
|
51
|
+
result_data = dict(flow_run_id = self.flow_id,
|
52
|
+
key = key ,
|
53
|
+
description = description )
|
54
|
+
flow_events.on__new_result(self, result_data )
|
38
55
|
|
39
56
|
def config_logger(self):
|
40
57
|
with self.logger as _:
|
@@ -56,6 +73,7 @@ class Flow(Type_Safe):
|
|
56
73
|
self.logger.add_memory_logger() # todo: move to method that does pre-execute tasks
|
57
74
|
|
58
75
|
self.log_debug(f"Executing flow run '{self.f__flow_id()}'")
|
76
|
+
self.resolve_args_and_kwargs()
|
59
77
|
try:
|
60
78
|
with Stdout() as stdout:
|
61
79
|
self.invoke_flow_target()
|
@@ -70,28 +88,31 @@ class Flow(Type_Safe):
|
|
70
88
|
if self.flow_config.log_to_memory:
|
71
89
|
self.captured_exec_logs = self.log_messages_with_colors()
|
72
90
|
self.logger.remove_memory_logger() # todo: move to method that does post-execute tasks
|
91
|
+
if self.flow_return_value:
|
92
|
+
self.add_flow_result(key = 'flow-return-value', description=f'{self.flow_return_value}')
|
73
93
|
flow_events.on__flow__stop(self)
|
74
94
|
return self
|
75
95
|
|
76
|
-
def f__flow_id(self):
|
77
|
-
return self.cformat.green(self.flow_id)
|
78
|
-
|
79
|
-
def f__flow_name(self):
|
80
|
-
return self.cformat.blue(self.flow_name)
|
81
|
-
|
82
96
|
def captured_logs(self):
|
83
97
|
return ansis_to_texts(self.captured_exec_logs)
|
84
98
|
|
85
99
|
|
86
100
|
async def invoke_flow_target__thread(self, flow): # this is a REALLY important method which is used to pin the flow object to the call stack
|
87
|
-
return await flow.flow_target(*flow.
|
101
|
+
return await flow.flow_target(*flow.resolved_args, **flow.resolved_kwargs) # which is then used by the Task.find_flow method to find it
|
88
102
|
|
89
103
|
def invoke_flow_target(self):
|
90
104
|
if asyncio.iscoroutinefunction(self.flow_target):
|
91
105
|
async_coroutine = self.invoke_flow_target__thread(self) # use this special method to pin the flow object to the call stack
|
92
106
|
self.flow_return_value = invoke_in_new_event_loop(async_coroutine) # this will start a complete new thread to execute the flow (which is exactly what we want)
|
93
107
|
else:
|
94
|
-
self.flow_return_value = self.flow_target(*self.
|
108
|
+
self.flow_return_value = self.flow_target(*self.resolved_args, **self.resolved_kwargs) # if the flow is sync, just execute the flow target
|
109
|
+
|
110
|
+
def f__flow_id(self):
|
111
|
+
return self.cformat.green(self.flow_id)
|
112
|
+
|
113
|
+
def f__flow_name(self):
|
114
|
+
return self.cformat.blue(self.flow_name)
|
115
|
+
|
95
116
|
|
96
117
|
def log_captured_stdout(self, stdout):
|
97
118
|
for line in stdout.value().splitlines():
|
@@ -162,6 +183,13 @@ class Flow(Type_Safe):
|
|
162
183
|
def random_flow_name(self):
|
163
184
|
return lower(random_id(prefix=FLOW__RANDOM_NAME__PREFIX))
|
164
185
|
|
186
|
+
def resolve_args_and_kwargs(self):
|
187
|
+
dependency_manager = Dependency_Manager()
|
188
|
+
dependency_manager.add_dependency('this_flow', self)
|
189
|
+
dependency_manager.add_dependency('flow_data', self.data)
|
190
|
+
self.resolved_args, self.resolved_kwargs = dependency_manager.resolve_dependencies(self.flow_target,
|
191
|
+
*self.flow_args,
|
192
|
+
**self.flow_kwargs)
|
165
193
|
|
166
194
|
def set_flow_target(self, target, *args, **kwargs):
|
167
195
|
self.flow_target = target
|
@@ -27,6 +27,14 @@ class Flow_Events(Type_Safe):
|
|
27
27
|
flow_event = Flow__Event(event_type=Flow__Event_Type.FLOW_MESSAGE, event_source=flow, event_data=event_data)
|
28
28
|
self.raise_event(flow_event)
|
29
29
|
|
30
|
+
def on__new_artifact(self, flow, result_data):
|
31
|
+
flow_event = Flow__Event(event_type=Flow__Event_Type.NEW_ARTIFACT , event_source=flow, event_data=result_data)
|
32
|
+
self.raise_event(flow_event)
|
33
|
+
|
34
|
+
def on__new_result(self, flow, result_data):
|
35
|
+
flow_event = Flow__Event(event_type=Flow__Event_Type.NEW_RESULT , event_source=flow, event_data=result_data)
|
36
|
+
self.raise_event(flow_event)
|
37
|
+
|
30
38
|
def on__task__start(self, task):
|
31
39
|
flow_event = Flow__Event(event_type=Flow__Event_Type.TASK_START, event_source=task)
|
32
40
|
self.raise_event(flow_event)
|
@@ -61,6 +61,9 @@ class Task(Type_Safe):
|
|
61
61
|
|
62
62
|
self.task_flow.executed_tasks.append(self)
|
63
63
|
self.log_debug(f"Executing task '{f_blue(self.task_name)}'")
|
64
|
+
self.resolve_args_and_kwargs()
|
65
|
+
|
66
|
+
def resolve_args_and_kwargs(self):
|
64
67
|
dependency_manager = Dependency_Manager()
|
65
68
|
dependency_manager.add_dependency('this_task', self )
|
66
69
|
dependency_manager.add_dependency('this_flow', self.task_flow )
|
@@ -68,7 +71,6 @@ class Task(Type_Safe):
|
|
68
71
|
dependency_manager.add_dependency('flow_data', self.task_flow.data)
|
69
72
|
self.resolved_args, self.resolved_kwargs = dependency_manager.resolve_dependencies(self.task_target, *self.task_args, **self.task_kwargs)
|
70
73
|
|
71
|
-
|
72
74
|
def execute__task_target__sync(self):
|
73
75
|
try:
|
74
76
|
with Stdout() as stdout:
|
@@ -4,5 +4,7 @@ class Flow__Event_Type(Type_Safe):
|
|
4
4
|
FLOW_MESSAGE: str = 'flow_message'
|
5
5
|
FLOW_START : str = 'flow_start'
|
6
6
|
FLOW_STOP : str = 'flow_stop'
|
7
|
+
NEW_ARTIFACT: str = 'new_artifact'
|
8
|
+
NEW_RESULT : str = 'new_result'
|
7
9
|
TASK_START : str = 'task_start'
|
8
10
|
TASK_STOP : str = 'task_stop'
|
osbot_utils/utils/Objects.py
CHANGED
@@ -4,6 +4,7 @@ import pickle
|
|
4
4
|
import sys
|
5
5
|
import types
|
6
6
|
import typing
|
7
|
+
from collections.abc import Mapping
|
7
8
|
|
8
9
|
from typing import Union
|
9
10
|
from types import SimpleNamespace
|
@@ -124,7 +125,7 @@ def dict_remove(data, target):
|
|
124
125
|
|
125
126
|
def dict_to_obj(target, class_name="_"):
|
126
127
|
DynamicClass = type(class_name, (SimpleNamespace,), {})
|
127
|
-
if isinstance(target,
|
128
|
+
if isinstance(target, Mapping):
|
128
129
|
new_dict = {}
|
129
130
|
for key, value in target.items():
|
130
131
|
new_dict[key] = dict_to_obj(value, class_name=class_name) # Recursively convert elements in the dict
|
osbot_utils/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
v1.
|
1
|
+
v1.58.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.58.0
|
4
4
|
Summary: OWASP Security Bot - Utils
|
5
5
|
Home-page: https://github.com/owasp-sbot/OSBot-Utils
|
6
6
|
License: MIT
|
@@ -22,7 +22,7 @@ Description-Content-Type: text/markdown
|
|
22
22
|
|
23
23
|
Powerful Python util methods and classes that simplify common apis and tasks.
|
24
24
|
|
25
|
-

|
26
26
|
[](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
|
27
27
|
|
28
28
|
|
@@ -154,16 +154,16 @@ osbot_utils/helpers/cache_requests/Cache__Requests__Row.py,sha256=h-yc7NkpScbHww
|
|
154
154
|
osbot_utils/helpers/cache_requests/Cache__Requests__Table.py,sha256=RgxAYhm-FIrXXteQRtD91pOLq8JXhSzxb51Jb6MTUdY,391
|
155
155
|
osbot_utils/helpers/cache_requests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
156
156
|
osbot_utils/helpers/cache_requests/flows/flow__Cache__Requests.py,sha256=xgx_oExxkcvRwQN1UCobimECIMUKGoIX5oGdCmp8Nyw,243
|
157
|
-
osbot_utils/helpers/flows/Flow.py,sha256=
|
158
|
-
osbot_utils/helpers/flows/Flow__Events.py,sha256=
|
159
|
-
osbot_utils/helpers/flows/Task.py,sha256=
|
157
|
+
osbot_utils/helpers/flows/Flow.py,sha256=m5j9OxR_xDgMh2z9u2FVQN_cQTQV_juJjbbNiNS8BuI,9645
|
158
|
+
osbot_utils/helpers/flows/Flow__Events.py,sha256=u9GzVNd08Hr49ZRIpoRDhwJnAHUFB-XzFzmNw-r3_Q0,2535
|
159
|
+
osbot_utils/helpers/flows/Task.py,sha256=ifPm0aqUG4sWAUTaYwT7ig-7Y9JmG9YTiNyC3dOX5sw,4887
|
160
160
|
osbot_utils/helpers/flows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
161
161
|
osbot_utils/helpers/flows/decorators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
162
162
|
osbot_utils/helpers/flows/decorators/flow.py,sha256=LUL7bHjZ_lC3QoTNh-KsDZHzjE2u4mU-5EpZnfsEGuc,738
|
163
163
|
osbot_utils/helpers/flows/decorators/task.py,sha256=9bhQBPJU1dO-J4FAsFkmxqQMBNtay4FT_b1BdpHJ9sA,734
|
164
164
|
osbot_utils/helpers/flows/models/Flow__Config.py,sha256=NLIfT0S8zxbig6Q1p9KeoyE2qRVWorHxk-JXCv9Yx-U,382
|
165
165
|
osbot_utils/helpers/flows/models/Flow__Event.py,sha256=O2SNmDG8FTsQQqm5tWmbomQsC_usA7EqMQhTWIFl4KM,157
|
166
|
-
osbot_utils/helpers/flows/models/Flow__Event_Type.py,sha256=
|
166
|
+
osbot_utils/helpers/flows/models/Flow__Event_Type.py,sha256=vPDW-7D96Sjn0X6-V1Xgp4ytQ58SgSbX0kyflXNwmK4,353
|
167
167
|
osbot_utils/helpers/flows/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
168
168
|
osbot_utils/helpers/html/Dict_To_Css.py,sha256=u6B4Mx7PXr-gDrTrs1hgknnvsZVK4Fic5LqedKjo-lk,1097
|
169
169
|
osbot_utils/helpers/html/Dict_To_Html.py,sha256=OlRSaDGOeseBNTxRB2ho5whqEacMXeAXWOfeVSEYqC4,3355
|
@@ -290,7 +290,7 @@ osbot_utils/utils/Json.py,sha256=7COxBlZRnpxtpNqpmzMPYkcKTnCok-s686nT27oiKEQ,648
|
|
290
290
|
osbot_utils/utils/Json_Cache.py,sha256=mLPkkDZN-3ZVJiDvV1KBJXILtKkTZ4OepzOsDoBPhWg,2006
|
291
291
|
osbot_utils/utils/Lists.py,sha256=tPz5x5s3sRO97WZ_nsxREBPC5cwaHrhgaYBhsrffTT8,5599
|
292
292
|
osbot_utils/utils/Misc.py,sha256=nODZT6p44B4xYiIiqfEeKYEErQiKR9SGthhGtZWGhkI,16804
|
293
|
-
osbot_utils/utils/Objects.py,sha256=
|
293
|
+
osbot_utils/utils/Objects.py,sha256=60OFmwQZgqyfmOGS_WtD59-b0lB7rGhqWoh0tgkBKOc,17367
|
294
294
|
osbot_utils/utils/Png.py,sha256=V1juGp6wkpPigMJ8HcxrPDIP4bSwu51oNkLI8YqP76Y,1172
|
295
295
|
osbot_utils/utils/Process.py,sha256=lr3CTiEkN3EiBx3ZmzYmTKlQoPdkgZBRjPulMxG-zdo,2357
|
296
296
|
osbot_utils/utils/Python_Logger.py,sha256=tx8N6wRKL3RDHboDRKZn8SirSJdSAE9cACyJkxrThZ8,12792
|
@@ -302,8 +302,8 @@ osbot_utils/utils/Toml.py,sha256=SD6IA4-mrtoBXcI0dIGKV9POMQNd6WYKvmDQq7GQ6ZQ,143
|
|
302
302
|
osbot_utils/utils/Version.py,sha256=Ww6ChwTxqp1QAcxOnztkTicShlcx6fbNsWX5xausHrg,422
|
303
303
|
osbot_utils/utils/Zip.py,sha256=G6Hk_hDcm9yvWzhTKzhT0R_6f0NBIAchHqMxGb3kfh4,14037
|
304
304
|
osbot_utils/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
305
|
-
osbot_utils/version,sha256=
|
306
|
-
osbot_utils-1.
|
307
|
-
osbot_utils-1.
|
308
|
-
osbot_utils-1.
|
309
|
-
osbot_utils-1.
|
305
|
+
osbot_utils/version,sha256=3zcuCY19oU6Xohxuk7cSp-mCBuuGU7OwYkdC8RVRMgw,8
|
306
|
+
osbot_utils-1.58.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
307
|
+
osbot_utils-1.58.0.dist-info/METADATA,sha256=jOtdSqjuFy3-p5D93fRccvYUYdAyQuM3irMTOpltDhw,1266
|
308
|
+
osbot_utils-1.58.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
309
|
+
osbot_utils-1.58.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|