kailash 0.9.14__py3-none-any.whl → 0.9.16__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 (39) hide show
  1. kailash/__init__.py +1 -0
  2. kailash/cli/validate_imports.py +1 -1
  3. kailash/core/ml/query_patterns.py +2 -2
  4. kailash/edge/resource/platform_integration.py +1 -4
  5. kailash/integrations/dataflow_edge.py +2 -2
  6. kailash/migration/__init__.py +30 -0
  7. kailash/migration/cli.py +340 -0
  8. kailash/migration/compatibility_checker.py +662 -0
  9. kailash/migration/configuration_validator.py +837 -0
  10. kailash/migration/documentation_generator.py +1828 -0
  11. kailash/migration/examples/__init__.py +5 -0
  12. kailash/migration/examples/complete_migration_example.py +692 -0
  13. kailash/migration/migration_assistant.py +715 -0
  14. kailash/migration/performance_comparator.py +760 -0
  15. kailash/migration/regression_detector.py +1141 -0
  16. kailash/migration/tests/__init__.py +6 -0
  17. kailash/migration/tests/test_compatibility_checker.py +403 -0
  18. kailash/migration/tests/test_integration.py +463 -0
  19. kailash/migration/tests/test_migration_assistant.py +397 -0
  20. kailash/migration/tests/test_performance_comparator.py +433 -0
  21. kailash/monitoring/alerts.py +2 -2
  22. kailash/nodes/__init__.py +211 -39
  23. kailash/nodes/__init___original.py +57 -0
  24. kailash/nodes/ai/iterative_llm_agent.py +2 -2
  25. kailash/nodes/data/async_sql.py +1507 -6
  26. kailash/runtime/local.py +1255 -8
  27. kailash/runtime/monitoring/__init__.py +1 -0
  28. kailash/runtime/monitoring/runtime_monitor.py +780 -0
  29. kailash/runtime/resource_manager.py +3033 -0
  30. kailash/sdk_exceptions.py +21 -0
  31. kailash/utils/circular_dependency_detector.py +319 -0
  32. kailash/workflow/cyclic_runner.py +18 -2
  33. {kailash-0.9.14.dist-info → kailash-0.9.16.dist-info}/METADATA +1 -1
  34. {kailash-0.9.14.dist-info → kailash-0.9.16.dist-info}/RECORD +39 -19
  35. {kailash-0.9.14.dist-info → kailash-0.9.16.dist-info}/WHEEL +0 -0
  36. {kailash-0.9.14.dist-info → kailash-0.9.16.dist-info}/entry_points.txt +0 -0
  37. {kailash-0.9.14.dist-info → kailash-0.9.16.dist-info}/licenses/LICENSE +0 -0
  38. {kailash-0.9.14.dist-info → kailash-0.9.16.dist-info}/licenses/NOTICE +0 -0
  39. {kailash-0.9.14.dist-info → kailash-0.9.16.dist-info}/top_level.txt +0 -0
kailash/nodes/__init__.py CHANGED
@@ -1,42 +1,24 @@
1
- """Node system for the Kailash SDK."""
2
-
3
- # Import all node modules to ensure registration - fixed circular import
4
- from kailash.nodes.base import Node, NodeParameter, NodeRegistry, register_node
5
- from kailash.nodes.base_cycle_aware import CycleAwareNode
6
- from kailash.nodes.code import PythonCodeNode
7
-
8
- from . import (
9
- ai,
10
- alerts,
11
- api,
12
- auth,
13
- cache,
14
- code,
15
- compliance,
16
- data,
17
- edge,
18
- enterprise,
19
- logic,
20
- mixins,
21
- monitoring,
22
- security,
23
- testing,
24
- transaction,
25
- transform,
26
- )
27
-
28
- # Compatibility alias - AsyncNode is now just Node
29
- AsyncNode = Node
30
-
31
- __all__ = [
32
- "Node",
33
- "AsyncNode", # Compatibility alias
34
- "CycleAwareNode",
35
- "NodeParameter",
36
- "NodeRegistry",
37
- "register_node",
38
- "PythonCodeNode",
39
- # Node modules
1
+ """
2
+ Kailash SDK Nodes Module - Safe Lazy Loading Implementation
3
+
4
+ This implementation provides lazy loading with circular dependency protection
5
+ and maintains full backward compatibility.
6
+ """
7
+
8
+ import importlib
9
+ import sys
10
+ import warnings
11
+ from typing import Any, Dict, Optional, Set
12
+
13
+ # Core imports that are always needed
14
+ from .base import Node, NodeParameter, NodeRegistry
15
+
16
+ # Track loading state to detect circular dependencies
17
+ _LOADING_STACK: Set[str] = set()
18
+ _LOADED_MODULES: Dict[str, Optional[Any]] = {}
19
+
20
+ # Define available node categories for lazy loading
21
+ _NODE_CATEGORIES = [
40
22
  "ai",
41
23
  "alerts",
42
24
  "api",
@@ -50,8 +32,198 @@ __all__ = [
50
32
  "logic",
51
33
  "mixins",
52
34
  "monitoring",
35
+ "rag",
53
36
  "security",
54
37
  "testing",
55
38
  "transaction",
56
39
  "transform",
57
40
  ]
41
+
42
+ # Initialize lazy module cache
43
+ _LAZY_MODULES: Dict[str, Optional[Any]] = {
44
+ category: None for category in _NODE_CATEGORIES
45
+ }
46
+
47
+
48
+ def _safe_lazy_import(name: str) -> Any:
49
+ """
50
+ Safely import a module with circular dependency detection.
51
+
52
+ Args:
53
+ name: The module name to import
54
+
55
+ Returns:
56
+ The imported module
57
+
58
+ Raises:
59
+ ImportError: If a circular dependency is detected
60
+ """
61
+ full_module_name = f"kailash.nodes.{name}"
62
+
63
+ # Check if already loaded
64
+ if name in _LOADED_MODULES:
65
+ return _LOADED_MODULES[name]
66
+
67
+ # Check for circular dependency
68
+ if full_module_name in _LOADING_STACK:
69
+ cycle_modules = list(_LOADING_STACK) + [full_module_name]
70
+ warnings.warn(
71
+ f"Circular dependency detected: {' -> '.join(cycle_modules)}. "
72
+ f"Using partial import to break the cycle.",
73
+ ImportWarning,
74
+ stacklevel=3,
75
+ )
76
+ # Return a placeholder that will be populated after loading
77
+ module = sys.modules.get(full_module_name)
78
+ if module:
79
+ return module
80
+ # Create empty module as placeholder
81
+ module = type(sys)("placeholder")
82
+ sys.modules[full_module_name] = module
83
+ return module
84
+
85
+ # Add to loading stack
86
+ _LOADING_STACK.add(full_module_name)
87
+
88
+ try:
89
+ # Perform the actual import
90
+ module = importlib.import_module(f".{name}", package="kailash.nodes")
91
+ _LOADED_MODULES[name] = module
92
+ return module
93
+ finally:
94
+ # Remove from loading stack
95
+ _LOADING_STACK.discard(full_module_name)
96
+
97
+
98
+ def __getattr__(name: str) -> Any:
99
+ """
100
+ Lazy loading of node category modules with circular dependency protection.
101
+
102
+ This function is called when accessing an attribute that doesn't exist
103
+ in the module's namespace. It enables lazy loading of node categories
104
+ while detecting and handling circular dependencies.
105
+
106
+ Args:
107
+ name: The attribute name being accessed
108
+
109
+ Returns:
110
+ The requested module or attribute
111
+
112
+ Raises:
113
+ AttributeError: If the attribute doesn't exist
114
+ """
115
+ # Check if it's a known node category
116
+ if name in _LAZY_MODULES:
117
+ if _LAZY_MODULES[name] is None:
118
+ try:
119
+ # Use safe import with circular dependency detection
120
+ _LAZY_MODULES[name] = _safe_lazy_import(name)
121
+ except ImportError as e:
122
+ # Log the error and re-raise
123
+ import logging
124
+
125
+ logging.error(f"Failed to import kailash.nodes.{name}: {e}")
126
+ raise
127
+ return _LAZY_MODULES[name]
128
+
129
+ # Handle special attributes
130
+ if name == "__all__":
131
+ return ["Node", "NodeParameter", "NodeRegistry"] + _NODE_CATEGORIES
132
+
133
+ # Attribute not found
134
+ raise AttributeError(f"module 'kailash.nodes' has no attribute '{name}'")
135
+
136
+
137
+ def __dir__():
138
+ """Return the list of available attributes for tab completion."""
139
+ return ["Node", "NodeParameter", "NodeRegistry"] + _NODE_CATEGORIES
140
+
141
+
142
+ def check_circular_dependencies() -> Dict[str, Any]:
143
+ """
144
+ Check for circular dependencies in the nodes module.
145
+
146
+ Returns:
147
+ A dictionary containing:
148
+ - has_circular_deps: Boolean indicating if circular deps exist
149
+ - circular_chains: List of circular dependency chains found
150
+ - warnings: List of warning messages
151
+ """
152
+ from pathlib import Path
153
+
154
+ from ..utils.circular_dependency_detector import CircularDependencyDetector
155
+
156
+ # Get the SDK root directory
157
+ sdk_root = Path(__file__).parent.parent.parent
158
+
159
+ detector = CircularDependencyDetector(sdk_root)
160
+ detector.build_import_graph("src/kailash/nodes")
161
+ cycles = detector.detect_cycles()
162
+
163
+ result = {
164
+ "has_circular_deps": bool(cycles),
165
+ "circular_chains": cycles,
166
+ "warnings": [],
167
+ }
168
+
169
+ if cycles:
170
+ for cycle in cycles:
171
+ result["warnings"].append(
172
+ f"Circular dependency detected: {' -> '.join(cycle)} -> {cycle[0]}"
173
+ )
174
+
175
+ return result
176
+
177
+
178
+ def preload_all_categories():
179
+ """
180
+ Preload all node categories (useful for testing or warming up).
181
+
182
+ This function loads all node categories immediately rather than lazily.
183
+ It's useful for:
184
+ - Testing that all imports work correctly
185
+ - Warming up the import cache
186
+ - Detecting circular dependencies early
187
+ """
188
+ failed_imports = []
189
+
190
+ for category in _NODE_CATEGORIES:
191
+ try:
192
+ _safe_lazy_import(category)
193
+ except ImportError as e:
194
+ failed_imports.append((category, str(e)))
195
+
196
+ if failed_imports:
197
+ warnings.warn(
198
+ f"Failed to import some categories: {failed_imports}", ImportWarning
199
+ )
200
+
201
+ return {
202
+ "loaded": [cat for cat in _NODE_CATEGORIES if cat in _LOADED_MODULES],
203
+ "failed": failed_imports,
204
+ }
205
+
206
+
207
+ # Performance monitoring
208
+ def get_import_stats() -> Dict[str, Any]:
209
+ """
210
+ Get statistics about module imports.
211
+
212
+ Returns:
213
+ Dictionary containing import statistics
214
+ """
215
+ return {
216
+ "loaded_modules": list(_LOADED_MODULES.keys()),
217
+ "pending_modules": [
218
+ cat for cat in _NODE_CATEGORIES if cat not in _LOADED_MODULES
219
+ ],
220
+ "total_categories": len(_NODE_CATEGORIES),
221
+ "loaded_count": len(_LOADED_MODULES),
222
+ "currently_loading": list(_LOADING_STACK),
223
+ }
224
+
225
+
226
+ # Backward compatibility - ensure all existing imports work
227
+ __all__ = ["Node", "NodeParameter", "NodeRegistry"] + _NODE_CATEGORIES
228
+
229
+ # Export core components directly
@@ -0,0 +1,57 @@
1
+ """Node system for the Kailash SDK."""
2
+
3
+ # Import all node modules to ensure registration - fixed circular import
4
+ from kailash.nodes.base import Node, NodeParameter, NodeRegistry, register_node
5
+ from kailash.nodes.base_cycle_aware import CycleAwareNode
6
+ from kailash.nodes.code import PythonCodeNode
7
+
8
+ from . import (
9
+ ai,
10
+ alerts,
11
+ api,
12
+ auth,
13
+ cache,
14
+ code,
15
+ compliance,
16
+ data,
17
+ edge,
18
+ enterprise,
19
+ logic,
20
+ mixins,
21
+ monitoring,
22
+ security,
23
+ testing,
24
+ transaction,
25
+ transform,
26
+ )
27
+
28
+ # Compatibility alias - AsyncNode is now just Node
29
+ AsyncNode = Node
30
+
31
+ __all__ = [
32
+ "Node",
33
+ "AsyncNode", # Compatibility alias
34
+ "CycleAwareNode",
35
+ "NodeParameter",
36
+ "NodeRegistry",
37
+ "register_node",
38
+ "PythonCodeNode",
39
+ # Node modules
40
+ "ai",
41
+ "alerts",
42
+ "api",
43
+ "auth",
44
+ "cache",
45
+ "code",
46
+ "compliance",
47
+ "data",
48
+ "edge",
49
+ "enterprise",
50
+ "logic",
51
+ "mixins",
52
+ "monitoring",
53
+ "security",
54
+ "testing",
55
+ "transaction",
56
+ "transform",
57
+ ]
@@ -1666,7 +1666,7 @@ class IterativeLLMAgentNode(LLMAgentNode):
1666
1666
  synthesis_messages = [
1667
1667
  {
1668
1668
  "role": "system",
1669
- "content": """You are an AI assistant synthesizing results from an iterative analysis process.
1669
+ "content": """You are an AI assistant synthesizing results from an iterative analysis process.
1670
1670
  Create a comprehensive, helpful response based on the findings from multiple iterations of analysis.""",
1671
1671
  },
1672
1672
  {
@@ -1679,7 +1679,7 @@ Results from {len(iterations)} iterations:
1679
1679
  Insights achieved:
1680
1680
  {chr(10).join(all_insights[:5]) if all_insights else "No specific insights achieved"}
1681
1681
 
1682
- Please provide a comprehensive response to the original query based on these findings. If the findings are limited,
1682
+ Please provide a comprehensive response to the original query based on these findings. If the findings are limited,
1683
1683
  provide your best analysis of the query directly.""",
1684
1684
  },
1685
1685
  ]