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.
Files changed (117) hide show
  1. kailash/__init__.py +1 -1
  2. kailash/access_control.py +40 -39
  3. kailash/api/auth.py +26 -32
  4. kailash/api/custom_nodes.py +29 -29
  5. kailash/api/custom_nodes_secure.py +35 -35
  6. kailash/api/database.py +17 -17
  7. kailash/api/gateway.py +19 -19
  8. kailash/api/mcp_integration.py +24 -23
  9. kailash/api/studio.py +45 -45
  10. kailash/api/workflow_api.py +8 -8
  11. kailash/cli/commands.py +5 -8
  12. kailash/manifest.py +42 -42
  13. kailash/mcp/__init__.py +1 -1
  14. kailash/mcp/ai_registry_server.py +20 -20
  15. kailash/mcp/client.py +9 -11
  16. kailash/mcp/client_new.py +10 -10
  17. kailash/mcp/server.py +1 -2
  18. kailash/mcp/server_enhanced.py +449 -0
  19. kailash/mcp/servers/ai_registry.py +6 -6
  20. kailash/mcp/utils/__init__.py +31 -0
  21. kailash/mcp/utils/cache.py +267 -0
  22. kailash/mcp/utils/config.py +263 -0
  23. kailash/mcp/utils/formatters.py +293 -0
  24. kailash/mcp/utils/metrics.py +418 -0
  25. kailash/nodes/ai/agents.py +9 -9
  26. kailash/nodes/ai/ai_providers.py +33 -34
  27. kailash/nodes/ai/embedding_generator.py +31 -32
  28. kailash/nodes/ai/intelligent_agent_orchestrator.py +62 -66
  29. kailash/nodes/ai/iterative_llm_agent.py +48 -48
  30. kailash/nodes/ai/llm_agent.py +32 -33
  31. kailash/nodes/ai/models.py +13 -13
  32. kailash/nodes/ai/self_organizing.py +44 -44
  33. kailash/nodes/api/__init__.py +5 -0
  34. kailash/nodes/api/auth.py +11 -11
  35. kailash/nodes/api/graphql.py +13 -13
  36. kailash/nodes/api/http.py +19 -19
  37. kailash/nodes/api/monitoring.py +463 -0
  38. kailash/nodes/api/rate_limiting.py +9 -13
  39. kailash/nodes/api/rest.py +29 -29
  40. kailash/nodes/api/security.py +819 -0
  41. kailash/nodes/base.py +24 -26
  42. kailash/nodes/base_async.py +7 -7
  43. kailash/nodes/base_cycle_aware.py +12 -12
  44. kailash/nodes/base_with_acl.py +5 -5
  45. kailash/nodes/code/python.py +56 -55
  46. kailash/nodes/data/__init__.py +6 -0
  47. kailash/nodes/data/directory.py +6 -6
  48. kailash/nodes/data/event_generation.py +297 -0
  49. kailash/nodes/data/file_discovery.py +598 -0
  50. kailash/nodes/data/readers.py +8 -8
  51. kailash/nodes/data/retrieval.py +10 -10
  52. kailash/nodes/data/sharepoint_graph.py +17 -17
  53. kailash/nodes/data/sources.py +5 -5
  54. kailash/nodes/data/sql.py +13 -13
  55. kailash/nodes/data/streaming.py +25 -25
  56. kailash/nodes/data/vector_db.py +22 -22
  57. kailash/nodes/data/writers.py +7 -7
  58. kailash/nodes/logic/async_operations.py +17 -17
  59. kailash/nodes/logic/convergence.py +11 -11
  60. kailash/nodes/logic/loop.py +4 -4
  61. kailash/nodes/logic/operations.py +11 -11
  62. kailash/nodes/logic/workflow.py +8 -9
  63. kailash/nodes/mixins/mcp.py +17 -17
  64. kailash/nodes/mixins.py +8 -10
  65. kailash/nodes/transform/chunkers.py +3 -3
  66. kailash/nodes/transform/formatters.py +7 -7
  67. kailash/nodes/transform/processors.py +11 -11
  68. kailash/runtime/access_controlled.py +18 -18
  69. kailash/runtime/async_local.py +18 -20
  70. kailash/runtime/docker.py +24 -26
  71. kailash/runtime/local.py +55 -31
  72. kailash/runtime/parallel.py +25 -25
  73. kailash/runtime/parallel_cyclic.py +29 -29
  74. kailash/runtime/runner.py +6 -6
  75. kailash/runtime/testing.py +22 -22
  76. kailash/sdk_exceptions.py +0 -58
  77. kailash/security.py +14 -26
  78. kailash/tracking/manager.py +38 -38
  79. kailash/tracking/metrics_collector.py +15 -14
  80. kailash/tracking/models.py +53 -53
  81. kailash/tracking/storage/base.py +7 -17
  82. kailash/tracking/storage/database.py +22 -23
  83. kailash/tracking/storage/filesystem.py +38 -40
  84. kailash/utils/export.py +21 -21
  85. kailash/utils/templates.py +8 -9
  86. kailash/visualization/api.py +30 -34
  87. kailash/visualization/dashboard.py +17 -17
  88. kailash/visualization/performance.py +32 -19
  89. kailash/visualization/reports.py +30 -28
  90. kailash/workflow/builder.py +8 -8
  91. kailash/workflow/convergence.py +13 -12
  92. kailash/workflow/cycle_analyzer.py +38 -33
  93. kailash/workflow/cycle_builder.py +12 -12
  94. kailash/workflow/cycle_config.py +16 -15
  95. kailash/workflow/cycle_debugger.py +40 -40
  96. kailash/workflow/cycle_exceptions.py +29 -29
  97. kailash/workflow/cycle_profiler.py +21 -21
  98. kailash/workflow/cycle_state.py +20 -22
  99. kailash/workflow/cyclic_runner.py +45 -45
  100. kailash/workflow/graph.py +57 -45
  101. kailash/workflow/mermaid_visualizer.py +9 -11
  102. kailash/workflow/migration.py +22 -22
  103. kailash/workflow/mock_registry.py +6 -6
  104. kailash/workflow/runner.py +9 -9
  105. kailash/workflow/safety.py +12 -13
  106. kailash/workflow/state.py +8 -11
  107. kailash/workflow/templates.py +19 -19
  108. kailash/workflow/validation.py +14 -14
  109. kailash/workflow/visualization.py +32 -24
  110. kailash-0.3.1.dist-info/METADATA +476 -0
  111. kailash-0.3.1.dist-info/RECORD +136 -0
  112. kailash-0.2.2.dist-info/METADATA +0 -121
  113. kailash-0.2.2.dist-info/RECORD +0 -126
  114. {kailash-0.2.2.dist-info → kailash-0.3.1.dist-info}/WHEEL +0 -0
  115. {kailash-0.2.2.dist-info → kailash-0.3.1.dist-info}/entry_points.txt +0 -0
  116. {kailash-0.2.2.dist-info → kailash-0.3.1.dist-info}/licenses/LICENSE +0 -0
  117. {kailash-0.2.2.dist-info → kailash-0.3.1.dist-info}/top_level.txt +0 -0
kailash/nodes/api/auth.py CHANGED
@@ -12,7 +12,7 @@ Key Components:
12
12
 
13
13
  import base64
14
14
  import time
15
- from typing import Any, Dict
15
+ from typing import Any
16
16
 
17
17
  import requests
18
18
 
@@ -42,7 +42,7 @@ class BasicAuthNode(Node):
42
42
  - RESTClientNode: Uses auth headers for API calls
43
43
  """
44
44
 
45
- def get_parameters(self) -> Dict[str, NodeParameter]:
45
+ def get_parameters(self) -> dict[str, NodeParameter]:
46
46
  """Define the parameters this node accepts.
47
47
 
48
48
  Returns:
@@ -63,7 +63,7 @@ class BasicAuthNode(Node):
63
63
  ),
64
64
  }
65
65
 
66
- def get_output_schema(self) -> Dict[str, NodeParameter]:
66
+ def get_output_schema(self) -> dict[str, NodeParameter]:
67
67
  """Define the output schema for this node.
68
68
 
69
69
  Returns:
@@ -84,7 +84,7 @@ class BasicAuthNode(Node):
84
84
  ),
85
85
  }
86
86
 
87
- def run(self, **kwargs) -> Dict[str, Any]:
87
+ def run(self, **kwargs) -> dict[str, Any]:
88
88
  """Generate Basic Authentication headers.
89
89
 
90
90
  Args:
@@ -162,7 +162,7 @@ class OAuth2Node(Node):
162
162
  self.token_data = None # Will store token information
163
163
  self.token_expires_at = 0 # Timestamp when token expires
164
164
 
165
- def get_parameters(self) -> Dict[str, NodeParameter]:
165
+ def get_parameters(self) -> dict[str, NodeParameter]:
166
166
  """Define the parameters this node accepts.
167
167
 
168
168
  Returns:
@@ -236,7 +236,7 @@ class OAuth2Node(Node):
236
236
  ),
237
237
  }
238
238
 
239
- def get_output_schema(self) -> Dict[str, NodeParameter]:
239
+ def get_output_schema(self) -> dict[str, NodeParameter]:
240
240
  """Define the output schema for this node.
241
241
 
242
242
  Returns:
@@ -269,7 +269,7 @@ class OAuth2Node(Node):
269
269
  ),
270
270
  }
271
271
 
272
- def _get_token(self, **kwargs) -> Dict[str, Any]:
272
+ def _get_token(self, **kwargs) -> dict[str, Any]:
273
273
  """Get an OAuth token using the configured grant type.
274
274
 
275
275
  This method handles different grant types with appropriate parameters.
@@ -359,7 +359,7 @@ class OAuth2Node(Node):
359
359
  f"Failed to parse OAuth token response: {str(e)}"
360
360
  ) from e
361
361
 
362
- def run(self, **kwargs) -> Dict[str, Any]:
362
+ def run(self, **kwargs) -> dict[str, Any]:
363
363
  """Get OAuth authentication headers.
364
364
 
365
365
  This method handles token acquisition, caching, and renewal based on
@@ -444,7 +444,7 @@ class APIKeyNode(Node):
444
444
  - RESTClientNode: Uses auth data for API calls
445
445
  """
446
446
 
447
- def get_parameters(self) -> Dict[str, NodeParameter]:
447
+ def get_parameters(self) -> dict[str, NodeParameter]:
448
448
  """Define the parameters this node accepts.
449
449
 
450
450
  Returns:
@@ -477,7 +477,7 @@ class APIKeyNode(Node):
477
477
  ),
478
478
  }
479
479
 
480
- def get_output_schema(self) -> Dict[str, NodeParameter]:
480
+ def get_output_schema(self) -> dict[str, NodeParameter]:
481
481
  """Define the output schema for this node.
482
482
 
483
483
  Returns:
@@ -510,7 +510,7 @@ class APIKeyNode(Node):
510
510
  ),
511
511
  }
512
512
 
513
- def run(self, **kwargs) -> Dict[str, Any]:
513
+ def run(self, **kwargs) -> dict[str, Any]:
514
514
  """Generate API key authentication data.
515
515
 
516
516
  Args:
@@ -10,7 +10,7 @@ Key Components:
10
10
  - GraphQL query building and response handling utilities
11
11
  """
12
12
 
13
- from typing import Any, Dict, Optional
13
+ from typing import Any
14
14
 
15
15
  from kailash.nodes.api.http import AsyncHTTPRequestNode, HTTPRequestNode
16
16
  from kailash.nodes.base import Node, NodeParameter, register_node
@@ -60,7 +60,7 @@ class GraphQLClientNode(Node):
60
60
  super().__init__(**kwargs)
61
61
  self.http_node = HTTPRequestNode(**kwargs)
62
62
 
63
- def get_parameters(self) -> Dict[str, NodeParameter]:
63
+ def get_parameters(self) -> dict[str, NodeParameter]:
64
64
  """Define the parameters this node accepts.
65
65
 
66
66
  Returns:
@@ -137,7 +137,7 @@ class GraphQLClientNode(Node):
137
137
  ),
138
138
  }
139
139
 
140
- def get_output_schema(self) -> Dict[str, NodeParameter]:
140
+ def get_output_schema(self) -> dict[str, NodeParameter]:
141
141
  """Define the output schema for this node.
142
142
 
143
143
  Returns:
@@ -173,9 +173,9 @@ class GraphQLClientNode(Node):
173
173
  def _build_graphql_payload(
174
174
  self,
175
175
  query: str,
176
- variables: Dict[str, Any] = None,
177
- operation_name: Optional[str] = None,
178
- ) -> Dict[str, Any]:
176
+ variables: dict[str, Any] = None,
177
+ operation_name: str | None = None,
178
+ ) -> dict[str, Any]:
179
179
  """Build a GraphQL request payload.
180
180
 
181
181
  Args:
@@ -197,8 +197,8 @@ class GraphQLClientNode(Node):
197
197
  return payload
198
198
 
199
199
  def _process_graphql_response(
200
- self, response: Dict[str, Any], flatten_response: bool = False
201
- ) -> Dict[str, Any]:
200
+ self, response: dict[str, Any], flatten_response: bool = False
201
+ ) -> dict[str, Any]:
202
202
  """Process a GraphQL response.
203
203
 
204
204
  Args:
@@ -241,7 +241,7 @@ class GraphQLClientNode(Node):
241
241
 
242
242
  return {"data": data, "errors": errors, "success": success}
243
243
 
244
- def run(self, **kwargs) -> Dict[str, Any]:
244
+ def run(self, **kwargs) -> dict[str, Any]:
245
245
  """Execute a GraphQL query or mutation.
246
246
 
247
247
  Args:
@@ -362,7 +362,7 @@ class AsyncGraphQLClientNode(AsyncNode):
362
362
  self.http_node = AsyncHTTPRequestNode(**kwargs)
363
363
  self.graphql_node = GraphQLClientNode(**kwargs)
364
364
 
365
- def get_parameters(self) -> Dict[str, NodeParameter]:
365
+ def get_parameters(self) -> dict[str, NodeParameter]:
366
366
  """Define the parameters this node accepts.
367
367
 
368
368
  Returns:
@@ -371,7 +371,7 @@ class AsyncGraphQLClientNode(AsyncNode):
371
371
  # Same parameters as the synchronous version
372
372
  return self.graphql_node.get_parameters()
373
373
 
374
- def get_output_schema(self) -> Dict[str, NodeParameter]:
374
+ def get_output_schema(self) -> dict[str, NodeParameter]:
375
375
  """Define the output schema for this node.
376
376
 
377
377
  Returns:
@@ -380,7 +380,7 @@ class AsyncGraphQLClientNode(AsyncNode):
380
380
  # Same output schema as the synchronous version
381
381
  return self.graphql_node.get_output_schema()
382
382
 
383
- def run(self, **kwargs) -> Dict[str, Any]:
383
+ def run(self, **kwargs) -> dict[str, Any]:
384
384
  """Synchronous version of the GraphQL request, for compatibility.
385
385
 
386
386
  This is implemented for compatibility but users should use the
@@ -399,7 +399,7 @@ class AsyncGraphQLClientNode(AsyncNode):
399
399
  # Forward to the synchronous GraphQL node
400
400
  return self.graphql_node.run(**kwargs)
401
401
 
402
- async def async_run(self, **kwargs) -> Dict[str, Any]:
402
+ async def async_run(self, **kwargs) -> dict[str, Any]:
403
403
  """Execute a GraphQL query or mutation asynchronously.
404
404
 
405
405
  Args:
kailash/nodes/api/http.py CHANGED
@@ -8,7 +8,7 @@ import asyncio
8
8
  import base64
9
9
  import time
10
10
  from enum import Enum
11
- from typing import Any, Dict, Optional
11
+ from typing import Any
12
12
 
13
13
  import aiohttp
14
14
  import requests
@@ -48,8 +48,8 @@ class HTTPResponse(BaseModel):
48
48
  """
49
49
 
50
50
  status_code: int
51
- headers: Dict[str, str]
52
- content_type: Optional[str] = None
51
+ headers: dict[str, str]
52
+ content_type: str | None = None
53
53
  content: Any # Can be dict, str, bytes depending on response format
54
54
  response_time_ms: float
55
55
  url: str
@@ -194,7 +194,7 @@ class HTTPRequestNode(Node):
194
194
  super().__init__(**kwargs)
195
195
  self.session = requests.Session()
196
196
 
197
- def get_parameters(self) -> Dict[str, NodeParameter]:
197
+ def get_parameters(self) -> dict[str, NodeParameter]:
198
198
  """Define the parameters this node accepts.
199
199
 
200
200
  Returns:
@@ -328,7 +328,7 @@ class HTTPRequestNode(Node):
328
328
  ),
329
329
  }
330
330
 
331
- def get_output_schema(self) -> Dict[str, NodeParameter]:
331
+ def get_output_schema(self) -> dict[str, NodeParameter]:
332
332
  """Define the output schema for this node.
333
333
 
334
334
  Returns:
@@ -358,10 +358,10 @@ class HTTPRequestNode(Node):
358
358
  def _apply_authentication(
359
359
  self,
360
360
  headers: dict,
361
- auth_type: Optional[str],
362
- auth_token: Optional[str],
363
- auth_username: Optional[str],
364
- auth_password: Optional[str],
361
+ auth_type: str | None,
362
+ auth_token: str | None,
363
+ auth_username: str | None,
364
+ auth_password: str | None,
365
365
  api_key_header: str,
366
366
  ) -> dict:
367
367
  """Apply authentication to request headers.
@@ -398,7 +398,7 @@ class HTTPRequestNode(Node):
398
398
 
399
399
  return auth_headers
400
400
 
401
- def run(self, **kwargs) -> Dict[str, Any]:
401
+ def run(self, **kwargs) -> dict[str, Any]:
402
402
  """Execute an HTTP request.
403
403
 
404
404
  Args:
@@ -683,7 +683,7 @@ class AsyncHTTPRequestNode(AsyncNode):
683
683
  super().__init__(**kwargs)
684
684
  self._session = None # Will be created when needed
685
685
 
686
- def get_parameters(self) -> Dict[str, NodeParameter]:
686
+ def get_parameters(self) -> dict[str, NodeParameter]:
687
687
  """Define the parameters this node accepts.
688
688
 
689
689
  Returns:
@@ -692,7 +692,7 @@ class AsyncHTTPRequestNode(AsyncNode):
692
692
  # Same parameters as the synchronous version
693
693
  return HTTPRequestNode().get_parameters()
694
694
 
695
- def get_output_schema(self) -> Dict[str, NodeParameter]:
695
+ def get_output_schema(self) -> dict[str, NodeParameter]:
696
696
  """Define the output schema for this node.
697
697
 
698
698
  Returns:
@@ -704,10 +704,10 @@ class AsyncHTTPRequestNode(AsyncNode):
704
704
  def _apply_authentication(
705
705
  self,
706
706
  headers: dict,
707
- auth_type: Optional[str],
708
- auth_token: Optional[str],
709
- auth_username: Optional[str],
710
- auth_password: Optional[str],
707
+ auth_type: str | None,
708
+ auth_token: str | None,
709
+ auth_username: str | None,
710
+ auth_password: str | None,
711
711
  api_key_header: str,
712
712
  ) -> dict:
713
713
  """Apply authentication to request headers.
@@ -744,7 +744,7 @@ class AsyncHTTPRequestNode(AsyncNode):
744
744
 
745
745
  return auth_headers
746
746
 
747
- def run(self, **kwargs) -> Dict[str, Any]:
747
+ def run(self, **kwargs) -> dict[str, Any]:
748
748
  """Synchronous version of the request, for compatibility.
749
749
 
750
750
  This is implemented for compatibility but users should use the
@@ -763,7 +763,7 @@ class AsyncHTTPRequestNode(AsyncNode):
763
763
  http_node = HTTPRequestNode(**self.config)
764
764
  return http_node.run(**kwargs)
765
765
 
766
- async def async_run(self, **kwargs) -> Dict[str, Any]:
766
+ async def async_run(self, **kwargs) -> dict[str, Any]:
767
767
  """Execute an HTTP request asynchronously.
768
768
 
769
769
  Args:
@@ -937,7 +937,7 @@ class AsyncHTTPRequestNode(AsyncNode):
937
937
 
938
938
  return result
939
939
 
940
- except (aiohttp.ClientError, asyncio.TimeoutError) as e:
940
+ except (TimeoutError, aiohttp.ClientError) as e:
941
941
  self.logger.warning(f"Async request failed: {str(e)}")
942
942
 
943
943
  # Last attempt, no more retries