jaseci 1.4.2.6__py3-none-any.whl → 2.0.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.

Potentially problematic release.


This version of jaseci might be problematic. Click here for more details.

Files changed (187) hide show
  1. jaseci/__init__.py +3 -37
  2. jaseci-2.0.0.dist-info/METADATA +65 -0
  3. jaseci-2.0.0.dist-info/RECORD +4 -0
  4. {jaseci-1.4.2.6.dist-info → jaseci-2.0.0.dist-info}/WHEEL +1 -2
  5. jaseci/VERSION +0 -1
  6. jaseci/cli_tools/__init__.py +0 -0
  7. jaseci/cli_tools/book_tools.py +0 -457
  8. jaseci/cli_tools/jsctl.py +0 -500
  9. jaseci/cli_tools/tests/__init__.py +0 -0
  10. jaseci/cli_tools/tests/test_jsctl.py +0 -556
  11. jaseci/extens/__init__.py +0 -0
  12. jaseci/extens/act_lib/__init__.py +0 -0
  13. jaseci/extens/act_lib/date.py +0 -118
  14. jaseci/extens/act_lib/elastic.py +0 -87
  15. jaseci/extens/act_lib/file.py +0 -77
  16. jaseci/extens/act_lib/file_handler.py +0 -190
  17. jaseci/extens/act_lib/internal.py +0 -19
  18. jaseci/extens/act_lib/jaseci.py +0 -62
  19. jaseci/extens/act_lib/mail.py +0 -10
  20. jaseci/extens/act_lib/maths.py +0 -168
  21. jaseci/extens/act_lib/net.py +0 -192
  22. jaseci/extens/act_lib/rand.py +0 -83
  23. jaseci/extens/act_lib/regex.py +0 -85
  24. jaseci/extens/act_lib/request.py +0 -170
  25. jaseci/extens/act_lib/std.py +0 -236
  26. jaseci/extens/act_lib/storage.py +0 -53
  27. jaseci/extens/act_lib/stripe.py +0 -338
  28. jaseci/extens/act_lib/task.py +0 -14
  29. jaseci/extens/act_lib/tests/__init__.py +0 -0
  30. jaseci/extens/act_lib/tests/std_test_code.py +0 -37
  31. jaseci/extens/act_lib/tests/test_date.py +0 -26
  32. jaseci/extens/act_lib/tests/test_elastic.py +0 -159
  33. jaseci/extens/act_lib/tests/test_file.py +0 -116
  34. jaseci/extens/act_lib/tests/test_file_lib.py +0 -40
  35. jaseci/extens/act_lib/tests/test_mail_lib.py +0 -33
  36. jaseci/extens/act_lib/tests/test_maths.py +0 -147
  37. jaseci/extens/act_lib/tests/test_net_lib.py +0 -62
  38. jaseci/extens/act_lib/tests/test_regex.py +0 -61
  39. jaseci/extens/act_lib/tests/test_std.py +0 -51
  40. jaseci/extens/act_lib/tests/test_std_lib.py +0 -36
  41. jaseci/extens/act_lib/tests/test_url.py +0 -32
  42. jaseci/extens/act_lib/tests/test_vector.py +0 -36
  43. jaseci/extens/act_lib/tests/test_webtool.py +0 -44
  44. jaseci/extens/act_lib/tests/test_zlib.py +0 -24
  45. jaseci/extens/act_lib/url.py +0 -80
  46. jaseci/extens/act_lib/vector.py +0 -158
  47. jaseci/extens/act_lib/webtool.py +0 -29
  48. jaseci/extens/act_lib/zip.py +0 -34
  49. jaseci/extens/api/__init__.py +0 -0
  50. jaseci/extens/api/actions_api.py +0 -171
  51. jaseci/extens/api/alias_api.py +0 -140
  52. jaseci/extens/api/architype_api.py +0 -197
  53. jaseci/extens/api/config_api.py +0 -129
  54. jaseci/extens/api/global_api.py +0 -85
  55. jaseci/extens/api/graph_api.py +0 -168
  56. jaseci/extens/api/health_api.py +0 -21
  57. jaseci/extens/api/interface.py +0 -269
  58. jaseci/extens/api/jac_api.py +0 -172
  59. jaseci/extens/api/jsorc_api.py +0 -317
  60. jaseci/extens/api/logger_api.py +0 -90
  61. jaseci/extens/api/master_api.py +0 -134
  62. jaseci/extens/api/object_api.py +0 -102
  63. jaseci/extens/api/prometheus_api.py +0 -75
  64. jaseci/extens/api/queue_api.py +0 -141
  65. jaseci/extens/api/sentinel_api.py +0 -271
  66. jaseci/extens/api/share_api.py +0 -64
  67. jaseci/extens/api/super_api.py +0 -65
  68. jaseci/extens/api/tests/__init__.py +0 -0
  69. jaseci/extens/api/tests/test_architype_api.py +0 -66
  70. jaseci/extens/api/tests/test_global_api.py +0 -179
  71. jaseci/extens/api/tests/test_graph_api.py +0 -64
  72. jaseci/extens/api/tests/test_logger_api.py +0 -43
  73. jaseci/extens/api/tests/test_object_api.py +0 -20
  74. jaseci/extens/api/tests/test_sentinel_api.py +0 -66
  75. jaseci/extens/api/tests/test_uncommon.py +0 -107
  76. jaseci/extens/api/tests/test_user_api.py +0 -32
  77. jaseci/extens/api/tests/test_walker_api.py +0 -316
  78. jaseci/extens/api/user_api.py +0 -166
  79. jaseci/extens/api/walker_api.py +0 -299
  80. jaseci/extens/api/webhook_api.py +0 -77
  81. jaseci/extens/svc/__init__.py +0 -0
  82. jaseci/extens/svc/elastic_svc.py +0 -366
  83. jaseci/extens/svc/kube_svc.py +0 -432
  84. jaseci/extens/svc/mail_svc.py +0 -156
  85. jaseci/extens/svc/prome_svc.py +0 -378
  86. jaseci/extens/svc/redis_svc.py +0 -63
  87. jaseci/extens/svc/storage_svc.py +0 -193
  88. jaseci/extens/svc/stripe_svc.py +0 -51
  89. jaseci/extens/svc/task_svc.py +0 -155
  90. jaseci/extens/svc/tasks.py +0 -302
  91. jaseci/jac/__init__.py +0 -0
  92. jaseci/jac/interpreter/__init__.py +0 -0
  93. jaseci/jac/interpreter/architype_interp.py +0 -219
  94. jaseci/jac/interpreter/interp.py +0 -1784
  95. jaseci/jac/interpreter/sentinel_interp.py +0 -260
  96. jaseci/jac/interpreter/tests/__init__.py +0 -0
  97. jaseci/jac/interpreter/tests/test_interp.py +0 -42
  98. jaseci/jac/interpreter/walker_interp.py +0 -249
  99. jaseci/jac/ir/__init__.py +0 -0
  100. jaseci/jac/ir/ast.py +0 -73
  101. jaseci/jac/ir/ast_builder.py +0 -249
  102. jaseci/jac/ir/jac_code.py +0 -151
  103. jaseci/jac/ir/passes/__init__.py +0 -6
  104. jaseci/jac/ir/passes/ast_prune_pass.py +0 -9
  105. jaseci/jac/ir/passes/codegen_pass.py +0 -244
  106. jaseci/jac/ir/passes/ir_pass.py +0 -29
  107. jaseci/jac/ir/passes/printer_pass.py +0 -23
  108. jaseci/jac/ir/passes/pt_prune_pass.py +0 -29
  109. jaseci/jac/ir/passes/schedule.py +0 -23
  110. jaseci/jac/ir/passes/stats_pass.py +0 -16
  111. jaseci/jac/jac.g4 +0 -450
  112. jaseci/jac/jac_parse/__init__.py +0 -0
  113. jaseci/jac/jac_parse/jacLexer.py +0 -809
  114. jaseci/jac/jac_parse/jacListener.py +0 -853
  115. jaseci/jac/jac_parse/jacParser.py +0 -9192
  116. jaseci/jac/jac_set.py +0 -120
  117. jaseci/jac/jsci_vm/__init__.py +0 -0
  118. jaseci/jac/jsci_vm/disasm.py +0 -94
  119. jaseci/jac/jsci_vm/inst_ptr.py +0 -31
  120. jaseci/jac/jsci_vm/machine.py +0 -188
  121. jaseci/jac/jsci_vm/op_codes.py +0 -82
  122. jaseci/jac/jsci_vm/tests/__init__.py +0 -0
  123. jaseci/jac/jsci_vm/tests/test_codegen.py +0 -31
  124. jaseci/jac/machine/__init__.py +0 -0
  125. jaseci/jac/machine/jac_scope.py +0 -86
  126. jaseci/jac/machine/jac_value.py +0 -227
  127. jaseci/jac/machine/machine_state.py +0 -386
  128. jaseci/jac/tests/__init__.py +0 -0
  129. jaseci/jac/tests/book_code.py +0 -624
  130. jaseci/jac/tests/test_book.py +0 -380
  131. jaseci/jac/tests/test_lang_14.py +0 -49
  132. jaseci/jsorc/__init__.py +0 -7
  133. jaseci/jsorc/jsorc.py +0 -642
  134. jaseci/jsorc/jsorc_settings.py +0 -211
  135. jaseci/jsorc/jsorc_utils.py +0 -298
  136. jaseci/jsorc/live_actions.py +0 -365
  137. jaseci/jsorc/manifests/__init__.py +0 -0
  138. jaseci/jsorc/manifests/database.yaml +0 -109
  139. jaseci/jsorc/manifests/elastic.yaml +0 -6029
  140. jaseci/jsorc/manifests/prometheus.yaml +0 -1383
  141. jaseci/jsorc/manifests/redis.yaml +0 -64
  142. jaseci/jsorc/memory.py +0 -258
  143. jaseci/jsorc/redis.py +0 -140
  144. jaseci/jsorc/remote_actions.py +0 -158
  145. jaseci/jsorc/tests/__init__.py +0 -0
  146. jaseci/jsorc/tests/test_actions.py +0 -542
  147. jaseci/jsorc/tests/test_jsorc.py +0 -112
  148. jaseci/prim/__init__.py +0 -0
  149. jaseci/prim/ability.py +0 -94
  150. jaseci/prim/architype.py +0 -90
  151. jaseci/prim/edge.py +0 -173
  152. jaseci/prim/element.py +0 -233
  153. jaseci/prim/graph.py +0 -27
  154. jaseci/prim/master.py +0 -67
  155. jaseci/prim/node.py +0 -533
  156. jaseci/prim/obj_mixins.py +0 -238
  157. jaseci/prim/sentinel.py +0 -282
  158. jaseci/prim/super_master.py +0 -31
  159. jaseci/prim/walker.py +0 -261
  160. jaseci/svc/__init__.py +0 -0
  161. jaseci/tests/__init__.py +0 -0
  162. jaseci/tests/infer.py +0 -39
  163. jaseci/tests/jac_test_code.py +0 -1293
  164. jaseci/tests/jac_test_progs.py +0 -774
  165. jaseci/tests/test_core.py +0 -153
  166. jaseci/tests/test_jac.py +0 -824
  167. jaseci/tests/test_node.py +0 -89
  168. jaseci/tests/test_progs.py +0 -702
  169. jaseci/tests/test_stack.py +0 -220
  170. jaseci/tests/test_stripe.py +0 -225
  171. jaseci/utils/__init__.py +0 -0
  172. jaseci/utils/actions/__init__.py +0 -0
  173. jaseci/utils/actions/actions_manager.py +0 -254
  174. jaseci/utils/actions/actions_optimizer.py +0 -517
  175. jaseci/utils/actions/actions_state.py +0 -95
  176. jaseci/utils/file_handler.py +0 -171
  177. jaseci/utils/gprof2dot.py +0 -3786
  178. jaseci/utils/id_list.py +0 -169
  179. jaseci/utils/json_handler.py +0 -70
  180. jaseci/utils/log_utils.py +0 -57
  181. jaseci/utils/test_core.py +0 -62
  182. jaseci/utils/utils.py +0 -387
  183. jaseci-1.4.2.6.dist-info/LICENSE +0 -21
  184. jaseci-1.4.2.6.dist-info/METADATA +0 -39
  185. jaseci-1.4.2.6.dist-info/RECORD +0 -185
  186. jaseci-1.4.2.6.dist-info/entry_points.txt +0 -3
  187. jaseci-1.4.2.6.dist-info/top_level.txt +0 -1
jaseci/prim/node.py DELETED
@@ -1,533 +0,0 @@
1
- """
2
- Node class for Jaseci
3
-
4
- Each node has an id, name, timestamp and it's set of edges.
5
- First node in list of 'member_node_ids' is designated root node
6
- """
7
-
8
- from collections import OrderedDict
9
- from jaseci.prim.element import Element
10
- from jaseci.prim.obj_mixins import Anchored
11
- from jaseci.prim.edge import Edge
12
- from jaseci.utils.id_list import IdList
13
- from jaseci.utils.utils import logger
14
-
15
- import uuid
16
-
17
- TO = 0
18
- FROM = 1
19
- BI = 2
20
-
21
-
22
- class Node(Element, Anchored):
23
- """Node class for Jaseci"""
24
-
25
- def __init__(self, dimension=0, **kwargs):
26
- self.edge_ids = IdList(self)
27
- self.fast_edges = {} # {name: [[NODEID, DIR, EDGEID, CONTEXT],...]}
28
- self._fast_edge_ids = IdList(self)
29
- self.parent_node_ids = IdList(self)
30
- self.member_node_ids = IdList(self)
31
- self.dimension = dimension # Nodes are always hdgd 0
32
- Element.__init__(self, **kwargs)
33
- Anchored.__init__(self)
34
-
35
- @property
36
- def smart_edges(self):
37
- obj_list = self.smart_edge_list.obj_list()
38
- for i in obj_list:
39
- if i.is_fast() and i.jid in self.edge_ids:
40
- self.edge_ids.remove_obj(i)
41
- self._fast_edge_ids.remove_obj(i)
42
- self.smart_add_edge(i)
43
- return obj_list
44
-
45
- @property
46
- def smart_edge_list(self):
47
- if not len(self._fast_edge_ids):
48
- self.smart_build_fast_edge_ids()
49
- return self._fast_edge_ids
50
-
51
- def smart_build_fast_edge_ids(self):
52
- self._fast_edge_ids = IdList(self, in_list=self.edge_ids)
53
- for k in self.fast_edges.keys():
54
- for v in self.fast_edges[k]:
55
- link_order = [v[0], self.jid] if v[1] == FROM else [self.jid, v[0]]
56
- if len(v) > 2 and self._h.has_obj(v[2]):
57
- edge = self._h.get_obj(self._m_id, v[2])
58
- if len(v) > 3:
59
- v[3] = edge.context
60
- else:
61
- v.append(edge.context)
62
- else:
63
- edge = Edge(
64
- m_id=self._m_id, h=self._h, kind="edge", name=k, auto_save=False
65
- )
66
- edge.from_node_id = link_order[0]
67
- edge.to_node_id = link_order[1]
68
- edge.bidirected = v[1] == BI
69
- edge.jid = v[2] if len(v) > 2 else uuid.uuid4().urn
70
- edge.context = v[3] if len(v) > 3 else {}
71
- # old `edge.save()` might be confusing
72
- # this line doesn't mean it has to be saved on db
73
- # it only needs to be available on cache (memory, redis)
74
- self._h.commit_obj_to_cache(edge, True)
75
- self._fast_edge_ids.add_obj(edge, bypass=True)
76
-
77
- def smart_add_edge(self, obj):
78
- # make sure fast edges built
79
- if not len(self._fast_edge_ids):
80
- self.smart_build_fast_edge_ids()
81
- # add new edge
82
- self._fast_edge_ids.add_obj(obj)
83
- # then store how needed
84
- if obj.is_fast():
85
- self.smart_edge_to_fast_edge(obj)
86
- else:
87
- self.edge_ids.add_obj(obj)
88
-
89
- def smart_edge_to_fast_edge(self, obj):
90
- if obj.name not in self.fast_edges:
91
- self.fast_edges[obj.name] = []
92
- details = [
93
- obj.opposing_node(self).jid,
94
- BI if obj.is_bidirected() else TO if obj.from_node() == self else FROM,
95
- obj.jid,
96
- obj.context,
97
- ]
98
- self.fast_edges[obj.name].append(details)
99
-
100
- def smart_remove_edge(self, obj):
101
- if obj.is_fast():
102
- pluck = None
103
- for i in self.fast_edges[obj.name]:
104
- other_node_id = obj.to_node_id if i[1] == TO else obj.from_node_id
105
- if i[0] == other_node_id:
106
- if obj.is_bidirected() or not (
107
- i[1] == TO and obj.to_node() == self
108
- ):
109
- pluck = i
110
- break
111
- self.fast_edges[obj.name].remove(pluck)
112
- if not len(self.fast_edges[obj.name]):
113
- del self.fast_edges[obj.name]
114
- elif obj and obj.jid in self.edge_ids:
115
- self.edge_ids.remove_obj(obj)
116
- self.clear_fast_edge_ids()
117
- self.save()
118
-
119
- def clear_fast_edge_ids(self):
120
- self._fast_edge_ids = IdList(self)
121
-
122
- def attach(self, node_obj, edge_set=None, as_outbound=True, as_bidirected=False):
123
- """
124
- Generalized attach function for attaching nodes with edges
125
- """
126
- if edge_set is None:
127
- edge_set = [
128
- Edge(
129
- m_id=self._m_id,
130
- h=self._h,
131
- kind="edge",
132
- name="generic",
133
- )
134
- ]
135
- link_order = [self, node_obj] if as_outbound else [node_obj, self]
136
- for e in edge_set:
137
- if not e.connect(link_order[0], link_order[1]):
138
- # Node not found error logged in set node function
139
- return []
140
- e.set_bidirected(as_bidirected)
141
- # save and return
142
- self.save()
143
- node_obj.save()
144
- return edge_set
145
-
146
- def attach_outbound(self, node_obj, edge_set=None):
147
- """
148
- Creates edge to a node and returns the edge
149
- edge_set is the list of edges to be used to make connections
150
- new edge is created if edge_set is empty
151
- """
152
- return self.attach(node_obj, edge_set, as_outbound=True)
153
-
154
- def attach_inbound(self, node_obj, edge_set=None):
155
- """
156
- Creates edge from a node and returns the edge
157
- edge_set is the list of edges to be used to make connections
158
- new edge is created if edge_set is empty
159
- """
160
- return self.attach(node_obj, edge_set, as_outbound=False)
161
-
162
- def attach_bidirected(self, node_obj, edge_set=None):
163
- """
164
- Creates bidirected edge to node returns the edge
165
- edge_set is the list of edges to be used to make connections
166
- new edge is created if edge_set is empty
167
- """
168
- return self.attach(node_obj, edge_set, as_bidirected=True)
169
-
170
- def detach(
171
- self,
172
- node_obj,
173
- edge_set=None,
174
- as_outbound=True,
175
- as_bidirected=False,
176
- ignore_direction=False,
177
- silent=True,
178
- ):
179
- """
180
- Generalized detach function for detaching nodes with edges
181
- """
182
- if edge_set is None:
183
- edge_set = self.attached_edges(node_obj)
184
- link_order = [self, node_obj] if as_outbound else [node_obj, self]
185
- num_detached = 0
186
- for e in edge_set:
187
- # validate edge connection exists
188
- if not e.connects(
189
- link_order[0], link_order[1], ignore_direction=ignore_direction
190
- ):
191
- if not silent:
192
- logger.warning(
193
- str(
194
- f"{e} does not connect "
195
- f"{link_order[0]} to {link_order[1]}"
196
- )
197
- )
198
- continue
199
- if as_bidirected and not ignore_direction and not e.is_bidirected():
200
- if not silent:
201
- logger.warning(str(f"{e} is not a bidirected edge "))
202
- continue
203
- # destroy edge
204
- num_detached += 1
205
- e.destroy()
206
- return num_detached
207
-
208
- def detach_outbound(self, node_obj, edge_set=None, silent=True):
209
- """
210
- Destroy edges to a node
211
- edge_set is the list of edges to be detached (and distroyed)
212
- all edges are deteached and destroyed if edge_set empty
213
- returns number of detachments
214
- """
215
- return self.detach(node_obj, edge_set, as_outbound=True)
216
-
217
- def detach_inbound(self, node_obj, edge_set=None, silent=True):
218
- """
219
- Destroy edges from a node
220
- edge_set is the list of edges to be detached (and distroyed)
221
- all edges are deteached and destroyed if edge_set empty
222
- returns number of detachments
223
- """
224
- return self.detach(node_obj, edge_set, as_outbound=False)
225
-
226
- def detach_bidirected(self, node_obj, edge_set=None, silent=True):
227
- """
228
- Destroy bidirected edges between nodes
229
- edge_set is the list of edges to be detached (and distroyed)
230
- all edges are deteached and destroyed if edge_set empty
231
- returns number of detachments
232
- """
233
- return self.detach(node_obj, edge_set, as_bidirected=True)
234
-
235
- def detach_edges(self, node_obj, edge_set=None, silent=True):
236
- """
237
- Destroy given edges between nodes without checking orientation
238
- edge_set is the list of edges to be detached (and distroyed)
239
- all edges are deteached and destroyed if edge_set empty
240
- returns number of detachments
241
- """
242
- return self.detach(node_obj, edge_set, ignore_direction=True)
243
-
244
- def destroy_outbound(self, node_obj, edge_set=None):
245
- """
246
- Destroys attached node and all relevant edges
247
- Node and all edges are destroyed if edge_set empty
248
- """
249
- if edge_set is None:
250
- edge_set = self.outbound_edges(node_obj)
251
- if self.detach_outbound(node_obj, edge_set):
252
- node_obj.destroy()
253
-
254
- def destroy_inbound(self, node_obj, edge_set=None):
255
- """
256
- Destroys attached node and all relevant edges
257
- Node and all edges are destroyed if edge_set empty
258
- """
259
- if edge_set is None:
260
- edge_set = self.inbound_edges(node_obj)
261
- if self.detach_inbound(node_obj, edge_set):
262
- node_obj.destroy()
263
-
264
- def destroy_bidirected(self, node_obj, edge_set=None):
265
- """
266
- Destroys attached node and all relevant edges
267
- Node and all edges are destroyed if edge_set empty
268
- """
269
- if edge_set is None:
270
- edge_set = self.bidirected_edges(node_obj)
271
- if self.detach_bidirected(node_obj, edge_set):
272
- node_obj.destroy()
273
-
274
- def is_attached_out(self, node_obj, edge_set=None):
275
- """
276
- Tests whether edges attach to a node
277
- """
278
- out_set = self.outbound_edges(node_obj)
279
- if edge_set is None:
280
- return len(out_set)
281
- else:
282
- for e in edge_set:
283
- if e not in out_set:
284
- return False
285
- return True
286
-
287
- def is_attached_in(self, node_obj, edge_set=None):
288
- """
289
- Tests whether edges attach from a node
290
- """
291
- in_set = self.inbound_edges(node_obj)
292
- if edge_set is None:
293
- return len(in_set)
294
- else:
295
- for e in edge_set:
296
- if e not in in_set:
297
- return False
298
- return True
299
-
300
- def is_attached_bi(self, node_obj, edge_set=None):
301
- """
302
- Tests whether edges attach either to or from a node
303
- """
304
- bi_set = self.bidirected_edges(node_obj)
305
- if edge_set is None:
306
- return len(bi_set)
307
- else:
308
- for e in edge_set:
309
- if e not in bi_set:
310
- return False
311
- return True
312
-
313
- def outbound_edges(self, node_obj=None):
314
- """Returns list of all edges out of node"""
315
- edge_set = []
316
- for e in self.smart_edges:
317
- if not e.is_bidirected() and e.connects(self, node_obj):
318
- edge_set.append(e)
319
- return edge_set
320
-
321
- def inbound_edges(self, node_obj=None):
322
- """Returns list of all edges in to node"""
323
- edge_set = []
324
- for e in self.smart_edges:
325
- if not e.is_bidirected() and e.connects(node_obj, self):
326
- edge_set.append(e)
327
- return edge_set
328
-
329
- def bidirected_edges(self, node_obj=None):
330
- """Returns list of all edges between nodes"""
331
- edge_set = []
332
- for e in self.smart_edges:
333
- if e.is_bidirected() and e.connects(self, node_obj):
334
- edge_set.append(e)
335
- return edge_set
336
-
337
- def attached_edges(self, node_obj=None, silent=False):
338
- """
339
- Returns the edges connecting self to or from a node
340
-
341
- silent is used to indicate whther the edge is intened to be used.
342
- (effectively turns off error checking when false)
343
- """
344
- edge_set = (
345
- self.outbound_edges(node_obj)
346
- + self.inbound_edges(node_obj)
347
- + self.bidirected_edges(node_obj)
348
- )
349
- if not silent and edge_set is None:
350
- logger.error(str(f"No edges found between {self} and {node_obj}"))
351
- return edge_set
352
-
353
- def outbound_nodes(self, edge_set=None):
354
- """Returns list of all nodes connected by edges out"""
355
- if edge_set is None:
356
- edge_set = self.smart_edges
357
- ret_list = []
358
- for e in edge_set:
359
- if not e.is_bidirected() and e.connects(source=self):
360
- ret_list.append(e.to_node())
361
- return ret_list
362
-
363
- def inbound_nodes(self, edge_set=None):
364
- """Returns list of all nodes connected by edges in"""
365
- if edge_set is None:
366
- edge_set = self.smart_edges
367
- ret_list = []
368
- for e in edge_set:
369
- if not e.is_bidirected() and e.connects(target=self):
370
- ret_list.append(e.from_node())
371
- return ret_list
372
-
373
- def bidirected_nodes(self, edge_set=None):
374
- """Returns list of all nodes connected by edges"""
375
- if edge_set is None:
376
- edge_set = self.smart_edges
377
- ret_list = []
378
- for e in edge_set:
379
- if e.is_bidirected():
380
- ret_list.append(e.opposing_node(self))
381
- return ret_list
382
-
383
- def attached_nodes(self):
384
- """Returns list of all nodes connected"""
385
- edge_set = self.smart_edges
386
- ret_list = []
387
- for e in edge_set:
388
- ret_list.append(e.opposing_node(self))
389
- return ret_list
390
-
391
- def dimension_matches(self, node_obj, silent=True):
392
- """Test if dimension matches another node"""
393
- matches = self.dimension == node_obj.dimension
394
- if not matches and not silent:
395
- logger.error(
396
- str(
397
- "'{}' cant connect to '{}' - dim mismatch {}->{}".format(
398
- self, node_obj, self.dimension, node_obj.dimension
399
- )
400
- )
401
- )
402
- return matches
403
-
404
- def make_member_of(self, node_obj):
405
- """
406
- Adds node to higher dimension node and does relevant checks
407
- """
408
- # check if valid inclusion
409
- if node_obj.dimension != self.dimension + 1:
410
- logger.error(
411
- str(
412
- "'{}' cant be member to '{}' - dimension mismatch {}->{}".format(
413
- self, node_obj, self.dimension, node_obj.dimension
414
- )
415
- )
416
- )
417
- # adds self to hdgd and hdgd to list of owners
418
- else:
419
- node_obj.member_node_ids.add_obj(self)
420
- self.parent_node_ids.add_obj(node_obj)
421
-
422
- def make_owner_of(self, node_obj):
423
- """
424
- Adds node to lower dimension node and does relevant checks
425
- """
426
- node_obj.make_member_of(self)
427
-
428
- def leave_memebership_of(self, node_obj):
429
- """Remove node from higher dimension node"""
430
- node_obj.member_node_ids.remove_obj(self)
431
- self.parent_node_ids.remove_obj(node_obj)
432
-
433
- def disown(self, node_obj):
434
- """Remove node from higher dimension node"""
435
- node_obj.leave_membership_of(self)
436
-
437
- def destroy(self):
438
- """
439
- Destroys self from memory and persistent storage
440
- """
441
- for i in self.smart_edges:
442
- i.destroy()
443
- super().destroy()
444
-
445
- def dot_str(self, node_map=None, detailed=False):
446
- """
447
- DOT representation
448
- """
449
-
450
- def handle_str(str):
451
- return str[:32].replace('"', '\\"')
452
-
453
- if node_map is None:
454
- nid = f"{uuid.UUID(self.jid).hex}"
455
- else:
456
- nid = f"{node_map.index(self.jid)}"
457
-
458
- dstr = f'"n{nid}" [ '
459
-
460
- if detailed:
461
- dstr += f'id="{uuid.UUID(self.jid).hex}", '
462
-
463
- dstr += f'label="n{nid}:{self.name}" '
464
-
465
- node_dict = self.context
466
- for i in self.private_values():
467
- node_dict.pop(i)
468
-
469
- if node_dict and detailed:
470
- for k, v in node_dict.items():
471
- if not isinstance(v, str) or v == "":
472
- continue
473
- dstr += f', {k}="{handle_str(v)}"'
474
-
475
- dstr += " ]"
476
-
477
- return dstr + "\n"
478
-
479
- def get_all_architypes(self, depth: int = 0):
480
- """
481
- Returns all reachable architypes
482
- """
483
-
484
- childs = {self.jid: self}
485
-
486
- edges = OrderedDict()
487
- nodes = OrderedDict(childs)
488
-
489
- depth -= 1
490
-
491
- while len(childs) and depth != 0:
492
- new_childs = OrderedDict()
493
-
494
- for node in childs.values():
495
- for edge in node.attached_edges():
496
- if not (edge.jid in edges):
497
- n_node = False
498
- to_node = edge.to_node()
499
-
500
- if to_node == node:
501
- n_node = edge.from_node()
502
- else:
503
- n_node = to_node
504
-
505
- if not (n_node.jid in nodes):
506
- edges.update({edge.jid: edge})
507
- new_childs.update({n_node.jid: n_node})
508
- else:
509
- edges.update({edge.jid: edge})
510
-
511
- childs = new_childs
512
- nodes.update(childs)
513
- depth -= 1
514
-
515
- return nodes, edges
516
-
517
- def traversing_dot_str(self, detailed=False, depth: int = 0):
518
- """
519
- DOT representation for graph.
520
- NOTE: This is different from the dot_str method for node intentionally
521
- because graph inherits node.
522
- """
523
- nodes, edges = self.get_all_architypes(depth)
524
-
525
- # Construct the graph string
526
- dstr = ""
527
- dstr += f"strict digraph {self.name} {{\n"
528
- for n in nodes.values():
529
- dstr += f" {n.dot_str(list(nodes.keys()), detailed)}"
530
- for e in edges.values():
531
- dstr += f" {e.dot_str(list(nodes.keys()), list(edges.keys()), detailed)}"
532
- dstr += "}"
533
- return dstr