kailash 0.2.2__py3-none-any.whl → 0.3.1__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.
- kailash/__init__.py +1 -1
- kailash/access_control.py +40 -39
- kailash/api/auth.py +26 -32
- kailash/api/custom_nodes.py +29 -29
- kailash/api/custom_nodes_secure.py +35 -35
- kailash/api/database.py +17 -17
- kailash/api/gateway.py +19 -19
- kailash/api/mcp_integration.py +24 -23
- kailash/api/studio.py +45 -45
- kailash/api/workflow_api.py +8 -8
- kailash/cli/commands.py +5 -8
- kailash/manifest.py +42 -42
- kailash/mcp/__init__.py +1 -1
- kailash/mcp/ai_registry_server.py +20 -20
- kailash/mcp/client.py +9 -11
- kailash/mcp/client_new.py +10 -10
- kailash/mcp/server.py +1 -2
- kailash/mcp/server_enhanced.py +449 -0
- kailash/mcp/servers/ai_registry.py +6 -6
- kailash/mcp/utils/__init__.py +31 -0
- kailash/mcp/utils/cache.py +267 -0
- kailash/mcp/utils/config.py +263 -0
- kailash/mcp/utils/formatters.py +293 -0
- kailash/mcp/utils/metrics.py +418 -0
- kailash/nodes/ai/agents.py +9 -9
- kailash/nodes/ai/ai_providers.py +33 -34
- kailash/nodes/ai/embedding_generator.py +31 -32
- kailash/nodes/ai/intelligent_agent_orchestrator.py +62 -66
- kailash/nodes/ai/iterative_llm_agent.py +48 -48
- kailash/nodes/ai/llm_agent.py +32 -33
- kailash/nodes/ai/models.py +13 -13
- kailash/nodes/ai/self_organizing.py +44 -44
- kailash/nodes/api/__init__.py +5 -0
- kailash/nodes/api/auth.py +11 -11
- kailash/nodes/api/graphql.py +13 -13
- kailash/nodes/api/http.py +19 -19
- kailash/nodes/api/monitoring.py +463 -0
- kailash/nodes/api/rate_limiting.py +9 -13
- kailash/nodes/api/rest.py +29 -29
- kailash/nodes/api/security.py +819 -0
- kailash/nodes/base.py +24 -26
- kailash/nodes/base_async.py +7 -7
- kailash/nodes/base_cycle_aware.py +12 -12
- kailash/nodes/base_with_acl.py +5 -5
- kailash/nodes/code/python.py +56 -55
- kailash/nodes/data/__init__.py +6 -0
- kailash/nodes/data/directory.py +6 -6
- kailash/nodes/data/event_generation.py +297 -0
- kailash/nodes/data/file_discovery.py +598 -0
- kailash/nodes/data/readers.py +8 -8
- kailash/nodes/data/retrieval.py +10 -10
- kailash/nodes/data/sharepoint_graph.py +17 -17
- kailash/nodes/data/sources.py +5 -5
- kailash/nodes/data/sql.py +13 -13
- kailash/nodes/data/streaming.py +25 -25
- kailash/nodes/data/vector_db.py +22 -22
- kailash/nodes/data/writers.py +7 -7
- kailash/nodes/logic/async_operations.py +17 -17
- kailash/nodes/logic/convergence.py +11 -11
- kailash/nodes/logic/loop.py +4 -4
- kailash/nodes/logic/operations.py +11 -11
- kailash/nodes/logic/workflow.py +8 -9
- kailash/nodes/mixins/mcp.py +17 -17
- kailash/nodes/mixins.py +8 -10
- kailash/nodes/transform/chunkers.py +3 -3
- kailash/nodes/transform/formatters.py +7 -7
- kailash/nodes/transform/processors.py +11 -11
- kailash/runtime/access_controlled.py +18 -18
- kailash/runtime/async_local.py +18 -20
- kailash/runtime/docker.py +24 -26
- kailash/runtime/local.py +55 -31
- kailash/runtime/parallel.py +25 -25
- kailash/runtime/parallel_cyclic.py +29 -29
- kailash/runtime/runner.py +6 -6
- kailash/runtime/testing.py +22 -22
- kailash/sdk_exceptions.py +0 -58
- kailash/security.py +14 -26
- kailash/tracking/manager.py +38 -38
- kailash/tracking/metrics_collector.py +15 -14
- kailash/tracking/models.py +53 -53
- kailash/tracking/storage/base.py +7 -17
- kailash/tracking/storage/database.py +22 -23
- kailash/tracking/storage/filesystem.py +38 -40
- kailash/utils/export.py +21 -21
- kailash/utils/templates.py +8 -9
- kailash/visualization/api.py +30 -34
- kailash/visualization/dashboard.py +17 -17
- kailash/visualization/performance.py +32 -19
- kailash/visualization/reports.py +30 -28
- kailash/workflow/builder.py +8 -8
- kailash/workflow/convergence.py +13 -12
- kailash/workflow/cycle_analyzer.py +38 -33
- kailash/workflow/cycle_builder.py +12 -12
- kailash/workflow/cycle_config.py +16 -15
- kailash/workflow/cycle_debugger.py +40 -40
- kailash/workflow/cycle_exceptions.py +29 -29
- kailash/workflow/cycle_profiler.py +21 -21
- kailash/workflow/cycle_state.py +20 -22
- kailash/workflow/cyclic_runner.py +45 -45
- kailash/workflow/graph.py +57 -45
- kailash/workflow/mermaid_visualizer.py +9 -11
- kailash/workflow/migration.py +22 -22
- kailash/workflow/mock_registry.py +6 -6
- kailash/workflow/runner.py +9 -9
- kailash/workflow/safety.py +12 -13
- kailash/workflow/state.py +8 -11
- kailash/workflow/templates.py +19 -19
- kailash/workflow/validation.py +14 -14
- kailash/workflow/visualization.py +32 -24
- kailash-0.3.1.dist-info/METADATA +476 -0
- kailash-0.3.1.dist-info/RECORD +136 -0
- kailash-0.2.2.dist-info/METADATA +0 -121
- kailash-0.2.2.dist-info/RECORD +0 -126
- {kailash-0.2.2.dist-info → kailash-0.3.1.dist-info}/WHEEL +0 -0
- {kailash-0.2.2.dist-info → kailash-0.3.1.dist-info}/entry_points.txt +0 -0
- {kailash-0.2.2.dist-info → kailash-0.3.1.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.2.2.dist-info → kailash-0.3.1.dist-info}/top_level.txt +0 -0
kailash/nodes/data/retrieval.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Document retrieval nodes for finding relevant content using various similarity methods."""
|
2
2
|
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
|
5
5
|
from kailash.nodes.base import Node, NodeParameter, register_node
|
6
6
|
|
@@ -9,7 +9,7 @@ from kailash.nodes.base import Node, NodeParameter, register_node
|
|
9
9
|
class RelevanceScorerNode(Node):
|
10
10
|
"""Scores chunk relevance using various similarity methods including embeddings similarity."""
|
11
11
|
|
12
|
-
def get_parameters(self) ->
|
12
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
13
13
|
return {
|
14
14
|
"chunks": NodeParameter(
|
15
15
|
name="chunks",
|
@@ -45,7 +45,7 @@ class RelevanceScorerNode(Node):
|
|
45
45
|
),
|
46
46
|
}
|
47
47
|
|
48
|
-
def run(self, **kwargs) ->
|
48
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
49
49
|
chunks = kwargs.get("chunks", [])
|
50
50
|
query_embeddings = kwargs.get("query_embedding", [])
|
51
51
|
chunk_embeddings = kwargs.get("chunk_embeddings", [])
|
@@ -98,8 +98,8 @@ class RelevanceScorerNode(Node):
|
|
98
98
|
return {"relevant_chunks": top_chunks}
|
99
99
|
|
100
100
|
def _cosine_similarity_scoring(
|
101
|
-
self, chunks:
|
102
|
-
) ->
|
101
|
+
self, chunks: list[dict], query_embeddings: list, chunk_embeddings: list
|
102
|
+
) -> list[dict]:
|
103
103
|
"""Score chunks using cosine similarity."""
|
104
104
|
# Extract actual embedding vectors from the embedding objects
|
105
105
|
# EmbeddingGeneratorNode returns embeddings in format: {"embedding": [...], "text": "...", "dimensions": X}
|
@@ -131,7 +131,7 @@ class RelevanceScorerNode(Node):
|
|
131
131
|
return 0.5
|
132
132
|
|
133
133
|
try:
|
134
|
-
dot_product = sum(x * y for x, y in zip(a, b))
|
134
|
+
dot_product = sum(x * y for x, y in zip(a, b, strict=False))
|
135
135
|
norm_a = sum(x * x for x in a) ** 0.5
|
136
136
|
norm_b = sum(x * x for x in b) ** 0.5
|
137
137
|
return dot_product / (norm_a * norm_b) if norm_a * norm_b > 0 else 0
|
@@ -162,16 +162,16 @@ class RelevanceScorerNode(Node):
|
|
162
162
|
return scored_chunks
|
163
163
|
|
164
164
|
def _bm25_scoring(
|
165
|
-
self, chunks:
|
166
|
-
) ->
|
165
|
+
self, chunks: list[dict], query_embeddings: list, chunk_embeddings: list
|
166
|
+
) -> list[dict]:
|
167
167
|
"""Score chunks using BM25 algorithm (future implementation)."""
|
168
168
|
# TODO: Implement BM25 scoring
|
169
169
|
# For now, return chunks with default scores
|
170
170
|
return [{**chunk, "relevance_score": 0.5} for chunk in chunks]
|
171
171
|
|
172
172
|
def _tfidf_scoring(
|
173
|
-
self, chunks:
|
174
|
-
) ->
|
173
|
+
self, chunks: list[dict], query_embeddings: list, chunk_embeddings: list
|
174
|
+
) -> list[dict]:
|
175
175
|
"""Score chunks using TF-IDF similarity (future implementation)."""
|
176
176
|
# TODO: Implement TF-IDF scoring
|
177
177
|
# For now, return chunks with default scores
|
@@ -23,7 +23,7 @@ Downstream consumers:
|
|
23
23
|
|
24
24
|
import os
|
25
25
|
from pathlib import Path
|
26
|
-
from typing import Any
|
26
|
+
from typing import Any
|
27
27
|
|
28
28
|
import requests
|
29
29
|
|
@@ -79,7 +79,7 @@ class SharePointGraphReader(Node):
|
|
79
79
|
author="Kailash SDK",
|
80
80
|
)
|
81
81
|
|
82
|
-
def get_parameters(self) ->
|
82
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
83
83
|
"""Define input parameters for SharePoint Graph operations."""
|
84
84
|
return {
|
85
85
|
"tenant_id": NodeParameter(
|
@@ -149,7 +149,7 @@ class SharePointGraphReader(Node):
|
|
149
149
|
|
150
150
|
def _authenticate(
|
151
151
|
self, tenant_id: str, client_id: str, client_secret: str
|
152
|
-
) ->
|
152
|
+
) -> dict[str, Any]:
|
153
153
|
"""Authenticate with Microsoft Graph API using MSAL.
|
154
154
|
|
155
155
|
Returns dict with token and headers for stateless operation.
|
@@ -184,7 +184,7 @@ class SharePointGraphReader(Node):
|
|
184
184
|
},
|
185
185
|
}
|
186
186
|
|
187
|
-
def _get_site_data(self, site_url: str, headers:
|
187
|
+
def _get_site_data(self, site_url: str, headers: dict[str, str]) -> dict[str, Any]:
|
188
188
|
"""Get SharePoint site data from Graph API."""
|
189
189
|
# Convert SharePoint URL to Graph API site ID format
|
190
190
|
site_id = site_url.replace("https://", "").replace(
|
@@ -201,8 +201,8 @@ class SharePointGraphReader(Node):
|
|
201
201
|
)
|
202
202
|
|
203
203
|
def _list_libraries(
|
204
|
-
self, site_id: str, headers:
|
205
|
-
) ->
|
204
|
+
self, site_id: str, headers: dict[str, str]
|
205
|
+
) -> list[dict[str, Any]]:
|
206
206
|
"""List all document libraries in the site."""
|
207
207
|
drives_url = f"https://graph.microsoft.com/v1.0/sites/{site_id}/drives"
|
208
208
|
response = requests.get(drives_url, headers=headers)
|
@@ -215,8 +215,8 @@ class SharePointGraphReader(Node):
|
|
215
215
|
)
|
216
216
|
|
217
217
|
def _get_drive_id(
|
218
|
-
self, site_id: str, library_name: str, headers:
|
219
|
-
) ->
|
218
|
+
self, site_id: str, library_name: str, headers: dict[str, str]
|
219
|
+
) -> str | None:
|
220
220
|
"""Get the drive ID for a specific library."""
|
221
221
|
libraries = self._list_libraries(site_id, headers)
|
222
222
|
for lib in libraries:
|
@@ -225,8 +225,8 @@ class SharePointGraphReader(Node):
|
|
225
225
|
return None
|
226
226
|
|
227
227
|
def _list_files(
|
228
|
-
self, site_id: str, library_name: str, folder_path: str, headers:
|
229
|
-
) ->
|
228
|
+
self, site_id: str, library_name: str, folder_path: str, headers: dict[str, str]
|
229
|
+
) -> dict[str, Any]:
|
230
230
|
"""List files in a specific library and folder."""
|
231
231
|
drive_id = self._get_drive_id(site_id, library_name, headers)
|
232
232
|
if not drive_id:
|
@@ -289,8 +289,8 @@ class SharePointGraphReader(Node):
|
|
289
289
|
file_name: str,
|
290
290
|
folder_path: str,
|
291
291
|
local_path: str,
|
292
|
-
headers:
|
293
|
-
) ->
|
292
|
+
headers: dict[str, str],
|
293
|
+
) -> dict[str, Any]:
|
294
294
|
"""Download a file from SharePoint."""
|
295
295
|
drive_id = self._get_drive_id(site_id, library_name, headers)
|
296
296
|
if not drive_id:
|
@@ -344,8 +344,8 @@ class SharePointGraphReader(Node):
|
|
344
344
|
)
|
345
345
|
|
346
346
|
def _search_files(
|
347
|
-
self, site_id: str, library_name: str, query: str, headers:
|
348
|
-
) ->
|
347
|
+
self, site_id: str, library_name: str, query: str, headers: dict[str, str]
|
348
|
+
) -> dict[str, Any]:
|
349
349
|
"""Search for files in a library."""
|
350
350
|
drive_id = self._get_drive_id(site_id, library_name, headers)
|
351
351
|
if not drive_id:
|
@@ -383,7 +383,7 @@ class SharePointGraphReader(Node):
|
|
383
383
|
f"Search failed: {response.status_code} - {response.text}"
|
384
384
|
)
|
385
385
|
|
386
|
-
def run(self, **kwargs) ->
|
386
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
387
387
|
"""Execute SharePoint Graph operation.
|
388
388
|
|
389
389
|
This method is stateless and returns JSON-serializable results
|
@@ -494,7 +494,7 @@ class SharePointGraphWriter(Node):
|
|
494
494
|
author="Kailash SDK",
|
495
495
|
)
|
496
496
|
|
497
|
-
def get_parameters(self) ->
|
497
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
498
498
|
"""Define input parameters for SharePoint upload operations."""
|
499
499
|
return {
|
500
500
|
"tenant_id": NodeParameter(
|
@@ -549,7 +549,7 @@ class SharePointGraphWriter(Node):
|
|
549
549
|
),
|
550
550
|
}
|
551
551
|
|
552
|
-
def run(self, **kwargs) ->
|
552
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
553
553
|
"""Execute SharePoint upload operation."""
|
554
554
|
# Validate required parameters
|
555
555
|
tenant_id = kwargs.get("tenant_id")
|
kailash/nodes/data/sources.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Data source nodes for providing input data to workflows."""
|
2
2
|
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
|
5
5
|
from kailash.nodes.base import Node, NodeParameter, register_node
|
6
6
|
|
@@ -9,7 +9,7 @@ from kailash.nodes.base import Node, NodeParameter, register_node
|
|
9
9
|
class DocumentSourceNode(Node):
|
10
10
|
"""Provides sample documents for hierarchical RAG processing."""
|
11
11
|
|
12
|
-
def get_parameters(self) ->
|
12
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
13
13
|
return {
|
14
14
|
"sample_documents": NodeParameter(
|
15
15
|
name="sample_documents",
|
@@ -20,7 +20,7 @@ class DocumentSourceNode(Node):
|
|
20
20
|
)
|
21
21
|
}
|
22
22
|
|
23
|
-
def run(self, **kwargs) ->
|
23
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
24
24
|
# Sample documents for demonstration
|
25
25
|
documents = [
|
26
26
|
{
|
@@ -48,7 +48,7 @@ class DocumentSourceNode(Node):
|
|
48
48
|
class QuerySourceNode(Node):
|
49
49
|
"""Provides sample queries for RAG processing."""
|
50
50
|
|
51
|
-
def get_parameters(self) ->
|
51
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
52
52
|
return {
|
53
53
|
"query": NodeParameter(
|
54
54
|
name="query",
|
@@ -59,7 +59,7 @@ class QuerySourceNode(Node):
|
|
59
59
|
)
|
60
60
|
}
|
61
61
|
|
62
|
-
def run(self, **kwargs) ->
|
62
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
63
63
|
query = kwargs.get("query", "What are the main types of machine learning?")
|
64
64
|
print(f"Debug QuerySource: providing query='{query}'")
|
65
65
|
return {"query": query}
|
kailash/nodes/data/sql.py
CHANGED
@@ -16,7 +16,7 @@ import os
|
|
16
16
|
import threading
|
17
17
|
import time
|
18
18
|
from datetime import datetime
|
19
|
-
from typing import Any,
|
19
|
+
from typing import Any, Optional
|
20
20
|
|
21
21
|
import yaml
|
22
22
|
from sqlalchemy import create_engine, text
|
@@ -38,7 +38,7 @@ class SQLDatabaseNode(Node):
|
|
38
38
|
self.config_path = project_config_path
|
39
39
|
self.config = self._load_project_config()
|
40
40
|
|
41
|
-
def _load_project_config(self) ->
|
41
|
+
def _load_project_config(self) -> dict[str, Any]:
|
42
42
|
"""Load project configuration from YAML file."""
|
43
43
|
if not os.path.exists(self.config_path):
|
44
44
|
raise NodeExecutionError(
|
@@ -46,7 +46,7 @@ class SQLDatabaseNode(Node):
|
|
46
46
|
)
|
47
47
|
|
48
48
|
try:
|
49
|
-
with open(self.config_path
|
49
|
+
with open(self.config_path) as f:
|
50
50
|
config = yaml.safe_load(f)
|
51
51
|
return config or {}
|
52
52
|
except yaml.YAMLError as e:
|
@@ -56,7 +56,7 @@ class SQLDatabaseNode(Node):
|
|
56
56
|
|
57
57
|
def get_database_config(
|
58
58
|
self, connection_name: str
|
59
|
-
) ->
|
59
|
+
) -> tuple[str, dict[str, Any]]:
|
60
60
|
"""Get database configuration by connection name.
|
61
61
|
|
62
62
|
Args:
|
@@ -185,8 +185,8 @@ class SQLDatabaseNode(Node):
|
|
185
185
|
"""
|
186
186
|
|
187
187
|
# Class-level shared resources for connection pooling
|
188
|
-
_shared_pools:
|
189
|
-
_pool_metrics:
|
188
|
+
_shared_pools: dict[tuple[str, frozenset], Any] = {}
|
189
|
+
_pool_metrics: dict[tuple[str, frozenset], dict[str, Any]] = {}
|
190
190
|
_pool_lock = threading.Lock()
|
191
191
|
_config_manager: Optional["SQLDatabaseNode._DatabaseConfigManager"] = None
|
192
192
|
|
@@ -252,7 +252,7 @@ class SQLDatabaseNode(Node):
|
|
252
252
|
# Call parent constructor
|
253
253
|
super().__init__(**kwargs)
|
254
254
|
|
255
|
-
def get_parameters(self) ->
|
255
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
256
256
|
"""Define input parameters for SQL execution.
|
257
257
|
|
258
258
|
Configuration parameters (provided to constructor):
|
@@ -334,7 +334,7 @@ class SQLDatabaseNode(Node):
|
|
334
334
|
|
335
335
|
return self._shared_pools[cache_key]
|
336
336
|
|
337
|
-
def run(self, **kwargs) ->
|
337
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
338
338
|
"""Execute SQL query using shared connection pool.
|
339
339
|
|
340
340
|
Args:
|
@@ -458,7 +458,7 @@ class SQLDatabaseNode(Node):
|
|
458
458
|
}
|
459
459
|
|
460
460
|
@classmethod
|
461
|
-
def get_pool_status(cls) ->
|
461
|
+
def get_pool_status(cls) -> dict[str, Any]:
|
462
462
|
"""Get status of all shared connection pools."""
|
463
463
|
with cls._pool_lock:
|
464
464
|
status = {}
|
@@ -736,7 +736,7 @@ class SQLDatabaseNode(Node):
|
|
736
736
|
|
737
737
|
return sanitized
|
738
738
|
|
739
|
-
def _convert_to_named_parameters(self, query: str, parameters:
|
739
|
+
def _convert_to_named_parameters(self, query: str, parameters: list) -> tuple:
|
740
740
|
"""Convert positional parameters to named parameters for SQLAlchemy 2.0.
|
741
741
|
|
742
742
|
Args:
|
@@ -790,8 +790,8 @@ class SQLDatabaseNode(Node):
|
|
790
790
|
return modified_query, param_dict
|
791
791
|
|
792
792
|
def _format_results(
|
793
|
-
self, rows:
|
794
|
-
) ->
|
793
|
+
self, rows: list, columns: list[str], result_format: str
|
794
|
+
) -> list[Any]:
|
795
795
|
"""Format query results according to specified format.
|
796
796
|
|
797
797
|
Args:
|
@@ -820,4 +820,4 @@ class SQLDatabaseNode(Node):
|
|
820
820
|
self.logger.warning(
|
821
821
|
f"Unknown result_format '{result_format}', defaulting to 'dict'"
|
822
822
|
)
|
823
|
-
return [dict(zip(columns, row)) for row in rows]
|
823
|
+
return [dict(zip(columns, row, strict=False)) for row in rows]
|
kailash/nodes/data/streaming.py
CHANGED
@@ -44,7 +44,7 @@ Example:
|
|
44
44
|
"""
|
45
45
|
|
46
46
|
import time
|
47
|
-
from typing import Any
|
47
|
+
from typing import Any
|
48
48
|
|
49
49
|
from kailash.nodes.base import Node, NodeMetadata, NodeParameter, register_node
|
50
50
|
from kailash.sdk_exceptions import NodeConfigurationError, NodeExecutionError
|
@@ -148,7 +148,7 @@ class KafkaConsumerNode(Node):
|
|
148
148
|
self._consumer = None
|
149
149
|
self._topic = None
|
150
150
|
|
151
|
-
def get_parameters(self) ->
|
151
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
152
152
|
"""Define parameters for the Kafka consumer node."""
|
153
153
|
return {
|
154
154
|
"bootstrap_servers": NodeParameter(
|
@@ -206,7 +206,7 @@ class KafkaConsumerNode(Node):
|
|
206
206
|
),
|
207
207
|
}
|
208
208
|
|
209
|
-
def configure(self, config:
|
209
|
+
def configure(self, config: dict[str, Any]) -> None:
|
210
210
|
"""Configure the Kafka consumer.
|
211
211
|
|
212
212
|
Creates and configures the Kafka consumer with the specified
|
@@ -241,7 +241,7 @@ class KafkaConsumerNode(Node):
|
|
241
241
|
self._consumer = f"kafka_consumer_{self.config['group_id']}"
|
242
242
|
self._topic = self.config["topic"]
|
243
243
|
|
244
|
-
def run(self, **kwargs) ->
|
244
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
245
245
|
"""Consume messages from Kafka.
|
246
246
|
|
247
247
|
Implementation of the abstract run method from the base Node class.
|
@@ -254,7 +254,7 @@ class KafkaConsumerNode(Node):
|
|
254
254
|
"""
|
255
255
|
return self.execute(kwargs)
|
256
256
|
|
257
|
-
def execute(self, inputs:
|
257
|
+
def execute(self, inputs: dict[str, Any]) -> dict[str, Any]:
|
258
258
|
"""Consume messages from Kafka.
|
259
259
|
|
260
260
|
Polls for messages up to the specified limit or timeout.
|
@@ -286,7 +286,7 @@ class KafkaConsumerNode(Node):
|
|
286
286
|
except Exception as e:
|
287
287
|
raise NodeExecutionError(f"Failed to consume messages: {str(e)}")
|
288
288
|
|
289
|
-
def _consume_messages(self, max_messages: int, timeout_ms: int) ->
|
289
|
+
def _consume_messages(self, max_messages: int, timeout_ms: int) -> list[dict]:
|
290
290
|
"""Consume messages from Kafka.
|
291
291
|
|
292
292
|
This is a placeholder for actual message consumption logic.
|
@@ -420,7 +420,7 @@ class StreamPublisherNode(Node):
|
|
420
420
|
self._publisher = None
|
421
421
|
self._protocol = None
|
422
422
|
|
423
|
-
def get_parameters(self) ->
|
423
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
424
424
|
"""Define parameters for the stream publisher node."""
|
425
425
|
return {
|
426
426
|
"protocol": NodeParameter(
|
@@ -465,7 +465,7 @@ class StreamPublisherNode(Node):
|
|
465
465
|
),
|
466
466
|
}
|
467
467
|
|
468
|
-
def configure(self, config:
|
468
|
+
def configure(self, config: dict[str, Any]) -> None:
|
469
469
|
"""Configure the stream publisher.
|
470
470
|
|
471
471
|
Creates the appropriate publisher based on the protocol.
|
@@ -499,7 +499,7 @@ class StreamPublisherNode(Node):
|
|
499
499
|
# Placeholder for actual publisher creation
|
500
500
|
self._publisher = f"{self._protocol}_publisher"
|
501
501
|
|
502
|
-
def run(self, **kwargs) ->
|
502
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
503
503
|
"""Publish messages to the streaming platform.
|
504
504
|
|
505
505
|
Implementation of the abstract run method from the base Node class.
|
@@ -512,7 +512,7 @@ class StreamPublisherNode(Node):
|
|
512
512
|
"""
|
513
513
|
return self.execute(kwargs)
|
514
514
|
|
515
|
-
def execute(self, inputs:
|
515
|
+
def execute(self, inputs: dict[str, Any]) -> dict[str, Any]:
|
516
516
|
"""Publish messages to the streaming platform.
|
517
517
|
|
518
518
|
Args:
|
@@ -541,7 +541,7 @@ class StreamPublisherNode(Node):
|
|
541
541
|
except Exception as e:
|
542
542
|
raise NodeExecutionError(f"Failed to publish messages: {str(e)}")
|
543
543
|
|
544
|
-
def _publish_messages(self, messages:
|
544
|
+
def _publish_messages(self, messages: list[dict], headers: dict) -> dict[str, Any]:
|
545
545
|
"""Publish messages to the stream.
|
546
546
|
|
547
547
|
This is a placeholder for actual publishing logic.
|
@@ -683,7 +683,7 @@ class WebSocketNode(Node):
|
|
683
683
|
self._connected = False
|
684
684
|
self._message_queue = []
|
685
685
|
|
686
|
-
def get_parameters(self) ->
|
686
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
687
687
|
"""Get the parameters for this node.
|
688
688
|
|
689
689
|
Returns:
|
@@ -750,7 +750,7 @@ class WebSocketNode(Node):
|
|
750
750
|
),
|
751
751
|
}
|
752
752
|
|
753
|
-
def configure(self, config:
|
753
|
+
def configure(self, config: dict[str, Any]) -> None:
|
754
754
|
"""Configure the WebSocket connection.
|
755
755
|
|
756
756
|
Validates the URL and prepares connection parameters.
|
@@ -770,7 +770,7 @@ class WebSocketNode(Node):
|
|
770
770
|
if not url.startswith(("ws://", "wss://")):
|
771
771
|
raise NodeConfigurationError("URL must start with ws:// or wss://")
|
772
772
|
|
773
|
-
def run(self, **kwargs) ->
|
773
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
774
774
|
"""Run the WebSocket node.
|
775
775
|
|
776
776
|
This method fulfills the abstract run method requirement from the base Node class.
|
@@ -786,7 +786,7 @@ class WebSocketNode(Node):
|
|
786
786
|
"""
|
787
787
|
return self.execute(kwargs)
|
788
788
|
|
789
|
-
def execute(self, inputs:
|
789
|
+
def execute(self, inputs: dict[str, Any]) -> dict[str, Any]:
|
790
790
|
"""Execute WebSocket operations.
|
791
791
|
|
792
792
|
Performs the requested action (connect, send, receive, disconnect).
|
@@ -816,7 +816,7 @@ class WebSocketNode(Node):
|
|
816
816
|
except Exception as e:
|
817
817
|
raise NodeExecutionError(f"WebSocket operation failed: {str(e)}")
|
818
818
|
|
819
|
-
def _connect(self) ->
|
819
|
+
def _connect(self) -> dict[str, Any]:
|
820
820
|
"""Connect to the WebSocket server.
|
821
821
|
|
822
822
|
Returns:
|
@@ -832,7 +832,7 @@ class WebSocketNode(Node):
|
|
832
832
|
"metadata": {"timestamp": time.time()},
|
833
833
|
}
|
834
834
|
|
835
|
-
def _send_message(self, message: Any) ->
|
835
|
+
def _send_message(self, message: Any) -> dict[str, Any]:
|
836
836
|
"""Send a message through the WebSocket.
|
837
837
|
|
838
838
|
Args:
|
@@ -851,7 +851,7 @@ class WebSocketNode(Node):
|
|
851
851
|
"metadata": {"timestamp": time.time()},
|
852
852
|
}
|
853
853
|
|
854
|
-
def _receive_messages(self, timeout: float) ->
|
854
|
+
def _receive_messages(self, timeout: float) -> dict[str, Any]:
|
855
855
|
"""Receive messages from the WebSocket.
|
856
856
|
|
857
857
|
Args:
|
@@ -877,7 +877,7 @@ class WebSocketNode(Node):
|
|
877
877
|
"metadata": {"count": len(messages), "timeout": timeout},
|
878
878
|
}
|
879
879
|
|
880
|
-
def _disconnect(self) ->
|
880
|
+
def _disconnect(self) -> dict[str, Any]:
|
881
881
|
"""Disconnect from the WebSocket server.
|
882
882
|
|
883
883
|
Returns:
|
@@ -994,7 +994,7 @@ class EventStreamNode(Node):
|
|
994
994
|
self._connected = False
|
995
995
|
self._last_event_id = None
|
996
996
|
|
997
|
-
def get_parameters(self) ->
|
997
|
+
def get_parameters(self) -> dict[str, NodeParameter]:
|
998
998
|
"""Get the parameters for this node.
|
999
999
|
|
1000
1000
|
Returns:
|
@@ -1048,7 +1048,7 @@ class EventStreamNode(Node):
|
|
1048
1048
|
),
|
1049
1049
|
}
|
1050
1050
|
|
1051
|
-
def run(self, **kwargs) ->
|
1051
|
+
def run(self, **kwargs) -> dict[str, Any]:
|
1052
1052
|
"""Run the EventStream node.
|
1053
1053
|
|
1054
1054
|
This method fulfills the abstract run method requirement from the base Node class.
|
@@ -1064,7 +1064,7 @@ class EventStreamNode(Node):
|
|
1064
1064
|
"""
|
1065
1065
|
return self.execute(kwargs)
|
1066
1066
|
|
1067
|
-
def execute(self, inputs:
|
1067
|
+
def execute(self, inputs: dict[str, Any]) -> dict[str, Any]:
|
1068
1068
|
"""Execute EventStream operations.
|
1069
1069
|
|
1070
1070
|
Args:
|
@@ -1090,7 +1090,7 @@ class EventStreamNode(Node):
|
|
1090
1090
|
except Exception as e:
|
1091
1091
|
raise NodeExecutionError(f"EventStream operation failed: {str(e)}")
|
1092
1092
|
|
1093
|
-
def _start_stream(self) ->
|
1093
|
+
def _start_stream(self) -> dict[str, Any]:
|
1094
1094
|
"""Start the event stream connection.
|
1095
1095
|
|
1096
1096
|
Returns:
|
@@ -1106,7 +1106,7 @@ class EventStreamNode(Node):
|
|
1106
1106
|
"metadata": {"timestamp": time.time()},
|
1107
1107
|
}
|
1108
1108
|
|
1109
|
-
def _stop_stream(self) ->
|
1109
|
+
def _stop_stream(self) -> dict[str, Any]:
|
1110
1110
|
"""Stop the event stream connection.
|
1111
1111
|
|
1112
1112
|
Returns:
|
@@ -1124,7 +1124,7 @@ class EventStreamNode(Node):
|
|
1124
1124
|
},
|
1125
1125
|
}
|
1126
1126
|
|
1127
|
-
def _receive_events(self, max_events: int) ->
|
1127
|
+
def _receive_events(self, max_events: int) -> dict[str, Any]:
|
1128
1128
|
"""Receive events from the stream.
|
1129
1129
|
|
1130
1130
|
Args:
|