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.
@@ -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.flow_args, **flow.flow_kwargs) # which is then used by the Task.find_flow method to find it
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.flow_args, **self.flow_kwargs) # if the flow is sync, just execute the flow target
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'
@@ -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, dict):
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.56.0
1
+ v1.58.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: osbot_utils
3
- Version: 1.56.0
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
- ![Current Release](https://img.shields.io/badge/release-v1.56.0-blue)
25
+ ![Current Release](https://img.shields.io/badge/release-v1.58.0-blue)
26
26
  [![codecov](https://codecov.io/gh/owasp-sbot/OSBot-Utils/graph/badge.svg?token=GNVW0COX1N)](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=iO-4B0uIv31n66INoXpodoYss5eEsOEGu3LDFevkKQ8,7626
158
- osbot_utils/helpers/flows/Flow__Events.py,sha256=Gy5P130Bz5RtRV7NaV5Iss4wZrjLdVxaps1r02kQLCk,2123
159
- osbot_utils/helpers/flows/Task.py,sha256=ITR6qFd_BWEFtWJ5wZUFcxq3A3FyN4YzU7_CeIuUph0,4809
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=YSOjzcRjCHmF_AIoWiccoNH0EAmNdTSmObXYB5exTGw,277
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=oiWF75BPahRtBRhFrQi_5Mv4wrqkjJnKAc_diw9CZdk,17321
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=Tr_IKFeVZOtzWeW8sdbz6QZge0TiRXb54jrSp_tV3_s,8
306
- osbot_utils-1.56.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
307
- osbot_utils-1.56.0.dist-info/METADATA,sha256=BkDSFwnvPd92g4ESDYOX5lwCnwWG8n5wBeDH33WfP60,1266
308
- osbot_utils-1.56.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
309
- osbot_utils-1.56.0.dist-info/RECORD,,
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,,