kailash 0.1.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.
Files changed (69) hide show
  1. kailash/__init__.py +31 -0
  2. kailash/__main__.py +11 -0
  3. kailash/cli/__init__.py +5 -0
  4. kailash/cli/commands.py +563 -0
  5. kailash/manifest.py +778 -0
  6. kailash/nodes/__init__.py +23 -0
  7. kailash/nodes/ai/__init__.py +26 -0
  8. kailash/nodes/ai/agents.py +417 -0
  9. kailash/nodes/ai/models.py +488 -0
  10. kailash/nodes/api/__init__.py +52 -0
  11. kailash/nodes/api/auth.py +567 -0
  12. kailash/nodes/api/graphql.py +480 -0
  13. kailash/nodes/api/http.py +598 -0
  14. kailash/nodes/api/rate_limiting.py +572 -0
  15. kailash/nodes/api/rest.py +665 -0
  16. kailash/nodes/base.py +1032 -0
  17. kailash/nodes/base_async.py +128 -0
  18. kailash/nodes/code/__init__.py +32 -0
  19. kailash/nodes/code/python.py +1021 -0
  20. kailash/nodes/data/__init__.py +125 -0
  21. kailash/nodes/data/readers.py +496 -0
  22. kailash/nodes/data/sharepoint_graph.py +623 -0
  23. kailash/nodes/data/sql.py +380 -0
  24. kailash/nodes/data/streaming.py +1168 -0
  25. kailash/nodes/data/vector_db.py +964 -0
  26. kailash/nodes/data/writers.py +529 -0
  27. kailash/nodes/logic/__init__.py +6 -0
  28. kailash/nodes/logic/async_operations.py +702 -0
  29. kailash/nodes/logic/operations.py +551 -0
  30. kailash/nodes/transform/__init__.py +5 -0
  31. kailash/nodes/transform/processors.py +379 -0
  32. kailash/runtime/__init__.py +6 -0
  33. kailash/runtime/async_local.py +356 -0
  34. kailash/runtime/docker.py +697 -0
  35. kailash/runtime/local.py +434 -0
  36. kailash/runtime/parallel.py +557 -0
  37. kailash/runtime/runner.py +110 -0
  38. kailash/runtime/testing.py +347 -0
  39. kailash/sdk_exceptions.py +307 -0
  40. kailash/tracking/__init__.py +7 -0
  41. kailash/tracking/manager.py +885 -0
  42. kailash/tracking/metrics_collector.py +342 -0
  43. kailash/tracking/models.py +535 -0
  44. kailash/tracking/storage/__init__.py +0 -0
  45. kailash/tracking/storage/base.py +113 -0
  46. kailash/tracking/storage/database.py +619 -0
  47. kailash/tracking/storage/filesystem.py +543 -0
  48. kailash/utils/__init__.py +0 -0
  49. kailash/utils/export.py +924 -0
  50. kailash/utils/templates.py +680 -0
  51. kailash/visualization/__init__.py +62 -0
  52. kailash/visualization/api.py +732 -0
  53. kailash/visualization/dashboard.py +951 -0
  54. kailash/visualization/performance.py +808 -0
  55. kailash/visualization/reports.py +1471 -0
  56. kailash/workflow/__init__.py +15 -0
  57. kailash/workflow/builder.py +245 -0
  58. kailash/workflow/graph.py +827 -0
  59. kailash/workflow/mermaid_visualizer.py +628 -0
  60. kailash/workflow/mock_registry.py +63 -0
  61. kailash/workflow/runner.py +302 -0
  62. kailash/workflow/state.py +238 -0
  63. kailash/workflow/visualization.py +588 -0
  64. kailash-0.1.0.dist-info/METADATA +710 -0
  65. kailash-0.1.0.dist-info/RECORD +69 -0
  66. kailash-0.1.0.dist-info/WHEEL +5 -0
  67. kailash-0.1.0.dist-info/entry_points.txt +2 -0
  68. kailash-0.1.0.dist-info/licenses/LICENSE +21 -0
  69. kailash-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,128 @@
1
+ """Asynchronous base node class extension for the Kailash SDK.
2
+
3
+ This module extends the base Node class with asynchronous execution capabilities,
4
+ allowing for more efficient handling of I/O-bound operations in workflows.
5
+ """
6
+
7
+ from datetime import datetime, timezone
8
+ from typing import Any, Dict
9
+
10
+ from kailash.nodes.base import Node
11
+ from kailash.sdk_exceptions import NodeExecutionError, NodeValidationError
12
+
13
+
14
+ class AsyncNode(Node):
15
+ """Base class for asynchronous nodes in the Kailash system.
16
+
17
+ This class extends the standard Node class with async execution capabilities,
18
+ providing a clean interface for implementing asynchronous operations in
19
+ workflow nodes. It's particularly useful for:
20
+
21
+ 1. API calls and network operations
22
+ 2. Database queries
23
+ 3. File operations
24
+ 4. External service integrations
25
+ 5. LLM/AI model inference
26
+
27
+ Design Philosophy:
28
+ - Maintain backward compatibility with synchronous nodes
29
+ - Support both sync and async execution methods
30
+ - Provide clear error handling and logging for async operations
31
+ - Enable efficient parallel execution in workflows
32
+
33
+ Usage Pattern:
34
+ - Override async_run() instead of run() for async functionality
35
+ - Default async_run() implementation calls run() for backward compatibility
36
+ - Node configurtion and validation remain the same as standard nodes
37
+
38
+ Upstream components:
39
+ - Workflow: Creates and manages node instances
40
+ - AsyncWorkflowExecutor: Executes nodes in parallel where possible
41
+ - AsyncLocalRuntime: Runs workflows with async support
42
+
43
+ Downstream usage:
44
+ - Custom AsyncNodes: Implement async_run() for I/O-bound operations
45
+ - TaskManager: Tracks node execution status
46
+ """
47
+
48
+ async def async_run(self, **kwargs) -> Dict[str, Any]:
49
+ """Asynchronous execution method for the node.
50
+
51
+ This method should be overridden by subclasses that require asynchronous
52
+ execution. The default implementation calls the synchronous run() method.
53
+
54
+ Args:
55
+ **kwargs: Input parameters for node execution
56
+
57
+ Returns:
58
+ Dictionary of outputs matching the node's output schema
59
+
60
+ Raises:
61
+ NodeExecutionError: If execution fails
62
+ """
63
+ # Default implementation calls the synchronous run() method
64
+ return self.run(**kwargs)
65
+
66
+ async def execute_async(self, **runtime_inputs) -> Dict[str, Any]:
67
+ """Execute the node asynchronously with validation and error handling.
68
+
69
+ This method follows the same pattern as execute() but supports asynchronous
70
+ execution. It performs:
71
+
72
+ 1. Input validation
73
+ 2. Execution via async_run()
74
+ 3. Output validation
75
+ 4. Error handling and logging
76
+
77
+ Args:
78
+ **runtime_inputs: Runtime inputs for node execution
79
+
80
+ Returns:
81
+ Dictionary of validated outputs
82
+
83
+ Raises:
84
+ NodeValidationError: If inputs or outputs are invalid
85
+ NodeExecutionError: If execution fails
86
+ """
87
+ start_time = datetime.now(timezone.utc)
88
+ try:
89
+ self.logger.info(f"Executing node {self.id} asynchronously")
90
+
91
+ # Merge runtime inputs with config (runtime inputs take precedence)
92
+ merged_inputs = {**self.config, **runtime_inputs}
93
+
94
+ # Handle nested config case (for nodes that store parameters in config['config'])
95
+ if "config" in merged_inputs and isinstance(merged_inputs["config"], dict):
96
+ # Extract nested config
97
+ nested_config = merged_inputs["config"]
98
+ merged_inputs.update(nested_config)
99
+ # Don't remove the config key as some nodes might need it
100
+
101
+ # Validate inputs
102
+ validated_inputs = self.validate_inputs(**merged_inputs)
103
+ self.logger.debug(f"Validated inputs for {self.id}: {validated_inputs}")
104
+
105
+ # Execute node logic asynchronously
106
+ outputs = await self.async_run(**validated_inputs)
107
+
108
+ # Validate outputs
109
+ validated_outputs = self.validate_outputs(outputs)
110
+
111
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
112
+ self.logger.info(
113
+ f"Node {self.id} executed successfully in {execution_time:.3f}s"
114
+ )
115
+ return validated_outputs
116
+
117
+ except NodeValidationError:
118
+ # Re-raise validation errors as-is
119
+ raise
120
+ except NodeExecutionError:
121
+ # Re-raise execution errors as-is
122
+ raise
123
+ except Exception as e:
124
+ # Wrap any other exception in NodeExecutionError
125
+ self.logger.error(f"Node {self.id} execution failed: {e}", exc_info=True)
126
+ raise NodeExecutionError(
127
+ f"Node '{self.id}' execution failed: {type(e).__name__}: {e}"
128
+ ) from e
@@ -0,0 +1,32 @@
1
+ """Code execution nodes for running arbitrary Python code.
2
+
3
+ This module enables users to write custom Python code as functions or classes
4
+ and automatically wrap them as Kailash nodes. This provides maximum flexibility
5
+ for users who need custom processing logic that doesn't fit into predefined nodes.
6
+
7
+ Key Features:
8
+ 1. Function wrapping - Convert any Python function into a node
9
+ 2. Class wrapping - Convert Python classes into stateful nodes
10
+ 3. Dynamic execution - Run arbitrary Python code safely
11
+ 4. Type inference - Automatically detect inputs/outputs
12
+ 5. Error handling - Graceful error management during execution
13
+
14
+ Example:
15
+ # Define a custom function
16
+ def process_data(data: pd.DataFrame, threshold: float) -> pd.DataFrame:
17
+ return data[data['value'] > threshold]
18
+
19
+ # Wrap it as a node
20
+ custom_node = PythonCodeNode.from_function(
21
+ func=process_data,
22
+ name="threshold_filter",
23
+ description="Filter data by threshold"
24
+ )
25
+
26
+ # Use in workflow
27
+ workflow.add_node(custom_node)
28
+ """
29
+
30
+ from .python import ClassWrapper, CodeExecutor, FunctionWrapper, PythonCodeNode
31
+
32
+ __all__ = ["PythonCodeNode", "CodeExecutor", "FunctionWrapper", "ClassWrapper"]