flowcept 0.8.9__py3-none-any.whl → 0.8.11__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.
- flowcept/cli.py +460 -0
- flowcept/commons/daos/keyvalue_dao.py +19 -23
- flowcept/commons/daos/mq_dao/mq_dao_base.py +29 -29
- flowcept/commons/daos/mq_dao/mq_dao_kafka.py +4 -3
- flowcept/commons/daos/mq_dao/mq_dao_mofka.py +4 -0
- flowcept/commons/daos/mq_dao/mq_dao_redis.py +38 -5
- flowcept/commons/daos/redis_conn.py +47 -0
- flowcept/commons/flowcept_dataclasses/task_object.py +36 -8
- flowcept/commons/settings_factory.py +2 -4
- flowcept/commons/task_data_preprocess.py +200 -0
- flowcept/commons/utils.py +1 -1
- flowcept/configs.py +11 -9
- flowcept/flowcept_api/flowcept_controller.py +30 -13
- flowcept/flowceptor/adapters/agents/__init__.py +1 -0
- flowcept/flowceptor/adapters/agents/agents_utils.py +89 -0
- flowcept/flowceptor/adapters/agents/flowcept_agent.py +292 -0
- flowcept/flowceptor/adapters/agents/flowcept_llm_prov_capture.py +186 -0
- flowcept/flowceptor/adapters/agents/prompts.py +51 -0
- flowcept/flowceptor/adapters/base_interceptor.py +17 -19
- flowcept/flowceptor/adapters/brokers/__init__.py +1 -0
- flowcept/flowceptor/adapters/brokers/mqtt_interceptor.py +132 -0
- flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py +3 -3
- flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py +3 -3
- flowcept/flowceptor/consumers/agent/__init__.py +1 -0
- flowcept/flowceptor/consumers/agent/base_agent_context_manager.py +101 -0
- flowcept/flowceptor/consumers/agent/client_agent.py +48 -0
- flowcept/flowceptor/consumers/agent/flowcept_agent_context_manager.py +145 -0
- flowcept/flowceptor/consumers/agent/flowcept_qa_manager.py +112 -0
- flowcept/flowceptor/consumers/base_consumer.py +90 -0
- flowcept/flowceptor/consumers/document_inserter.py +138 -53
- flowcept/flowceptor/telemetry_capture.py +1 -1
- flowcept/instrumentation/task_capture.py +19 -9
- flowcept/version.py +1 -1
- {flowcept-0.8.9.dist-info → flowcept-0.8.11.dist-info}/METADATA +18 -6
- {flowcept-0.8.9.dist-info → flowcept-0.8.11.dist-info}/RECORD +39 -25
- flowcept-0.8.11.dist-info/entry_points.txt +2 -0
- resources/sample_settings.yaml +44 -23
- flowcept/flowceptor/adapters/zambeze/__init__.py +0 -1
- flowcept/flowceptor/adapters/zambeze/zambeze_dataclasses.py +0 -41
- flowcept/flowceptor/adapters/zambeze/zambeze_interceptor.py +0 -102
- {flowcept-0.8.9.dist-info → flowcept-0.8.11.dist-info}/WHEEL +0 -0
- {flowcept-0.8.9.dist-info → flowcept-0.8.11.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from threading import Thread
|
|
4
4
|
from time import time, sleep
|
|
5
|
-
from typing import Dict
|
|
5
|
+
from typing import Dict, Callable, Tuple
|
|
6
6
|
from uuid import uuid4
|
|
7
7
|
|
|
8
|
+
from flowcept.commons.task_data_preprocess import summarize_telemetry, tag_critical_task
|
|
9
|
+
from flowcept.flowceptor.consumers.base_consumer import BaseConsumer
|
|
8
10
|
from flowcept.commons.autoflush_buffer import AutoflushBuffer
|
|
9
|
-
from flowcept.commons.daos.mq_dao.mq_dao_base import MQDao
|
|
10
11
|
from flowcept.commons.flowcept_dataclasses.task_object import TaskObject
|
|
11
12
|
from flowcept.commons.flowcept_dataclasses.workflow_object import (
|
|
12
13
|
WorkflowObject,
|
|
@@ -16,11 +17,9 @@ from flowcept.commons.utils import GenericJSONDecoder
|
|
|
16
17
|
from flowcept.commons.vocabulary import Status
|
|
17
18
|
from flowcept.configs import (
|
|
18
19
|
INSERTION_BUFFER_TIME,
|
|
19
|
-
|
|
20
|
-
DB_MIN_BUFFER_SIZE,
|
|
20
|
+
DB_BUFFER_SIZE,
|
|
21
21
|
DB_INSERTER_MAX_TRIALS_STOP,
|
|
22
22
|
DB_INSERTER_SLEEP_TRIALS_STOP,
|
|
23
|
-
ADAPTIVE_DB_BUFFER_SIZE,
|
|
24
23
|
REMOVE_EMPTY_FIELDS,
|
|
25
24
|
JSON_SERIALIZER,
|
|
26
25
|
ENRICH_MESSAGES,
|
|
@@ -32,8 +31,18 @@ from flowcept.flowceptor.consumers.consumer_utils import (
|
|
|
32
31
|
)
|
|
33
32
|
|
|
34
33
|
|
|
35
|
-
class DocumentInserter:
|
|
36
|
-
"""
|
|
34
|
+
class DocumentInserter(BaseConsumer):
|
|
35
|
+
"""
|
|
36
|
+
DocumentInserter is a message consumer in Flowcept.
|
|
37
|
+
|
|
38
|
+
It handles messages related to tasks, workflows, and control signals, processes them
|
|
39
|
+
(e.g., adds metadata, sanitizes fields), and then inserts them into one or more configured
|
|
40
|
+
document databases (e.g., MongoDB, LMDB). It buffers incoming messages to reduce insertion
|
|
41
|
+
overhead and supports both time-based and size-based flushing.
|
|
42
|
+
|
|
43
|
+
The inserter is intended to run in a thread or process alongside other Flowcept consumers,
|
|
44
|
+
ensuring provenance data is persisted reliably and in a structured format.
|
|
45
|
+
"""
|
|
37
46
|
|
|
38
47
|
DECODER = GenericJSONDecoder if JSON_SERIALIZER == "complex" else None
|
|
39
48
|
|
|
@@ -54,8 +63,8 @@ class DocumentInserter:
|
|
|
54
63
|
check_safe_stops=True,
|
|
55
64
|
bundle_exec_id=None,
|
|
56
65
|
):
|
|
57
|
-
self._mq_dao = MQDao.build()
|
|
58
66
|
self._doc_daos = []
|
|
67
|
+
self.logger = FlowceptLogger()
|
|
59
68
|
if MONGO_ENABLED:
|
|
60
69
|
from flowcept.commons.daos.docdb_dao.mongodb_dao import MongoDBDAO
|
|
61
70
|
|
|
@@ -64,34 +73,38 @@ class DocumentInserter:
|
|
|
64
73
|
from flowcept.commons.daos.docdb_dao.lmdb_dao import LMDBDAO
|
|
65
74
|
|
|
66
75
|
self._doc_daos.append(LMDBDAO())
|
|
76
|
+
self._should_start = True
|
|
77
|
+
if not len(self._doc_daos):
|
|
78
|
+
self._should_start = False
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
super().__init__()
|
|
67
82
|
self._previous_time = time()
|
|
68
|
-
self.logger = FlowceptLogger()
|
|
69
83
|
self._main_thread: Thread = None
|
|
70
|
-
self.
|
|
84
|
+
self._curr_db_buffer_size = DB_BUFFER_SIZE
|
|
71
85
|
self._bundle_exec_id = bundle_exec_id
|
|
72
86
|
self.check_safe_stops = check_safe_stops
|
|
73
87
|
self.buffer: AutoflushBuffer = AutoflushBuffer(
|
|
74
88
|
flush_function=DocumentInserter.flush_function,
|
|
75
89
|
flush_function_kwargs={"logger": self.logger, "doc_daos": self._doc_daos},
|
|
76
|
-
max_size=self.
|
|
90
|
+
max_size=self._curr_db_buffer_size,
|
|
77
91
|
flush_interval=INSERTION_BUFFER_TIME,
|
|
78
92
|
)
|
|
79
93
|
|
|
80
|
-
def _set_buffer_size(self):
|
|
81
|
-
if not ADAPTIVE_DB_BUFFER_SIZE:
|
|
82
|
-
return
|
|
83
|
-
else:
|
|
84
|
-
self._curr_max_buffer_size = max(
|
|
85
|
-
DB_MIN_BUFFER_SIZE,
|
|
86
|
-
min(
|
|
87
|
-
DB_MAX_BUFFER_SIZE,
|
|
88
|
-
int(self._curr_max_buffer_size * 1.1),
|
|
89
|
-
),
|
|
90
|
-
)
|
|
91
|
-
|
|
92
94
|
@staticmethod
|
|
93
95
|
def flush_function(buffer, doc_daos, logger):
|
|
94
|
-
"""
|
|
96
|
+
"""
|
|
97
|
+
Flush the buffer contents to all configured document databases.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
buffer : list
|
|
102
|
+
List of messages to be flushed to the databases.
|
|
103
|
+
doc_daos : list
|
|
104
|
+
List of DAO instances to insert data into (e.g., MongoDBDAO, LMDBDAO).
|
|
105
|
+
logger : FlowceptLogger
|
|
106
|
+
Logger instance for debug and info logging.
|
|
107
|
+
"""
|
|
95
108
|
logger.info(f"Current Doc buffer size: {len(buffer)}, Gonna flush {len(buffer)} msgs to DocDBs!")
|
|
96
109
|
for dao in doc_daos:
|
|
97
110
|
dao.insert_and_update_many_tasks(buffer, TaskObject.task_id_field())
|
|
@@ -107,9 +120,12 @@ class DocumentInserter:
|
|
|
107
120
|
message["workflow_id"] = wf_id
|
|
108
121
|
|
|
109
122
|
if "campaign_id" not in message:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
123
|
+
try:
|
|
124
|
+
campaign_id = self._mq_dao._keyvalue_dao.get_key("current_campaign_id")
|
|
125
|
+
if campaign_id:
|
|
126
|
+
message["campaign_id"] = campaign_id
|
|
127
|
+
except Exception as e:
|
|
128
|
+
self.logger.error(e)
|
|
113
129
|
|
|
114
130
|
if "subtype" not in message and "group_id" in message:
|
|
115
131
|
message["subtype"] = "iteration"
|
|
@@ -127,6 +143,23 @@ class DocumentInserter:
|
|
|
127
143
|
|
|
128
144
|
if ENRICH_MESSAGES:
|
|
129
145
|
TaskObject.enrich_task_dict(message)
|
|
146
|
+
if (
|
|
147
|
+
"telemetry_at_start" in message
|
|
148
|
+
and message["telemetry_at_start"]
|
|
149
|
+
and "telemetry_at_end" in message
|
|
150
|
+
and message["telemetry_at_end"]
|
|
151
|
+
):
|
|
152
|
+
try:
|
|
153
|
+
telemetry_summary = summarize_telemetry(message)
|
|
154
|
+
message["telemetry_summary"] = telemetry_summary
|
|
155
|
+
# TODO: make this dynamic
|
|
156
|
+
tags = tag_critical_task(
|
|
157
|
+
generated=message.get("generated", {}), telemetry_summary=telemetry_summary, thresholds=None
|
|
158
|
+
)
|
|
159
|
+
if tags:
|
|
160
|
+
message["tags"] = tags
|
|
161
|
+
except Exception as e:
|
|
162
|
+
self.logger.error(e) # TODO: check if cpu, etc is in the fields in for the telemetry_summary
|
|
130
163
|
|
|
131
164
|
if REMOVE_EMPTY_FIELDS:
|
|
132
165
|
remove_empty_fields_from_dict(message)
|
|
@@ -153,36 +186,71 @@ class DocumentInserter:
|
|
|
153
186
|
f"in DocInserter from the interceptor "
|
|
154
187
|
f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
|
|
155
188
|
)
|
|
156
|
-
self.
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
189
|
+
if self.check_safe_stops:
|
|
190
|
+
self.logger.info(
|
|
191
|
+
f"Begin register_time_based_thread_end "
|
|
192
|
+
f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
|
|
193
|
+
)
|
|
194
|
+
self._mq_dao.register_time_based_thread_end(interceptor_instance_id, exec_bundle_id)
|
|
195
|
+
self.logger.info(
|
|
196
|
+
f"Done register_time_based_thread_end "
|
|
197
|
+
f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
|
|
198
|
+
)
|
|
165
199
|
return "continue"
|
|
166
200
|
elif message["info"] == "stop_document_inserter":
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
201
|
+
exec_bundle_id = message.get("exec_bundle_id", None)
|
|
202
|
+
if self._bundle_exec_id == exec_bundle_id:
|
|
203
|
+
self.logger.info(f"Document Inserter for exec_id {exec_bundle_id} is stopping...")
|
|
204
|
+
return "stop"
|
|
205
|
+
else:
|
|
206
|
+
return "continue"
|
|
207
|
+
|
|
208
|
+
def start(self, target: Callable = None, args: Tuple = (), threaded: bool = True, daemon=True):
|
|
209
|
+
"""
|
|
210
|
+
Start the DocumentInserter thread.
|
|
211
|
+
|
|
212
|
+
Parameters
|
|
213
|
+
----------
|
|
214
|
+
target : Callable, optional
|
|
215
|
+
Target function to run. Defaults to `self.thread_target`.
|
|
216
|
+
args : tuple, optional
|
|
217
|
+
Arguments to pass to the target function. Defaults to empty tuple.
|
|
218
|
+
threaded : bool, optional
|
|
219
|
+
Whether to run the inserter in a separate thread. Defaults to True.
|
|
220
|
+
daemon : bool, optional
|
|
221
|
+
Whether the thread should be a daemon. Defaults to True.
|
|
222
|
+
|
|
223
|
+
Returns
|
|
224
|
+
-------
|
|
225
|
+
DocumentInserter
|
|
226
|
+
The current instance of the DocumentInserter.
|
|
227
|
+
"""
|
|
228
|
+
if not self._should_start:
|
|
229
|
+
self.logger.info("Doc Inserter cannot start as all DocDBs are disabled.")
|
|
230
|
+
return self
|
|
231
|
+
super().start(target=self.thread_target, threaded=threaded, daemon=daemon)
|
|
178
232
|
return self
|
|
179
233
|
|
|
180
|
-
def
|
|
181
|
-
self.
|
|
234
|
+
def thread_target(self):
|
|
235
|
+
"""Function to be used in the self.start method."""
|
|
236
|
+
super().default_thread_target()
|
|
182
237
|
self.buffer.stop()
|
|
183
238
|
self.logger.info("Ok, we broke the doc inserter message listen loop!")
|
|
184
239
|
|
|
185
|
-
def
|
|
240
|
+
def message_handler(self, msg_obj: Dict):
|
|
241
|
+
"""
|
|
242
|
+
Overrides the message_handler method by determining message's type and dispatching to the appropriate handler.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
msg_obj : dict
|
|
247
|
+
The message object received from the message queue.
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
bool
|
|
252
|
+
False if a stop control message is received, True otherwise.
|
|
253
|
+
"""
|
|
186
254
|
msg_type = msg_obj.get("type")
|
|
187
255
|
if msg_type == "flowcept_control":
|
|
188
256
|
r = self._handle_control_message(msg_obj)
|
|
@@ -211,7 +279,22 @@ class DocumentInserter:
|
|
|
211
279
|
return True
|
|
212
280
|
|
|
213
281
|
def stop(self, bundle_exec_id=None):
|
|
214
|
-
"""
|
|
282
|
+
"""
|
|
283
|
+
Stop the DocumentInserter safely, waiting for all time-based threads to end.
|
|
284
|
+
|
|
285
|
+
Parameters
|
|
286
|
+
----------
|
|
287
|
+
bundle_exec_id : str, optional
|
|
288
|
+
The execution bundle ID to check for safe stopping. If None, will not use it as a filter.
|
|
289
|
+
|
|
290
|
+
Notes
|
|
291
|
+
-----
|
|
292
|
+
This method flushes remaining buffered data, stops internal threads,
|
|
293
|
+
closes database connections, and clears campaign state from the key-value store.
|
|
294
|
+
"""
|
|
295
|
+
if not self._should_start:
|
|
296
|
+
self.logger.info("Doc Inserter has not been started, so it can't stop.")
|
|
297
|
+
return self
|
|
215
298
|
if self.check_safe_stops:
|
|
216
299
|
trial = 0
|
|
217
300
|
while not self._mq_dao.all_time_based_threads_ended(bundle_exec_id):
|
|
@@ -230,12 +313,14 @@ class DocumentInserter:
|
|
|
230
313
|
msg = f"DocInserter {id(self)} gave up waiting for signal. "
|
|
231
314
|
self.logger.critical(msg + "Safe to stop now.")
|
|
232
315
|
break
|
|
316
|
+
self._mq_dao.delete_current_campaign_id()
|
|
317
|
+
|
|
233
318
|
self.logger.info("Sending message to stop document inserter.")
|
|
234
|
-
self._mq_dao.send_document_inserter_stop()
|
|
319
|
+
self._mq_dao.send_document_inserter_stop(exec_bundle_id=self._bundle_exec_id)
|
|
235
320
|
self.logger.info(f"Doc Inserter {id(self)} Sent message to stop itself.")
|
|
236
321
|
self._main_thread.join()
|
|
237
322
|
for dao in self._doc_daos:
|
|
238
323
|
self.logger.info(f"Closing document_inserter {dao.__class__.__name__} connection.")
|
|
239
324
|
dao.close()
|
|
240
|
-
|
|
325
|
+
|
|
241
326
|
self.logger.info("Document Inserter is stopped.")
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from time import time
|
|
2
2
|
from typing import Dict
|
|
3
|
+
import os
|
|
4
|
+
import threading
|
|
5
|
+
import random
|
|
3
6
|
|
|
4
7
|
from flowcept.commons.flowcept_dataclasses.task_object import (
|
|
5
8
|
TaskObject,
|
|
@@ -56,25 +59,24 @@ class FlowceptTask(object):
|
|
|
56
59
|
campaign_id: str = None,
|
|
57
60
|
activity_id: str = None,
|
|
58
61
|
used: Dict = None,
|
|
62
|
+
subtype: str = None,
|
|
59
63
|
custom_metadata: Dict = None,
|
|
60
|
-
flowcept: "Flowcept" = None,
|
|
61
64
|
):
|
|
62
65
|
if not INSTRUMENTATION_ENABLED:
|
|
63
66
|
self._ended = True
|
|
64
67
|
return
|
|
65
|
-
if flowcept is not None and flowcept._interceptor_instances[0].kind == "instrumentation":
|
|
66
|
-
self._interceptor = flowcept._interceptor_instances[0]
|
|
67
|
-
else:
|
|
68
|
-
self._interceptor = InstrumentationInterceptor.get_instance()
|
|
69
|
-
|
|
70
68
|
self._task = TaskObject()
|
|
71
|
-
self.
|
|
69
|
+
self._interceptor = InstrumentationInterceptor.get_instance()
|
|
70
|
+
tel = self._interceptor.telemetry_capture.capture()
|
|
71
|
+
if tel:
|
|
72
|
+
self._task.telemetry_at_start = tel
|
|
72
73
|
self._task.activity_id = activity_id
|
|
73
74
|
self._task.started_at = time()
|
|
74
|
-
self._task.task_id = task_id or
|
|
75
|
+
self._task.task_id = task_id or self._gen_task_id()
|
|
75
76
|
self._task.workflow_id = workflow_id or Flowcept.current_workflow_id
|
|
76
77
|
self._task.campaign_id = campaign_id or Flowcept.campaign_id
|
|
77
78
|
self._task.used = used
|
|
79
|
+
self._task.subtype = subtype
|
|
78
80
|
self._task.custom_metadata = custom_metadata
|
|
79
81
|
self._ended = False
|
|
80
82
|
|
|
@@ -85,6 +87,12 @@ class FlowceptTask(object):
|
|
|
85
87
|
if not self._ended:
|
|
86
88
|
self.end()
|
|
87
89
|
|
|
90
|
+
def _gen_task_id(self):
|
|
91
|
+
pid = os.getpid()
|
|
92
|
+
tid = threading.get_ident()
|
|
93
|
+
rand = random.getrandbits(32)
|
|
94
|
+
return f"{self._task.started_at}_{pid}_{tid}_{rand}"
|
|
95
|
+
|
|
88
96
|
def end(
|
|
89
97
|
self,
|
|
90
98
|
generated: Dict = None,
|
|
@@ -120,7 +128,9 @@ class FlowceptTask(object):
|
|
|
120
128
|
"""
|
|
121
129
|
if not INSTRUMENTATION_ENABLED:
|
|
122
130
|
return
|
|
123
|
-
|
|
131
|
+
tel = self._interceptor.telemetry_capture.capture()
|
|
132
|
+
if tel:
|
|
133
|
+
self._task.telemetry_at_end = tel
|
|
124
134
|
self._task.ended_at = ended_at or time()
|
|
125
135
|
self._task.status = status
|
|
126
136
|
self._task.stderr = stderr
|
flowcept/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowcept
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.11
|
|
4
4
|
Summary: Capture and query workflow provenance data using data observability
|
|
5
5
|
Project-URL: GitHub, https://github.com/ORNL/flowcept
|
|
6
6
|
Author: Oak Ridge National Laboratory
|
|
@@ -29,6 +29,7 @@ Requires-Dist: furo; extra == 'all'
|
|
|
29
29
|
Requires-Dist: jupyterlab; extra == 'all'
|
|
30
30
|
Requires-Dist: mlflow-skinny; extra == 'all'
|
|
31
31
|
Requires-Dist: nbmake; extra == 'all'
|
|
32
|
+
Requires-Dist: paho-mqtt; extra == 'all'
|
|
32
33
|
Requires-Dist: pika; extra == 'all'
|
|
33
34
|
Requires-Dist: plotly; extra == 'all'
|
|
34
35
|
Requires-Dist: pymongo; extra == 'all'
|
|
@@ -65,6 +66,12 @@ Requires-Dist: furo; extra == 'docs'
|
|
|
65
66
|
Requires-Dist: sphinx; extra == 'docs'
|
|
66
67
|
Provides-Extra: kafka
|
|
67
68
|
Requires-Dist: confluent-kafka<=2.8.0; extra == 'kafka'
|
|
69
|
+
Provides-Extra: llm-agent
|
|
70
|
+
Requires-Dist: faiss-cpu; extra == 'llm-agent'
|
|
71
|
+
Requires-Dist: langchain-community; extra == 'llm-agent'
|
|
72
|
+
Requires-Dist: mcp[cli]; extra == 'llm-agent'
|
|
73
|
+
Requires-Dist: sentence-transformers; extra == 'llm-agent'
|
|
74
|
+
Requires-Dist: tiktoken; extra == 'llm-agent'
|
|
68
75
|
Provides-Extra: ml-dev
|
|
69
76
|
Requires-Dist: datasets==2.17.0; extra == 'ml-dev'
|
|
70
77
|
Requires-Dist: nltk; extra == 'ml-dev'
|
|
@@ -80,6 +87,8 @@ Requires-Dist: sqlalchemy; extra == 'mlflow'
|
|
|
80
87
|
Requires-Dist: watchdog; extra == 'mlflow'
|
|
81
88
|
Provides-Extra: mongo
|
|
82
89
|
Requires-Dist: pymongo; extra == 'mongo'
|
|
90
|
+
Provides-Extra: mqtt
|
|
91
|
+
Requires-Dist: paho-mqtt; extra == 'mqtt'
|
|
83
92
|
Provides-Extra: nvidia
|
|
84
93
|
Requires-Dist: nvidia-ml-py; extra == 'nvidia'
|
|
85
94
|
Provides-Extra: tensorboard
|
|
@@ -112,7 +121,9 @@ Description-Content-Type: text/markdown
|
|
|
112
121
|
|
|
113
122
|
## Overview
|
|
114
123
|
|
|
115
|
-
Flowcept is a runtime data integration system that captures and queries workflow provenance with minimal or no code changes. It unifies data
|
|
124
|
+
Flowcept is a runtime data integration system that captures and queries workflow provenance with minimal or no code changes. It unifies data from diverse workflows and tools, enabling integrated analysis and insights, especially in federated environments.
|
|
125
|
+
|
|
126
|
+
Designed for scenarios involving critical data from multiple workflows, Flowcept supports end-to-end monitoring, analysis, querying, and enhanced support for Machine Learning (ML) workflows.
|
|
116
127
|
|
|
117
128
|
## Features
|
|
118
129
|
|
|
@@ -135,8 +146,9 @@ Notes:
|
|
|
135
146
|
- TensorBoard
|
|
136
147
|
- Python scripts can be easily instrumented via `@decorators` using `@flowcept_task` (for generic Python method) or `@torch_task` (for methods that encapsulate PyTorch model manipulation, such as training or evaluation).
|
|
137
148
|
- Currently supported MQ systems:
|
|
138
|
-
- Kafka
|
|
139
|
-
- Redis
|
|
149
|
+
- [Kafka](https://kafka.apache.org)
|
|
150
|
+
- [Redis](https://redis.io)
|
|
151
|
+
- [Mofka](https://mofka.readthedocs.io)
|
|
140
152
|
- Currently supported database systems:
|
|
141
153
|
- MongoDB
|
|
142
154
|
- Lightning Memory-Mapped Database (lightweight file-only database system)
|
|
@@ -181,7 +193,7 @@ If you want to install all optional dependencies, use:
|
|
|
181
193
|
pip install flowcept[all]
|
|
182
194
|
```
|
|
183
195
|
|
|
184
|
-
This is
|
|
196
|
+
This is useful mostly for Flowcept developers. Please avoid installing like this if you can, as it may install several dependencies you will never use.
|
|
185
197
|
|
|
186
198
|
### 4. Installing from Source
|
|
187
199
|
To install Flowcept from the source repository:
|
|
@@ -363,7 +375,7 @@ Some unit tests utilize `torch==2.2.2`, `torchtext=0.17.2`, and `torchvision==0.
|
|
|
363
375
|
|
|
364
376
|
## Documentation
|
|
365
377
|
|
|
366
|
-
Full documentation is available on [Read the Docs](https://
|
|
378
|
+
Full documentation is available on [Read the Docs](https://flowcept.readthedocs.io/).
|
|
367
379
|
|
|
368
380
|
## Cite us
|
|
369
381
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
flowcept/__init__.py,sha256=CukmdzTUvm6Y_plTKPq4kKn7w9LdR36j7V_C_UQyjhU,2011
|
|
2
|
-
flowcept/
|
|
3
|
-
flowcept/
|
|
2
|
+
flowcept/cli.py,sha256=5rFPMle_fyXNiOvAgfCh8eIqR_vZKoY3aXbeORU8bcY,15117
|
|
3
|
+
flowcept/configs.py,sha256=PyZ0svU0DKLeSNMaLq8G62zsOrSL2RO1mPZorjTQs_Q,7458
|
|
4
|
+
flowcept/version.py,sha256=kZzuCD8eKygfSNYWrKZruE9fLy68IKgtP2XirWNoQso,307
|
|
4
5
|
flowcept/analytics/__init__.py,sha256=46q-7vsHq_ddPNrzNnDgEOiRgvlx-5Ggu2ocyROMV0w,641
|
|
5
6
|
flowcept/analytics/analytics_utils.py,sha256=FRJdBtQa7Hrk2oR_FFhmhmMf3X6YyZ4nbH5RIYh7KL4,8753
|
|
6
7
|
flowcept/analytics/data_augmentation.py,sha256=Dyr5x316Zf-k1e8rVoQMCpFOrklYVHjfejRPrtoycmc,1641
|
|
@@ -9,28 +10,30 @@ flowcept/commons/__init__.py,sha256=W94CqapS0IGuuIGHHaz4sNuuiYhgtJWtpDEbnI0pGwI,
|
|
|
9
10
|
flowcept/commons/autoflush_buffer.py,sha256=8M0fcIeHck-mSGQ2HFpW3_Af8-dHswhIbUMX5FATm48,2589
|
|
10
11
|
flowcept/commons/flowcept_logger.py,sha256=0asRucrDMeRXvsdhuCmH6lWO7lAt_Z5o5uW7rrQhcjc,1857
|
|
11
12
|
flowcept/commons/query_utils.py,sha256=3tyK5VYA10iDtmtzNwa8OQGn93DBxsu6rTjHDphftSc,2208
|
|
12
|
-
flowcept/commons/settings_factory.py,sha256=
|
|
13
|
-
flowcept/commons/
|
|
13
|
+
flowcept/commons/settings_factory.py,sha256=bMTjgXRfb5HsL2lPnLfem-9trqELbNWE04Ie7lSlxYM,1731
|
|
14
|
+
flowcept/commons/task_data_preprocess.py,sha256=skTkT8XpO1gsIfu5YGHPj4A1qK4O139rELpwVmMryeY,6767
|
|
15
|
+
flowcept/commons/utils.py,sha256=nzNSAupZidI54ngNF67MX5H0gIj1YOq0GTv6A-z6eEE,8418
|
|
14
16
|
flowcept/commons/vocabulary.py,sha256=_GzHJ1wSYJlLsu_uu1Am6N3zvc59S4FCuT5yp7lynPw,713
|
|
15
17
|
flowcept/commons/daos/__init__.py,sha256=RO51svfHOg9naN676zuQwbj_RQ6IFHu-RALeefvtwwk,23
|
|
16
|
-
flowcept/commons/daos/keyvalue_dao.py,sha256=
|
|
18
|
+
flowcept/commons/daos/keyvalue_dao.py,sha256=g7zgC9hVC1NTllwUAqGt44YqdqYUgAKgPlX8_G4BRGw,3599
|
|
19
|
+
flowcept/commons/daos/redis_conn.py,sha256=gFyW-5yf6B8ExEYopCmbap8ki-iEwuIw-KH9f6o7UGQ,1495
|
|
17
20
|
flowcept/commons/daos/docdb_dao/__init__.py,sha256=qRvXREeUJ4mkhxdC9bzpOsVX6M2FB5hDyLFxhMxTGhs,30
|
|
18
21
|
flowcept/commons/daos/docdb_dao/docdb_dao_base.py,sha256=YbfSVJPwZGK2GBYkeapRC83HkmP0c6Msv5TriD88RcI,11812
|
|
19
22
|
flowcept/commons/daos/docdb_dao/lmdb_dao.py,sha256=dJOLgCx_lwdz6MKiMpM_UE4rm0angDCPaVz_WU5KqIA,10407
|
|
20
23
|
flowcept/commons/daos/docdb_dao/mongodb_dao.py,sha256=0y9RiL54e1GxSTkRHFlMrLFAHWuB3YyNS2zLsnBPtxg,38456
|
|
21
24
|
flowcept/commons/daos/mq_dao/__init__.py,sha256=Xxm4FmbBUZDQ7XIAmSFbeKE_AdHsbgFmSuftvMWSykQ,21
|
|
22
|
-
flowcept/commons/daos/mq_dao/mq_dao_base.py,sha256=
|
|
23
|
-
flowcept/commons/daos/mq_dao/mq_dao_kafka.py,sha256=
|
|
24
|
-
flowcept/commons/daos/mq_dao/mq_dao_mofka.py,sha256=
|
|
25
|
-
flowcept/commons/daos/mq_dao/mq_dao_redis.py,sha256=
|
|
25
|
+
flowcept/commons/daos/mq_dao/mq_dao_base.py,sha256=gXOHRhWHiJmN7mNRE4QIbnOfrN-314Ds2LONzsBw3Ug,9184
|
|
26
|
+
flowcept/commons/daos/mq_dao/mq_dao_kafka.py,sha256=Idq5TKm-dNZwlfkmLxUy7IBrn0DBtCekrC4n5dXUpn4,4379
|
|
27
|
+
flowcept/commons/daos/mq_dao/mq_dao_mofka.py,sha256=tRdMGYDzdeIJxad-B4-DE6u8Wzs61eTzOW4ojZrnTxs,4057
|
|
28
|
+
flowcept/commons/daos/mq_dao/mq_dao_redis.py,sha256=WKPoMPBSce4shqbBkgsnuqJAJoZZ4U_hdebhyFqtejQ,5535
|
|
26
29
|
flowcept/commons/flowcept_dataclasses/__init__.py,sha256=8KkiJh0WSRAB50waVluxCSI8Tb9X1L9nup4c8RN3ulc,30
|
|
27
30
|
flowcept/commons/flowcept_dataclasses/base_settings_dataclasses.py,sha256=Cjw2PGYtZDfnwecz6G3S42Ncmxj7AIZVEBx05bsxRUo,399
|
|
28
|
-
flowcept/commons/flowcept_dataclasses/task_object.py,sha256=
|
|
31
|
+
flowcept/commons/flowcept_dataclasses/task_object.py,sha256=ZzUINqIm6s0J7M6a9OnzEcrBq5z8QZ-m_5n8UE0I6kI,5715
|
|
29
32
|
flowcept/commons/flowcept_dataclasses/telemetry.py,sha256=9_5ONCo-06r5nKHXmi5HfIhiZSuPgmTECiq_u9MlxXM,2822
|
|
30
33
|
flowcept/commons/flowcept_dataclasses/workflow_object.py,sha256=f8aB0b3xcUr3KQTlloF7R_P6xQejzDPOm-s6dLhGMeA,4383
|
|
31
34
|
flowcept/flowcept_api/__init__.py,sha256=T1ty86YlocQ5Z18l5fUqHj_CC6Unq_iBv0lFyiI7Ao8,22
|
|
32
35
|
flowcept/flowcept_api/db_api.py,sha256=hKXep-n50rp9cAzV0ljk2QVEF8O64yxi3ujXv5_Ibac,9723
|
|
33
|
-
flowcept/flowcept_api/flowcept_controller.py,sha256=
|
|
36
|
+
flowcept/flowcept_api/flowcept_controller.py,sha256=_aB7x7ANOthpqD-xCA8UgiyeyabbzLpXgtpzkKXBBbw,12530
|
|
34
37
|
flowcept/flowcept_api/task_query_api.py,sha256=SrwB0OCVtbpvCPECkE2ySM10G_g8Wlk5PJ8h-0xEaNc,23821
|
|
35
38
|
flowcept/flowcept_webserver/__init__.py,sha256=8411GIXGddKTKoHUvbo_Rq6svosNG7tG8VzvUEBd7WI,28
|
|
36
39
|
flowcept/flowcept_webserver/app.py,sha256=VUV8_JZbIbx9u_1O7m7XtRdhZb_7uifUa-iNlPhmZws,658
|
|
@@ -38,11 +41,18 @@ flowcept/flowcept_webserver/resources/__init__.py,sha256=XOk5yhLeLU6JmVXxbl3TY2z
|
|
|
38
41
|
flowcept/flowcept_webserver/resources/query_rsrc.py,sha256=Mk1XDC_wVYkMk0eaazqWWrTC07gQU9U0toKfip0ihZE,1353
|
|
39
42
|
flowcept/flowcept_webserver/resources/task_messages_rsrc.py,sha256=0u68it2W-9NzUUx5fWOZCqvRKe5EsLI8oyvto9634Ng,666
|
|
40
43
|
flowcept/flowceptor/__init__.py,sha256=wVxRXUv07iNx6SMRRma2vqhR_GIcRl0re_WCYG65PUs,29
|
|
41
|
-
flowcept/flowceptor/telemetry_capture.py,sha256=
|
|
44
|
+
flowcept/flowceptor/telemetry_capture.py,sha256=kDlRA1chkR31ckNuuQu7PmJPAO_yxwJ1-KRHJKW8csA,13739
|
|
42
45
|
flowcept/flowceptor/adapters/__init__.py,sha256=SuZbSZVVQeBJ9zXW-M9jF09dw3XIjre3lSGrUO1Y8Po,27
|
|
43
|
-
flowcept/flowceptor/adapters/base_interceptor.py,sha256=
|
|
46
|
+
flowcept/flowceptor/adapters/base_interceptor.py,sha256=m2k_775gsiG7uEYEKLgA0KC4fysGTafbINCC4jkqd3M,6388
|
|
44
47
|
flowcept/flowceptor/adapters/instrumentation_interceptor.py,sha256=DhK2bBnpghqPSeA62BUqRg6pl8zxuYrP33dK4x6PhRE,733
|
|
45
48
|
flowcept/flowceptor/adapters/interceptor_state_manager.py,sha256=xRzmi5YFKBEqNtX8F5s6XlMTRe27ml4BmQtBO4WtG2c,919
|
|
49
|
+
flowcept/flowceptor/adapters/agents/__init__.py,sha256=5x_qyGaazppgvNDWbNhC_gfTav0b3r_P4CX7QwFv4BQ,32
|
|
50
|
+
flowcept/flowceptor/adapters/agents/agents_utils.py,sha256=JDxxsgcCdRR3CV3odIuLcHQcq-VFuApZaioqs_yHkuU,2798
|
|
51
|
+
flowcept/flowceptor/adapters/agents/flowcept_agent.py,sha256=13CobrSp_uObvLSVW3QNQOcqVa5rvwKBwFa4mjuLvb8,8173
|
|
52
|
+
flowcept/flowceptor/adapters/agents/flowcept_llm_prov_capture.py,sha256=2qzcItS3FHF-Wym_u9jZ-XzgDJnDgm9rGGRhfaqJZ8M,5992
|
|
53
|
+
flowcept/flowceptor/adapters/agents/prompts.py,sha256=VipBULibXYRF_mMCf_yYJ2Sb-aRNY_y7YTDmed4AfgM,2587
|
|
54
|
+
flowcept/flowceptor/adapters/brokers/__init__.py,sha256=mhQXVmh0JklvL93GUtJZLJnPRYX9Nmb8IqcyKJGQBzk,36
|
|
55
|
+
flowcept/flowceptor/adapters/brokers/mqtt_interceptor.py,sha256=wx3STMYPHeXB6ilUn-UQYsxesGp2hF7TRlfn52hNJtY,4845
|
|
46
56
|
flowcept/flowceptor/adapters/dask/__init__.py,sha256=GKreb5L_nliD2BEckyB943zOQ-b6Gn1fLDj81FqSK2Y,23
|
|
47
57
|
flowcept/flowceptor/adapters/dask/dask_dataclasses.py,sha256=6LTG-kdcc6AUuVINvkqB5QHw6pchg1aMqj0sdWt2Ef8,580
|
|
48
58
|
flowcept/flowceptor/adapters/dask/dask_interceptor.py,sha256=uBQpLluYXzlT1gBDfTe4_WueC_fWBEs5Xr8ntpOmljE,5869
|
|
@@ -51,23 +61,27 @@ flowcept/flowceptor/adapters/mlflow/__init__.py,sha256=3mzHrvh1XQOy68qx1A3so9Nq2
|
|
|
51
61
|
flowcept/flowceptor/adapters/mlflow/interception_event_handler.py,sha256=-SsIRdOcZjQUTzWgsZ41ouqpla4Qd32jIWXIAGU1pPw,494
|
|
52
62
|
flowcept/flowceptor/adapters/mlflow/mlflow_dao.py,sha256=dPEgCduiw14_pzT5WCjuokwaN7p5Tu7UvWS2rtGh4qk,4589
|
|
53
63
|
flowcept/flowceptor/adapters/mlflow/mlflow_dataclasses.py,sha256=vbijpDW6npHdsA9-28otXw94O4a9R-PWtq3xlJapsyY,690
|
|
54
|
-
flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py,sha256=
|
|
64
|
+
flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py,sha256=OLmVBdOCMS3GPcdxSdCD794RDbW6p4f8eBh1PXWcvHE,3799
|
|
55
65
|
flowcept/flowceptor/adapters/tensorboard/__init__.py,sha256=LrcR4WCIlBwwHIUSteQ8k8JBdCJTFqLvvgAfnoLeREw,30
|
|
56
66
|
flowcept/flowceptor/adapters/tensorboard/tensorboard_dataclasses.py,sha256=lSfDd6TucVNzGxbm69BYyCVgMr2p9iUEQjnsS4jIfeI,554
|
|
57
|
-
flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py,sha256=
|
|
58
|
-
flowcept/flowceptor/adapters/zambeze/__init__.py,sha256=1e9_hK2cUKDXhQ0kBRftwcJjGFqbMVGisNP9oAuWpzk,26
|
|
59
|
-
flowcept/flowceptor/adapters/zambeze/zambeze_dataclasses.py,sha256=nn9MxvcdzgmOa8n5Jwdl7UzlSzxEu9bA-Ls6cHyb91c,849
|
|
60
|
-
flowcept/flowceptor/adapters/zambeze/zambeze_interceptor.py,sha256=Bjyi48JW0DXJLJuvwPxaD8zxxsSoEFgSoXl8YcbwFWk,3782
|
|
67
|
+
flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py,sha256=PUKGlCsYcybsk1HK573Brs6FiXQRoaj6MKgZ3Oyeec4,4881
|
|
61
68
|
flowcept/flowceptor/consumers/__init__.py,sha256=foxtVEb2ZEe9g1slfYIKM4tIFv-He1l7XS--SYs7nlQ,28
|
|
69
|
+
flowcept/flowceptor/consumers/base_consumer.py,sha256=xvs_BMrNFJhNX3ACEkf0DUH7JIJNtjNgg2xMRmujoiE,2935
|
|
62
70
|
flowcept/flowceptor/consumers/consumer_utils.py,sha256=7bvFJWusJkfA4j0gwZLDIIsIOyfk9wRq6s5liS3JAV0,5665
|
|
63
|
-
flowcept/flowceptor/consumers/document_inserter.py,sha256=
|
|
71
|
+
flowcept/flowceptor/consumers/document_inserter.py,sha256=p5g18ghOrSbrR1b3btnBwZi48qMIvMT9n3QuRBq89LQ,13374
|
|
72
|
+
flowcept/flowceptor/consumers/agent/__init__.py,sha256=R1uvjBPeTLw9SpYgyUc6Qmo16pE84PFHcELTTFvyTWU,56
|
|
73
|
+
flowcept/flowceptor/consumers/agent/base_agent_context_manager.py,sha256=dRgWFuCacB_7lj1NfEeZM2uERmRTxh9QOxx1ywXtzfY,3226
|
|
74
|
+
flowcept/flowceptor/consumers/agent/client_agent.py,sha256=5dtjTRMHACIDwU_0k2xsKia24iasMM_6IMxWYCt5Ql8,1639
|
|
75
|
+
flowcept/flowceptor/consumers/agent/flowcept_agent_context_manager.py,sha256=RSdQ2zFkCizD2CtgdCIRRgs9J2E_G-49wmjNEZYoPMc,5302
|
|
76
|
+
flowcept/flowceptor/consumers/agent/flowcept_qa_manager.py,sha256=FaUTTixKncWjs-6xPw9BdNdPBFopFQ9tNRNT9kLPtyc,4156
|
|
64
77
|
flowcept/instrumentation/__init__.py,sha256=M5bTmg80E4QyN91gUX3qfw_nbtJSXwGWcKxdZP3vJz0,34
|
|
65
78
|
flowcept/instrumentation/flowcept_loop.py,sha256=RvETm3Pn37dIw_a1RXigyh2U7MCBHqi46dPmbrz3RMQ,12171
|
|
66
79
|
flowcept/instrumentation/flowcept_task.py,sha256=l_BAYEUZ_SeBt8QJN_E9D9QcZVYRnW9qO_XRnqvmePE,5993
|
|
67
80
|
flowcept/instrumentation/flowcept_torch.py,sha256=mH4sI2FMtBpGk4hN3U6MUwqd6sOPER8TbigUkexfhDY,23437
|
|
68
|
-
flowcept/instrumentation/task_capture.py,sha256=
|
|
69
|
-
resources/sample_settings.yaml,sha256=
|
|
70
|
-
flowcept-0.8.
|
|
71
|
-
flowcept-0.8.
|
|
72
|
-
flowcept-0.8.
|
|
73
|
-
flowcept-0.8.
|
|
81
|
+
flowcept/instrumentation/task_capture.py,sha256=I3So1eysuyJ4KS3Fya14WldbgG0pBJ1CTvTikVKSEsM,5090
|
|
82
|
+
resources/sample_settings.yaml,sha256=cdMyRirOorBBVidUS2RVLs8NKlBjbN-SJZ2XDnloc3A,6313
|
|
83
|
+
flowcept-0.8.11.dist-info/METADATA,sha256=xZpXRV3xItrqcWvCFipJljywnlW8BGSMOC0d02q5qao,18811
|
|
84
|
+
flowcept-0.8.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
85
|
+
flowcept-0.8.11.dist-info/entry_points.txt,sha256=i8q67WE0201rVxYI2lyBtS52shvgl93x2Szp4q8zMlw,47
|
|
86
|
+
flowcept-0.8.11.dist-info/licenses/LICENSE,sha256=r5-2P6tFTuRGWT5TiX32s1y0tnp4cIqBEC1QjTaXe2k,1086
|
|
87
|
+
flowcept-0.8.11.dist-info/RECORD,,
|