hgraph 0.3.14__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 (255) hide show
  1. hgraph/__init__.py +7 -0
  2. hgraph/_builder/__init__.py +7 -0
  3. hgraph/_builder/_builder.py +28 -0
  4. hgraph/_builder/_graph_builder.py +92 -0
  5. hgraph/_builder/_input_builder.py +19 -0
  6. hgraph/_builder/_node_builder.py +38 -0
  7. hgraph/_builder/_output_builder.py +20 -0
  8. hgraph/_builder/_scalar_builder.py +19 -0
  9. hgraph/_builder/_ts_builder.py +244 -0
  10. hgraph/_impl/__init__.py +5 -0
  11. hgraph/_impl/_builder/__init__.py +7 -0
  12. hgraph/_impl/_builder/_component_builder.py +30 -0
  13. hgraph/_impl/_builder/_graph_builder.py +65 -0
  14. hgraph/_impl/_builder/_map_builder.py +34 -0
  15. hgraph/_impl/_builder/_mesh_builder.py +36 -0
  16. hgraph/_impl/_builder/_node_builder.py +123 -0
  17. hgraph/_impl/_builder/_node_impl_builder.py +29 -0
  18. hgraph/_impl/_builder/_reduce_builder.py +34 -0
  19. hgraph/_impl/_builder/_service_impl_builder.py +30 -0
  20. hgraph/_impl/_builder/_switch_builder.py +35 -0
  21. hgraph/_impl/_builder/_try_except_builder.py +34 -0
  22. hgraph/_impl/_builder/_ts_builder.py +340 -0
  23. hgraph/_impl/_impl_configuration.py +9 -0
  24. hgraph/_impl/_operators/__init__.py +30 -0
  25. hgraph/_impl/_operators/_bool_operators.py +23 -0
  26. hgraph/_impl/_operators/_conversion_operators/__init__.py +12 -0
  27. hgraph/_impl/_operators/_conversion_operators/_compound_scalar_conversion_operators.py +76 -0
  28. hgraph/_impl/_operators/_conversion_operators/_conversion_operator_util.py +17 -0
  29. hgraph/_impl/_operators/_conversion_operators/_date_time_conversion_operators.py +40 -0
  30. hgraph/_impl/_operators/_conversion_operators/_general_conversion_operators.py +13 -0
  31. hgraph/_impl/_operators/_conversion_operators/_mapping_conversion_operators.py +149 -0
  32. hgraph/_impl/_operators/_conversion_operators/_set_conversion_operators.py +97 -0
  33. hgraph/_impl/_operators/_conversion_operators/_ts_conversion_operators.py +75 -0
  34. hgraph/_impl/_operators/_conversion_operators/_tsb_conversion_operators.py +81 -0
  35. hgraph/_impl/_operators/_conversion_operators/_tsd_conversion_operators.py +239 -0
  36. hgraph/_impl/_operators/_conversion_operators/_tsl_conversion_operators.py +83 -0
  37. hgraph/_impl/_operators/_conversion_operators/_tss_conversion_operators.py +134 -0
  38. hgraph/_impl/_operators/_conversion_operators/_tuple_conversion_operators.py +121 -0
  39. hgraph/_impl/_operators/_date_time_operators.py +195 -0
  40. hgraph/_impl/_operators/_enum_operators.py +112 -0
  41. hgraph/_impl/_operators/_flow_control.py +176 -0
  42. hgraph/_impl/_operators/_frame_operators.py +40 -0
  43. hgraph/_impl/_operators/_frozendict_operators.py +250 -0
  44. hgraph/_impl/_operators/_frozenset_operators.py +78 -0
  45. hgraph/_impl/_operators/_getattr.py +12 -0
  46. hgraph/_impl/_operators/_graph_operators.py +187 -0
  47. hgraph/_impl/_operators/_number_operators.py +226 -0
  48. hgraph/_impl/_operators/_record_replay_in_memory.py +218 -0
  49. hgraph/_impl/_operators/_scalar_operators.py +505 -0
  50. hgraph/_impl/_operators/_series_operators.py +109 -0
  51. hgraph/_impl/_operators/_set_operators.py +81 -0
  52. hgraph/_impl/_operators/_str_operators.py +174 -0
  53. hgraph/_impl/_operators/_stream_analytical_operators.py +72 -0
  54. hgraph/_impl/_operators/_stream_operators.py +371 -0
  55. hgraph/_impl/_operators/_time_series_conversion.py +30 -0
  56. hgraph/_impl/_operators/_time_series_properties.py +66 -0
  57. hgraph/_impl/_operators/_to_json.py +95 -0
  58. hgraph/_impl/_operators/_to_table_dispatch_impl.py +241 -0
  59. hgraph/_impl/_operators/_to_table_impl.py +85 -0
  60. hgraph/_impl/_operators/_tsb_operators.py +312 -0
  61. hgraph/_impl/_operators/_tsd_operators.py +601 -0
  62. hgraph/_impl/_operators/_tsl_operators.py +361 -0
  63. hgraph/_impl/_operators/_tss_operators.py +210 -0
  64. hgraph/_impl/_operators/_tuple_operators.py +133 -0
  65. hgraph/_impl/_operators/_type.py +15 -0
  66. hgraph/_impl/_operators/_type_operators.py +32 -0
  67. hgraph/_impl/_operators/_zero.py +40 -0
  68. hgraph/_impl/_runtime/__init__.py +13 -0
  69. hgraph/_impl/_runtime/_common.py +39 -0
  70. hgraph/_impl/_runtime/_component_node.py +129 -0
  71. hgraph/_impl/_runtime/_data_writer.py +25 -0
  72. hgraph/_impl/_runtime/_evaluation_clock.py +157 -0
  73. hgraph/_impl/_runtime/_evaluation_engine.py +136 -0
  74. hgraph/_impl/_runtime/_graph.py +262 -0
  75. hgraph/_impl/_runtime/_graph_executor.py +77 -0
  76. hgraph/_impl/_runtime/_graph_recorder.py +70 -0
  77. hgraph/_impl/_runtime/_map_node.py +181 -0
  78. hgraph/_impl/_runtime/_mesh_node.py +263 -0
  79. hgraph/_impl/_runtime/_nested_evaluation_engine.py +99 -0
  80. hgraph/_impl/_runtime/_node.py +561 -0
  81. hgraph/_impl/_runtime/_reduce_node.py +266 -0
  82. hgraph/_impl/_runtime/_service_node_impl.py +53 -0
  83. hgraph/_impl/_runtime/_switch_node.py +127 -0
  84. hgraph/_impl/_runtime/_try_except_node.py +85 -0
  85. hgraph/_impl/_types/__init__.py +11 -0
  86. hgraph/_impl/_types/_feature_extension.py +60 -0
  87. hgraph/_impl/_types/_input.py +206 -0
  88. hgraph/_impl/_types/_output.py +96 -0
  89. hgraph/_impl/_types/_ref.py +302 -0
  90. hgraph/_impl/_types/_scalar_value.py +49 -0
  91. hgraph/_impl/_types/_signal.py +17 -0
  92. hgraph/_impl/_types/_ts.py +79 -0
  93. hgraph/_impl/_types/_tsb.py +206 -0
  94. hgraph/_impl/_types/_tsd.py +445 -0
  95. hgraph/_impl/_types/_tsl.py +199 -0
  96. hgraph/_impl/_types/_tss.py +279 -0
  97. hgraph/_impl/graph_construction.md +40 -0
  98. hgraph/_operators/__init__.py +13 -0
  99. hgraph/_operators/_analytical_operators.py +46 -0
  100. hgraph/_operators/_flow_control.py +91 -0
  101. hgraph/_operators/_graph_operators.py +107 -0
  102. hgraph/_operators/_operators.py +792 -0
  103. hgraph/_operators/_record_replay.py +152 -0
  104. hgraph/_operators/_stream.py +158 -0
  105. hgraph/_operators/_string.py +70 -0
  106. hgraph/_operators/_time_series_conversion.py +82 -0
  107. hgraph/_operators/_time_series_properties.py +37 -0
  108. hgraph/_operators/_to_json.py +26 -0
  109. hgraph/_operators/_to_table.py +228 -0
  110. hgraph/_operators/_tsd_and_mapping.py +86 -0
  111. hgraph/_operators/_type_operators.py +28 -0
  112. hgraph/_runtime/__init__.py +13 -0
  113. hgraph/_runtime/_constants.py +10 -0
  114. hgraph/_runtime/_data_writer.py +117 -0
  115. hgraph/_runtime/_delayed_binding.py +68 -0
  116. hgraph/_runtime/_evaluation_clock.py +168 -0
  117. hgraph/_runtime/_evaluation_engine.py +367 -0
  118. hgraph/_runtime/_feedback.py +64 -0
  119. hgraph/_runtime/_global_state.py +123 -0
  120. hgraph/_runtime/_graph.py +100 -0
  121. hgraph/_runtime/_graph_executor.py +95 -0
  122. hgraph/_runtime/_graph_recorder.py +49 -0
  123. hgraph/_runtime/_graph_runner.py +181 -0
  124. hgraph/_runtime/_lifecycle.py +150 -0
  125. hgraph/_runtime/_node.py +437 -0
  126. hgraph/_runtime/_traits.py +32 -0
  127. hgraph/_types/__init__.py +24 -0
  128. hgraph/_types/_context_meta_data.py +129 -0
  129. hgraph/_types/_context_type.py +28 -0
  130. hgraph/_types/_error_type.py +131 -0
  131. hgraph/_types/_frame_scalar_type_meta_data.py +159 -0
  132. hgraph/_types/_generic_rank_util.py +39 -0
  133. hgraph/_types/_ref_meta_data.py +121 -0
  134. hgraph/_types/_ref_type.py +66 -0
  135. hgraph/_types/_scalar_type_meta_data.py +1138 -0
  136. hgraph/_types/_scalar_types.py +343 -0
  137. hgraph/_types/_scalar_value.py +82 -0
  138. hgraph/_types/_schema_type.py +283 -0
  139. hgraph/_types/_time_series_meta_data.py +98 -0
  140. hgraph/_types/_time_series_types.py +431 -0
  141. hgraph/_types/_ts_meta_data.py +113 -0
  142. hgraph/_types/_ts_signal_meta_data.py +58 -0
  143. hgraph/_types/_ts_type.py +37 -0
  144. hgraph/_types/_ts_type_var_meta_data.py +146 -0
  145. hgraph/_types/_tsb_meta_data.py +264 -0
  146. hgraph/_types/_tsb_type.py +594 -0
  147. hgraph/_types/_tsd_meta_data.py +158 -0
  148. hgraph/_types/_tsd_type.py +279 -0
  149. hgraph/_types/_tsl_meta_data.py +177 -0
  150. hgraph/_types/_tsl_type.py +243 -0
  151. hgraph/_types/_tss_meta_data.py +104 -0
  152. hgraph/_types/_tss_type.py +117 -0
  153. hgraph/_types/_type_meta_data.py +157 -0
  154. hgraph/_types/_typing_utils.py +103 -0
  155. hgraph/_wiring/__init__.py +19 -0
  156. hgraph/_wiring/_context_wiring.py +227 -0
  157. hgraph/_wiring/_decorators.py +1008 -0
  158. hgraph/_wiring/_dispatch.py +217 -0
  159. hgraph/_wiring/_exception_handling.py +176 -0
  160. hgraph/_wiring/_graph_builder.py +157 -0
  161. hgraph/_wiring/_helper_functions.py +51 -0
  162. hgraph/_wiring/_map.py +692 -0
  163. hgraph/_wiring/_mesh.py +247 -0
  164. hgraph/_wiring/_reduce.py +168 -0
  165. hgraph/_wiring/_source_code_details.py +17 -0
  166. hgraph/_wiring/_stub_wiring_node.py +125 -0
  167. hgraph/_wiring/_switch.py +306 -0
  168. hgraph/_wiring/_wiring_context.py +82 -0
  169. hgraph/_wiring/_wiring_errors.py +189 -0
  170. hgraph/_wiring/_wiring_node_class/__init__.py +19 -0
  171. hgraph/_wiring/_wiring_node_class/_adaptor_impl_node_class.py +130 -0
  172. hgraph/_wiring/_wiring_node_class/_adaptor_node_class.py +149 -0
  173. hgraph/_wiring/_wiring_node_class/_component_node_class.py +161 -0
  174. hgraph/_wiring/_wiring_node_class/_graph_wiring_node_class.py +489 -0
  175. hgraph/_wiring/_wiring_node_class/_map_wiring_node.py +113 -0
  176. hgraph/_wiring/_wiring_node_class/_mesh_wiring_node.py +46 -0
  177. hgraph/_wiring/_wiring_node_class/_node_impl_wiring_node_class.py +34 -0
  178. hgraph/_wiring/_wiring_node_class/_operator_wiring_node.py +220 -0
  179. hgraph/_wiring/_wiring_node_class/_pull_source_node_class.py +66 -0
  180. hgraph/_wiring/_wiring_node_class/_python_const_wiring_node_class.py +49 -0
  181. hgraph/_wiring/_wiring_node_class/_python_wiring_node_classes.py +103 -0
  182. hgraph/_wiring/_wiring_node_class/_reduce_wiring_node.py +60 -0
  183. hgraph/_wiring/_wiring_node_class/_reference_service_node_class.py +109 -0
  184. hgraph/_wiring/_wiring_node_class/_req_repl_service_node_service.py +104 -0
  185. hgraph/_wiring/_wiring_node_class/_service_adaptor_impl_node_class.py +112 -0
  186. hgraph/_wiring/_wiring_node_class/_service_adaptor_node_class.py +179 -0
  187. hgraph/_wiring/_wiring_node_class/_service_impl_node_class.py +392 -0
  188. hgraph/_wiring/_wiring_node_class/_service_interface_node_class.py +39 -0
  189. hgraph/_wiring/_wiring_node_class/_stub_wiring_node_class.py +39 -0
  190. hgraph/_wiring/_wiring_node_class/_subscription_service_node_service.py +104 -0
  191. hgraph/_wiring/_wiring_node_class/_switch_wiring_node.py +74 -0
  192. hgraph/_wiring/_wiring_node_class/_try_except_wiring_node.py +54 -0
  193. hgraph/_wiring/_wiring_node_class/_wiring_node_class.py +521 -0
  194. hgraph/_wiring/_wiring_node_instance.py +221 -0
  195. hgraph/_wiring/_wiring_node_signature.py +710 -0
  196. hgraph/_wiring/_wiring_observer.py +87 -0
  197. hgraph/_wiring/_wiring_port.py +392 -0
  198. hgraph/_wiring/_wiring_utils.py +151 -0
  199. hgraph/adaptors/__init__.py +0 -0
  200. hgraph/adaptors/data_frame/__init__.py +5 -0
  201. hgraph/adaptors/data_frame/_data_frame_operators.py +82 -0
  202. hgraph/adaptors/data_frame/_data_frame_record_replay.py +186 -0
  203. hgraph/adaptors/data_frame/_data_frame_source.py +205 -0
  204. hgraph/adaptors/data_frame/_data_source_generators.py +433 -0
  205. hgraph/adaptors/data_frame/_record_replay_data_frame_impl.py +41 -0
  206. hgraph/adaptors/data_frame/_to_data_frame_converters.py +303 -0
  207. hgraph/adaptors/perspective/__init__.py +11 -0
  208. hgraph/adaptors/perspective/_perspective.py +405 -0
  209. hgraph/adaptors/perspective/_perspective_adaptor.py +118 -0
  210. hgraph/adaptors/perspective/_perspetive_publish.py +231 -0
  211. hgraph/adaptors/perspective/index_template.html +44 -0
  212. hgraph/adaptors/perspective/table_template.html +37 -0
  213. hgraph/adaptors/perspective/workspace_template.html +68 -0
  214. hgraph/adaptors/tornado/__init__.py +0 -0
  215. hgraph/adaptors/tornado/_tornado_web.py +86 -0
  216. hgraph/adaptors/tornado/http_client_adaptor.py +58 -0
  217. hgraph/adaptors/tornado/http_server_adaptor.py +338 -0
  218. hgraph/adaptors/tornado/websocket_client_adaptor.py +76 -0
  219. hgraph/adaptors/tornado/websocket_server_adaptor.py +264 -0
  220. hgraph/debug/__init__.py +1 -0
  221. hgraph/debug/_inspector_controller.py +614 -0
  222. hgraph/debug/_inspector_observer.py +127 -0
  223. hgraph/debug/_inspector_util.py +306 -0
  224. hgraph/debug/_trace_controller.py +100 -0
  225. hgraph/debug/inspector_template.html +141 -0
  226. hgraph/nodes/__init__.py +8 -0
  227. hgraph/nodes/_analytical.py +13 -0
  228. hgraph/nodes/_graph.py +10 -0
  229. hgraph/nodes/_mesh_util.py +68 -0
  230. hgraph/nodes/_numpy.py +121 -0
  231. hgraph/nodes/_pass_through.py +10 -0
  232. hgraph/nodes/_service_utils.py +246 -0
  233. hgraph/nodes/_tsd_operators.py +84 -0
  234. hgraph/nodes/_tsl_operators.py +36 -0
  235. hgraph/nodes/_window_operators.py +60 -0
  236. hgraph/nodes/analytics/__init__.py +4 -0
  237. hgraph/nodes/analytics/_polars_recorder_api_impl.py +203 -0
  238. hgraph/nodes/analytics/_recordable_converters.py +189 -0
  239. hgraph/nodes/analytics/_recordable_feedback.py +158 -0
  240. hgraph/nodes/analytics/_recorder_api.py +215 -0
  241. hgraph/nodes/analytics/_ts_to_data_frame.py +86 -0
  242. hgraph/nodes/analytics/analytics.md +14 -0
  243. hgraph/notebook/NoteBook.md +35 -0
  244. hgraph/notebook/__init__.py +1 -0
  245. hgraph/notebook/_notebook_graph.py +62 -0
  246. hgraph/test/__init__.py +4 -0
  247. hgraph/test/_node_printer.py +182 -0
  248. hgraph/test/_node_profiler.py +124 -0
  249. hgraph/test/_node_unit_tester.py +161 -0
  250. hgraph/test/_wiring_tracer.py +50 -0
  251. hgraph/test/testing.md +19 -0
  252. hgraph-0.3.14.dist-info/LICENSE +21 -0
  253. hgraph-0.3.14.dist-info/METADATA +101 -0
  254. hgraph-0.3.14.dist-info/RECORD +255 -0
  255. hgraph-0.3.14.dist-info/WHEEL +4 -0
hgraph/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ from hgraph._builder import *
2
+ from hgraph._operators import *
3
+ from hgraph._runtime import *
4
+ from hgraph._types import *
5
+ from hgraph._wiring import *
6
+ from hgraph._impl import *
7
+
@@ -0,0 +1,7 @@
1
+ from hgraph._builder._builder import *
2
+ from hgraph._builder._graph_builder import *
3
+ from hgraph._builder._input_builder import *
4
+ from hgraph._builder._node_builder import *
5
+ from hgraph._builder._output_builder import *
6
+ from hgraph._builder._scalar_builder import *
7
+ from hgraph._builder._ts_builder import *
@@ -0,0 +1,28 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import TypeVar, Generic
3
+
4
+ ITEM = TypeVar("ITEM")
5
+
6
+ __all__ = ("Builder",)
7
+
8
+
9
+ class Builder(ABC, Generic[ITEM]):
10
+ """
11
+ The builder is responsible for constructing and initialising the item type it is responsible for.
12
+ It is also responsible for destroying and cleaning up the resources associated to the item.
13
+ These can be thought of as life-cycle methods.
14
+ """
15
+
16
+ @abstractmethod
17
+ def make_instance(self, **kwargs) -> ITEM:
18
+ """
19
+ Create a new instance of the item.
20
+ And additional attributes required for construction are passed in as kwargs.
21
+ Actual instance of the builder will fix these args for all instances of builder for the type.
22
+ """
23
+
24
+ @abstractmethod
25
+ def release_instance(self, item: ITEM):
26
+ """
27
+ Release the item and it's resources.
28
+ """
@@ -0,0 +1,92 @@
1
+ import typing
2
+ from abc import abstractmethod
3
+ from dataclasses import dataclass
4
+ from typing import Iterable
5
+
6
+ from hgraph._builder._builder import Builder
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from hgraph._runtime._graph import Graph
10
+ from hgraph._runtime._node import Node
11
+ from hgraph._builder._node_builder import NodeBuilder
12
+ from hgraph._types._scalar_types import SCALAR
13
+
14
+ __all__ = ("Edge", "GraphBuilder", "GraphBuilderFactory")
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class Edge:
19
+ src_node: int
20
+ output_path: tuple["SCALAR", ...]
21
+ dst_node: int
22
+ input_path: tuple["SCALAR", ...]
23
+
24
+
25
+ @dataclass(frozen=True)
26
+ class GraphBuilder(Builder["Graph"]):
27
+ node_builders: tuple["NodeBuilder", ...]
28
+ edges: tuple[Edge, ...]
29
+
30
+ @abstractmethod
31
+ def make_instance(self, graph_id: tuple[int, ...], parent_node: "Node" = None, label: str = None) -> "Graph":
32
+ """
33
+ Construct an instance of a graph. The id provided is the id for the graph instance to be constructed.
34
+ """
35
+
36
+ @abstractmethod
37
+ def make_and_connect_nodes(self, graph_id: tuple[int, ...], first_node_ndx: int) -> Iterable["Node"]:
38
+ """
39
+ Make the nodes described in the node builders and connect the edges as described in the edges.
40
+ Return the iterable of newly constructed and wired nodes.
41
+ This can be used to feed into a new graph instance or to extend (or re-initialise) an existing graph.
42
+ """
43
+
44
+ @abstractmethod
45
+ def release_instance(self, item: "Graph"):
46
+ """
47
+ Release resources constructed during the build process, plus the graph.
48
+ """
49
+
50
+
51
+ class GraphBuilderFactory:
52
+
53
+ _graph_builder_class: typing.Optional[typing.Type[GraphBuilder]] = None
54
+
55
+ @staticmethod
56
+ def default():
57
+ from hgraph._impl._builder._graph_builder import PythonGraphBuilder
58
+
59
+ return PythonGraphBuilder
60
+
61
+ @staticmethod
62
+ def is_declared() -> bool:
63
+ return GraphBuilderFactory._graph_builder_class is not None
64
+
65
+ @staticmethod
66
+ def declared() -> typing.Type[GraphBuilder]:
67
+ if GraphBuilderFactory._graph_builder_class is None:
68
+ raise RuntimeError("No graph builder type has been declared")
69
+ return GraphBuilderFactory._graph_builder_class
70
+
71
+ @staticmethod
72
+ def declare(cls: typing.Type[GraphBuilder]):
73
+ if GraphBuilderFactory._graph_builder_class is not None:
74
+ raise RuntimeError("A graph builder type has already been declared")
75
+ GraphBuilderFactory._graph_builder_class = cls
76
+
77
+ @staticmethod
78
+ def un_declare():
79
+ GraphBuilderFactory._graph_builder_class = None
80
+
81
+ @staticmethod
82
+ def make(node_builders: tuple["NodeBuilder", ...], edges: tuple[Edge, ...]) -> GraphBuilder:
83
+ """
84
+ Make a graph builder instance. If no graph builder class is declared, the default builder will be used.
85
+ :param node_builders: The node builders to use
86
+ :param edges: The edges to use for binding the node outputs to inputs.
87
+ :return: The GraphBuilder instance.
88
+ """
89
+ if GraphBuilderFactory.is_declared():
90
+ return GraphBuilderFactory.declared()(node_builders=node_builders, edges=edges)
91
+ else:
92
+ return GraphBuilderFactory.default()(node_builders=node_builders, edges=edges)
@@ -0,0 +1,19 @@
1
+ import typing
2
+
3
+ from hgraph._builder._builder import Builder
4
+
5
+ if typing.TYPE_CHECKING:
6
+ from hgraph._types._time_series_types import TimeSeriesInput
7
+ from hgraph._runtime._node import Node
8
+
9
+ __all__ = ("InputBuilder",)
10
+
11
+
12
+ class InputBuilder(Builder["TimeSeriesInput"]):
13
+
14
+ def make_instance(self, owning_node: "Node" = None, owning_input: "TimeSeriesInput" = None) -> "TimeSeriesInput":
15
+ """One of owning_node or owning_input must be defined."""
16
+ raise NotImplementedError()
17
+
18
+ def release_instance(self, item: "TimeSeriesInput"):
19
+ raise NotImplementedError()
@@ -0,0 +1,38 @@
1
+ from abc import abstractmethod
2
+ from dataclasses import dataclass
3
+ from typing import Optional, Any, Mapping, TypeVar
4
+
5
+ from hgraph._builder._builder import Builder
6
+ from hgraph._builder._input_builder import InputBuilder
7
+ from hgraph._builder._output_builder import OutputBuilder
8
+ from hgraph._runtime._node import NodeSignature, Node
9
+
10
+ __all__ = ("NodeBuilder",)
11
+
12
+
13
+ NODE = TypeVar("NODE", bound=Node)
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class NodeBuilder(Builder[NODE]):
18
+ signature: NodeSignature
19
+ scalars: Mapping[str, Any]
20
+ input_builder: Optional[InputBuilder] = None
21
+ output_builder: Optional[OutputBuilder] = None
22
+ error_builder: Optional[OutputBuilder] = None
23
+
24
+ @abstractmethod
25
+ def make_instance(self, owning_graph_id: tuple[int, ...], node_ndx) -> NODE:
26
+ """
27
+ Construct an instance of a node. The id provided is the id for the node instance to be constructed.
28
+ """
29
+
30
+ @abstractmethod
31
+ def release_instance(self, item: NODE):
32
+ """
33
+ Release any resources constructed during the build process, plus the node.
34
+ """
35
+
36
+
37
+ # TODO: Need to ensure that each type of NodeBuilder is described in the abstract and a factory is provided
38
+ # to provide instances of the builder to allow us to support multiple engines.
@@ -0,0 +1,20 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from hgraph._builder._builder import Builder
4
+
5
+ if TYPE_CHECKING:
6
+ from hgraph._runtime._node import Node
7
+ from hgraph._types._time_series_types import TimeSeriesOutput
8
+
9
+
10
+ __all__ = ("OutputBuilder",)
11
+
12
+
13
+ class OutputBuilder(Builder["TimeSeriesOutput"]):
14
+
15
+ def make_instance(self, owning_node: "Node" = None, owning_output: "TimeSeriesOutput" = None) -> "TimeSeriesOutput":
16
+ """One of owning_node or owning_output must be defined."""
17
+ raise NotImplementedError()
18
+
19
+ def release_instance(self, item: "TimeSeriesOutput"):
20
+ raise NotImplementedError()
@@ -0,0 +1,19 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from hgraph._builder._builder import Builder
4
+
5
+ if TYPE_CHECKING:
6
+ from hgraph._types._scalar_value import ScalarValue
7
+
8
+
9
+ __all__ = ("ScalarValueBuilder",)
10
+
11
+
12
+ class ScalarValueBuilder(Builder["ScalarValue"]):
13
+
14
+ def make_instance(self) -> "ScalarValue":
15
+ """A scalar value is a basic type"""
16
+ raise NotImplementedError()
17
+
18
+ def release_instance(self, item: "ScalarValue"):
19
+ raise NotImplementedError()
@@ -0,0 +1,244 @@
1
+ from abc import ABC, abstractmethod
2
+ from dataclasses import dataclass
3
+ from typing import Optional, TYPE_CHECKING
4
+
5
+ from _pytest.nodes import Node
6
+
7
+ from hgraph._types._tsl_meta_data import HgTSLTypeMetaData
8
+ from hgraph._builder._input_builder import InputBuilder
9
+ from hgraph._builder._output_builder import OutputBuilder
10
+ from hgraph._types._tsd_meta_data import HgTSDTypeMetaData
11
+
12
+ if TYPE_CHECKING:
13
+ from hgraph._types._scalar_type_meta_data import HgScalarTypeMetaData
14
+ from hgraph._types._time_series_meta_data import HgTimeSeriesTypeMetaData
15
+ from hgraph._types._time_series_types import TimeSeriesInput, TimeSeriesOutput
16
+ from hgraph._types._tsb_type import TimeSeriesSchema
17
+
18
+ __all__ = (
19
+ "TSOutputBuilder",
20
+ "TSInputBuilder",
21
+ "TimeSeriesBuilderFactory",
22
+ "TSSInputBuilder",
23
+ "TSLOutputBuilder",
24
+ "TSLInputBuilder",
25
+ "TSBOutputBuilder",
26
+ "TSBInputBuilder",
27
+ "TSSOutputBuilder",
28
+ "TSSInputBuilder",
29
+ "TSSignalInputBuilder",
30
+ "TSDOutputBuilder",
31
+ "TSDInputBuilder",
32
+ )
33
+
34
+ """
35
+ This file contains the base signatures for the time-series builders. The implementation needs to provide
36
+ valid instances of each of these signatures and the factory should be provided to resolved an instance of the
37
+ template to the appropriate builder instance.
38
+
39
+ This is here to allow us to write generic wiring logic that will allow for multiple implementations of the engine.
40
+ """
41
+
42
+
43
+ @dataclass(frozen=True)
44
+ class TSOutputBuilder(OutputBuilder):
45
+
46
+ value_tp: "HgScalarTypeMetaData"
47
+
48
+ def make_instance(self, owning_node=None, owning_output=None) -> "TimeSeriesOutput":
49
+ raise NotImplementedError()
50
+
51
+ def release_instance(self, item: "TimeSeriesOutput"):
52
+ raise NotImplementedError()
53
+
54
+
55
+ @dataclass(frozen=True)
56
+ class TSInputBuilder(InputBuilder):
57
+
58
+ value_tp: "HgScalarTypeMetaData"
59
+
60
+ def make_instance(self, owning_node: Node = None, owning_input: "TimeSeriesInput" = None) -> "TimeSeriesInput":
61
+ raise NotImplementedError()
62
+
63
+ def release_instance(self, item: "TimeSeriesInput"):
64
+ raise NotImplementedError()
65
+
66
+
67
+ class TSSignalInputBuilder(InputBuilder):
68
+
69
+ def make_instance(self, owning_node: Node = None, owning_input: "TimeSeriesInput" = None) -> "TimeSeriesInput":
70
+ raise NotImplementedError()
71
+
72
+ def release_instance(self, item: "TimeSeriesInput"):
73
+ raise NotImplementedError()
74
+
75
+
76
+ @dataclass(frozen=True)
77
+ class TSBInputBuilder(InputBuilder):
78
+
79
+ schema: "TimeSeriesSchema"
80
+
81
+ def make_instance(self, owning_node: Node = None, owning_input: "TimeSeriesInput" = None) -> "TimeSeriesInput":
82
+ raise NotImplementedError()
83
+
84
+ def release_instance(self, item: "TimeSeriesInput"):
85
+ raise NotImplementedError()
86
+
87
+
88
+ @dataclass(frozen=True)
89
+ class TSBOutputBuilder(OutputBuilder):
90
+
91
+ schema: "TimeSeriesSchema"
92
+
93
+ def make_instance(self, owning_node: Node = None, owning_output: "TimeSeriesOutput" = None) -> "TimeSeriesOutput":
94
+ raise NotImplementedError()
95
+
96
+ def release_instance(self, item: "TimeSeriesOutput"):
97
+ raise NotImplementedError()
98
+
99
+
100
+ @dataclass(frozen=True)
101
+ class TSLInputBuilder(InputBuilder):
102
+
103
+ value_tp: "HgTimeSeriesTypeMetaData"
104
+ size_tp: "HgScalarTypeMetaData"
105
+
106
+ def make_instance(self, owning_node: Node = None, owning_input: "TimeSeriesInput" = None) -> "TimeSeriesInput":
107
+ raise NotImplementedError()
108
+
109
+ def release_instance(self, item: "TimeSeriesInput"):
110
+ raise NotImplementedError()
111
+
112
+
113
+ @dataclass(frozen=True)
114
+ class TSLOutputBuilder(OutputBuilder):
115
+
116
+ value_tp: "HgTimeSeriesTypeMetaData"
117
+ size_tp: "HgScalarTypeMetaData"
118
+
119
+ def make_instance(self, owning_node: Node = None, owning_output: "TimeSeriesOutput" = None) -> "TimeSeriesOutput":
120
+ raise NotImplementedError()
121
+
122
+ def release_instance(self, item: "TimeSeriesOutput"):
123
+ raise NotImplementedError()
124
+
125
+
126
+ class TSDInputBuilder(InputBuilder):
127
+
128
+ key_tp: "HgScalarTypeMetaData"
129
+ value_tp: "HgTimeSeriesTypeMetaData"
130
+
131
+ def make_instance(self, owning_node: Node = None, owning_input: "TimeSeriesInput" = None) -> "TimeSeriesInput":
132
+ raise NotImplementedError()
133
+
134
+ def release_instance(self, item: "TimeSeriesInput"):
135
+ raise NotImplementedError()
136
+
137
+
138
+ @dataclass(frozen=True)
139
+ class TSDOutputBuilder(OutputBuilder):
140
+
141
+ key_tp: "HgScalarTypeMetaData"
142
+ value_tp: "HgTimeSeriesTypeMetaData"
143
+
144
+ def make_instance(self, owning_node: Node = None, owning_output: "TimeSeriesOutput" = None) -> "TimeSeriesOutput":
145
+ raise NotImplementedError()
146
+
147
+ def release_instance(self, item: "TimeSeriesOutput"):
148
+ raise NotImplementedError()
149
+
150
+
151
+ @dataclass(frozen=True)
152
+ class TSSOutputBuilder(OutputBuilder):
153
+
154
+ value_tp: "HgScalarTypeMetaData"
155
+
156
+ def make_instance(self, owning_node: Node = None, owning_output: "TimeSeriesOutput" = None) -> "TimeSeriesOutput":
157
+ raise NotImplementedError()
158
+
159
+ def release_instance(self, item: "TimeSeriesOutput"):
160
+ raise NotImplementedError()
161
+
162
+
163
+ @dataclass(frozen=True)
164
+ class TSSInputBuilder(InputBuilder):
165
+
166
+ value_tp: "HgScalarTypeMetaData"
167
+
168
+ def make_instance(self, owning_node: Node = None, owning_input: "TimeSeriesInput" = None) -> "TimeSeriesInput":
169
+ raise NotImplementedError()
170
+
171
+ def release_instance(self, item: "TimeSeriesInput"):
172
+ raise NotImplementedError()
173
+
174
+
175
+ class REFInputBuilder(InputBuilder):
176
+ value_tp: "HgTimeSeriesTypeMetaData"
177
+
178
+ def make_instance(self, owning_node: Node = None, owning_input: "TimeSeriesInput" = None) -> "TimeSeriesInput":
179
+ raise NotImplementedError()
180
+
181
+ def release_instance(self, item: "TimeSeriesInput"):
182
+ raise NotImplementedError()
183
+
184
+
185
+ @dataclass(frozen=True)
186
+ class REFOutputBuilder(OutputBuilder):
187
+ value_tp: "HgTimeSeriesTypeMetaData"
188
+
189
+ def make_instance(self, owning_node: Node = None, owning_output: "TimeSeriesOutput" = None) -> "TimeSeriesOutput":
190
+ raise NotImplementedError()
191
+
192
+ def release_instance(self, item: "TimeSeriesOutput"):
193
+ raise NotImplementedError()
194
+
195
+
196
+ class TimeSeriesBuilderFactory:
197
+
198
+ _instance: Optional["TimeSeriesBuilderFactory"] = None
199
+
200
+ @staticmethod
201
+ def declare_default_factory():
202
+ from hgraph._impl._builder._ts_builder import PythonTimeSeriesBuilderFactory
203
+
204
+ TimeSeriesBuilderFactory.declare(PythonTimeSeriesBuilderFactory())
205
+
206
+ @staticmethod
207
+ def has_instance() -> bool:
208
+ return TimeSeriesBuilderFactory._instance is not None
209
+
210
+ @staticmethod
211
+ def instance() -> "TimeSeriesBuilderFactory":
212
+ if TimeSeriesBuilderFactory._instance is None:
213
+ raise RuntimeError("No time-series builder factory has been declared")
214
+ return TimeSeriesBuilderFactory._instance
215
+
216
+ @staticmethod
217
+ def declare(factory: "TimeSeriesBuilderFactory"):
218
+ if TimeSeriesBuilderFactory._instance is not None:
219
+ raise RuntimeError("A time-series builder factory has already been declared")
220
+ TimeSeriesBuilderFactory._instance = factory
221
+
222
+ @staticmethod
223
+ def un_declare():
224
+ TimeSeriesBuilderFactory._instance = None
225
+
226
+ @abstractmethod
227
+ def make_input_builder(self, value_tp: "HgTimeSeriesTypeMetaData") -> TSInputBuilder:
228
+ """Return an instance of an input builder for the given type"""
229
+
230
+ @abstractmethod
231
+ def make_output_builder(self, value_tp: "HgTimeSeriesTypeMetaData") -> TSOutputBuilder:
232
+ """Return an instance of an output builder for the given type"""
233
+
234
+ def make_error_builder(self, error_tp: "HgTimeSeriesTypeMetaData") -> TSOutputBuilder:
235
+ """
236
+ Return an instance of an output builder for the error type.
237
+ Since the error type is fixed, this does not require a type.
238
+ Additionally, since this is defined in terms of an abstract method,
239
+ we can implement directly.
240
+
241
+ The node may require a collection type output. The is_tsd and scalar_tp arguments should be provided
242
+ if the node requires a tsd or is_tsl and size_tp arguments are required if the node requires a list type.
243
+ """
244
+ return self.make_output_builder(error_tp)
@@ -0,0 +1,5 @@
1
+ from hgraph._impl._builder import *
2
+ from hgraph._impl._operators import *
3
+ from hgraph._impl._runtime import *
4
+ from hgraph._impl._types import *
5
+ from hgraph._impl._impl_configuration import *
@@ -0,0 +1,7 @@
1
+ from hgraph._impl._builder._graph_builder import *
2
+ from hgraph._impl._builder._map_builder import *
3
+ from hgraph._impl._builder._node_builder import *
4
+ from hgraph._impl._builder._node_impl_builder import *
5
+ from hgraph._impl._builder._reduce_builder import *
6
+ from hgraph._impl._builder._switch_builder import *
7
+ from hgraph._impl._builder._ts_builder import *
@@ -0,0 +1,30 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional, Mapping
3
+
4
+ from hgraph._impl._builder._node_builder import PythonBaseNodeBuilder
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class PythonComponentNodeBuilder(PythonBaseNodeBuilder):
9
+ nested_graph: Optional["GraphBuilder"] = None # This is the generator function
10
+ # The nodes representing the stub inputs in the nested graph.
11
+ input_node_ids: Mapping[str, int] | None = None
12
+ output_node_id: int | None = None # The node representing the stub output in the nested graph.
13
+
14
+ def make_instance(self, owning_graph_id: tuple[int, ...], node_ndx: int) -> "PythonTryExceptNodeImpl":
15
+ from hgraph._impl._runtime._component_node import PythonComponentNodeImpl
16
+
17
+ node = PythonComponentNodeImpl(
18
+ node_ndx=node_ndx,
19
+ owning_graph_id=owning_graph_id,
20
+ signature=self.signature,
21
+ scalars=self.scalars,
22
+ nested_graph_builder=self.nested_graph,
23
+ input_node_ids=self.input_node_ids,
24
+ output_node_id=self.output_node_id,
25
+ )
26
+
27
+ return self._build_inputs_and_outputs(node)
28
+
29
+ def release_instance(self, item: "PythonTryExceptNodeImpl"):
30
+ """Nothing to be done here"""
@@ -0,0 +1,65 @@
1
+ from dataclasses import dataclass
2
+ from typing import Iterable
3
+
4
+ from hgraph._builder._graph_builder import GraphBuilder
5
+ from hgraph._impl._runtime._graph import PythonGraph
6
+ from hgraph._runtime._graph import Graph
7
+ from hgraph._runtime._node import Node
8
+
9
+ __all__ = ("PythonGraphBuilder",)
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class PythonGraphBuilder(GraphBuilder):
14
+ """
15
+ Builds a graph (set of nodes with edges)
16
+ """
17
+
18
+ @staticmethod
19
+ def _extract_output(node: Node, path: [int]):
20
+ if not path:
21
+ raise RuntimeError("No path to find an output for")
22
+ output = node.output
23
+ for item in path:
24
+ output = output[item]
25
+ return output
26
+
27
+ @staticmethod
28
+ def _extract_input(node: Node, path: [int]):
29
+ if not path:
30
+ raise RuntimeError("No path to find an input for")
31
+ input_ = node.input
32
+ for item in path:
33
+ input_ = input_[item]
34
+ return input_
35
+
36
+ def make_instance(self, graph_id: tuple[int, ...], parent_node: Node = None, label: str = "") -> Graph:
37
+ nodes = self.make_and_connect_nodes(graph_id, 0)
38
+ # The nodes are initialised within the context of the graph
39
+ return PythonGraph(graph_id=graph_id, nodes=nodes, parent_node=parent_node, label=label)
40
+
41
+ def make_and_connect_nodes(self, graph_id: tuple[int, ...], first_node_ndx: int) -> Iterable[Node]:
42
+ nodes = [nb.make_instance(graph_id, ndx + first_node_ndx) for ndx, nb in enumerate(self.node_builders)]
43
+ for edge in self.edges:
44
+ src_node: Node = nodes[edge.src_node]
45
+ dst_node: Node = nodes[edge.dst_node]
46
+ # TODO: Should we normalise outputs to always be an UnnamedBundleOutput? For now if the path is tuple() assume
47
+ # the output is the node output [This would be useful dealing with special outputs like error.
48
+ if edge.output_path == (-1,):
49
+ # This is an error handler
50
+ output = src_node.error_output
51
+ else:
52
+ output = (
53
+ src_node.output if edge.output_path == tuple() else self._extract_output(src_node, edge.output_path)
54
+ )
55
+ input_ = self._extract_input(dst_node, edge.input_path)
56
+ input_.bind_output(output)
57
+ return nodes
58
+
59
+ def release_instance(self, item: Graph):
60
+ for node, node_builder in zip(item.nodes, self.node_builders):
61
+ node_builder.release_instance(node)
62
+ item.dispose()
63
+
64
+ def __hash__(self):
65
+ return hash(id(self))
@@ -0,0 +1,34 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, Mapping, Optional
3
+
4
+ from hgraph._impl._builder._node_builder import PythonBaseNodeBuilder
5
+ from hgraph._impl._runtime._map_node import PythonTsdMapNodeImpl
6
+
7
+ if TYPE_CHECKING:
8
+ from hgraph._builder._graph_builder import GraphBuilder
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class PythonTsdMapNodeBuilder(PythonBaseNodeBuilder):
13
+ nested_graph: Optional["GraphBuilder"] = None # This is the generator function
14
+ input_node_ids: Mapping[str, int] | None = None # The nodes representing the stub inputs in the nested graph.
15
+ output_node_id: int | None = None # The node representing the stub output in the nested graph.
16
+ multiplexed_args: frozenset[str] | None = None # The inputs that need to be de-multiplexed.
17
+ key_arg: str | None = None # The key arg to use, None if no key exists
18
+
19
+ def make_instance(self, owning_graph_id: tuple[int, ...], node_ndx: int) -> PythonTsdMapNodeImpl:
20
+ node = PythonTsdMapNodeImpl(
21
+ node_ndx=node_ndx,
22
+ owning_graph_id=owning_graph_id,
23
+ signature=self.signature,
24
+ scalars=self.scalars,
25
+ nested_graph_builder=self.nested_graph,
26
+ input_node_ids=self.input_node_ids,
27
+ output_node_id=self.output_node_id,
28
+ multiplexed_args=self.multiplexed_args,
29
+ key_arg=self.key_arg,
30
+ )
31
+ return self._build_inputs_and_outputs(node)
32
+
33
+ def release_instance(self, item: PythonTsdMapNodeImpl):
34
+ """Nothing to do"""
@@ -0,0 +1,36 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, Mapping, Optional
3
+
4
+ from hgraph._impl._builder._node_builder import PythonBaseNodeBuilder
5
+ from hgraph._impl._runtime._mesh_node import PythonMeshNodeImpl
6
+
7
+ if TYPE_CHECKING:
8
+ from hgraph._builder._graph_builder import GraphBuilder
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class PythonMeshNodeBuilder(PythonBaseNodeBuilder):
13
+ nested_graph: Optional["GraphBuilder"] = None # This is the generator function
14
+ input_node_ids: Mapping[str, int] | None = None # The nodes representing the stub inputs in the nested graph.
15
+ output_node_id: int | None = None # The node representing the stub output in the nested graph.
16
+ multiplexed_args: frozenset[str] | None = None # The inputs that need to be de-multiplexed.
17
+ key_arg: str | None = None # The key arg to use, None if no key exists
18
+ context_path: str | None = None # The context path to use
19
+
20
+ def make_instance(self, owning_graph_id: tuple[int, ...], node_ndx: int) -> PythonMeshNodeImpl:
21
+ node = PythonMeshNodeImpl(
22
+ node_ndx=node_ndx,
23
+ owning_graph_id=owning_graph_id,
24
+ signature=self.signature,
25
+ scalars=self.scalars,
26
+ nested_graph_builder=self.nested_graph,
27
+ input_node_ids=self.input_node_ids,
28
+ output_node_id=self.output_node_id,
29
+ multiplexed_args=self.multiplexed_args,
30
+ key_arg=self.key_arg,
31
+ context_path=self.context_path,
32
+ )
33
+ return self._build_inputs_and_outputs(node)
34
+
35
+ def release_instance(self, item: PythonMeshNodeImpl):
36
+ """Nothing to do"""