infrahub-server 1.6.2__py3-none-any.whl → 1.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. infrahub/actions/tasks.py +4 -2
  2. infrahub/api/exceptions.py +2 -2
  3. infrahub/api/schema.py +3 -1
  4. infrahub/artifacts/tasks.py +1 -0
  5. infrahub/auth.py +2 -2
  6. infrahub/cli/db.py +54 -28
  7. infrahub/computed_attribute/gather.py +3 -4
  8. infrahub/computed_attribute/tasks.py +23 -6
  9. infrahub/config.py +8 -0
  10. infrahub/constants/enums.py +12 -0
  11. infrahub/core/account.py +12 -9
  12. infrahub/core/attribute.py +106 -108
  13. infrahub/core/branch/models.py +44 -71
  14. infrahub/core/branch/tasks.py +5 -3
  15. infrahub/core/changelog/diff.py +1 -20
  16. infrahub/core/changelog/models.py +0 -7
  17. infrahub/core/constants/__init__.py +17 -0
  18. infrahub/core/constants/database.py +0 -1
  19. infrahub/core/constants/schema.py +0 -1
  20. infrahub/core/convert_object_type/repository_conversion.py +3 -4
  21. infrahub/core/diff/branch_differ.py +1 -1
  22. infrahub/core/diff/conflict_transferer.py +1 -1
  23. infrahub/core/diff/data_check_synchronizer.py +4 -3
  24. infrahub/core/diff/enricher/cardinality_one.py +2 -2
  25. infrahub/core/diff/enricher/hierarchy.py +1 -1
  26. infrahub/core/diff/enricher/labels.py +1 -1
  27. infrahub/core/diff/merger/merger.py +28 -2
  28. infrahub/core/diff/merger/serializer.py +3 -10
  29. infrahub/core/diff/model/diff.py +1 -1
  30. infrahub/core/diff/query/merge.py +376 -135
  31. infrahub/core/diff/repository/repository.py +3 -1
  32. infrahub/core/graph/__init__.py +1 -1
  33. infrahub/core/graph/constraints.py +3 -3
  34. infrahub/core/graph/schema.py +2 -12
  35. infrahub/core/ipam/reconciler.py +8 -6
  36. infrahub/core/ipam/utilization.py +8 -15
  37. infrahub/core/manager.py +133 -152
  38. infrahub/core/merge.py +1 -1
  39. infrahub/core/metadata/__init__.py +0 -0
  40. infrahub/core/metadata/interface.py +37 -0
  41. infrahub/core/metadata/model.py +31 -0
  42. infrahub/core/metadata/query/__init__.py +0 -0
  43. infrahub/core/metadata/query/node_metadata.py +301 -0
  44. infrahub/core/migrations/graph/__init__.py +4 -0
  45. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -12
  46. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -12
  47. infrahub/core/migrations/graph/m017_add_core_profile.py +5 -2
  48. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -1
  49. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +0 -10
  50. infrahub/core/migrations/graph/m020_duplicate_edges.py +0 -8
  51. infrahub/core/migrations/graph/m025_uniqueness_nulls.py +2 -1
  52. infrahub/core/migrations/graph/m026_0000_prefix_fix.py +2 -1
  53. infrahub/core/migrations/graph/m029_duplicates_cleanup.py +0 -1
  54. infrahub/core/migrations/graph/m031_check_number_attributes.py +2 -2
  55. infrahub/core/migrations/graph/m038_redo_0000_prefix_fix.py +2 -1
  56. infrahub/core/migrations/graph/m041_deleted_dup_edges.py +1 -1
  57. infrahub/core/migrations/graph/m049_remove_is_visible_relationship.py +53 -0
  58. infrahub/core/migrations/graph/m050_backfill_vertex_metadata.py +168 -0
  59. infrahub/core/migrations/query/__init__.py +2 -2
  60. infrahub/core/migrations/query/attribute_add.py +17 -6
  61. infrahub/core/migrations/query/attribute_remove.py +19 -5
  62. infrahub/core/migrations/query/attribute_rename.py +21 -5
  63. infrahub/core/migrations/query/node_duplicate.py +19 -4
  64. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  65. infrahub/core/migrations/schema/attribute_kind_update.py +26 -6
  66. infrahub/core/migrations/schema/attribute_name_update.py +1 -1
  67. infrahub/core/migrations/schema/attribute_supports_profile.py +5 -3
  68. infrahub/core/migrations/schema/models.py +3 -0
  69. infrahub/core/migrations/schema/node_attribute_add.py +5 -2
  70. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  71. infrahub/core/migrations/schema/node_kind_update.py +1 -1
  72. infrahub/core/migrations/schema/node_remove.py +24 -2
  73. infrahub/core/migrations/schema/tasks.py +4 -1
  74. infrahub/core/migrations/shared.py +13 -6
  75. infrahub/core/models.py +6 -6
  76. infrahub/core/node/__init__.py +157 -58
  77. infrahub/core/node/base.py +9 -5
  78. infrahub/core/node/create.py +7 -3
  79. infrahub/core/node/delete_validator.py +1 -1
  80. infrahub/core/node/standard.py +100 -14
  81. infrahub/core/order.py +30 -0
  82. infrahub/core/property.py +0 -1
  83. infrahub/core/protocols.py +1 -0
  84. infrahub/core/protocols_base.py +10 -2
  85. infrahub/core/query/__init__.py +11 -6
  86. infrahub/core/query/attribute.py +164 -49
  87. infrahub/core/query/branch.py +58 -70
  88. infrahub/core/query/delete.py +1 -1
  89. infrahub/core/query/diff.py +7 -7
  90. infrahub/core/query/ipam.py +104 -43
  91. infrahub/core/query/node.py +1072 -281
  92. infrahub/core/query/relationship.py +531 -325
  93. infrahub/core/query/resource_manager.py +107 -18
  94. infrahub/core/query/standard_node.py +25 -5
  95. infrahub/core/query/utils.py +2 -4
  96. infrahub/core/relationship/constraints/count.py +1 -1
  97. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  98. infrahub/core/relationship/constraints/peer_parent.py +1 -1
  99. infrahub/core/relationship/constraints/peer_relatives.py +1 -1
  100. infrahub/core/relationship/constraints/profiles_kind.py +1 -1
  101. infrahub/core/relationship/constraints/profiles_removal.py +168 -0
  102. infrahub/core/relationship/model.py +293 -139
  103. infrahub/core/schema/attribute_parameters.py +28 -1
  104. infrahub/core/schema/attribute_schema.py +11 -17
  105. infrahub/core/schema/basenode_schema.py +3 -0
  106. infrahub/core/schema/definitions/core/__init__.py +8 -2
  107. infrahub/core/schema/definitions/core/account.py +10 -10
  108. infrahub/core/schema/definitions/core/artifact.py +14 -8
  109. infrahub/core/schema/definitions/core/check.py +10 -4
  110. infrahub/core/schema/definitions/core/generator.py +26 -6
  111. infrahub/core/schema/definitions/core/graphql_query.py +1 -1
  112. infrahub/core/schema/definitions/core/group.py +9 -2
  113. infrahub/core/schema/definitions/core/ipam.py +80 -10
  114. infrahub/core/schema/definitions/core/menu.py +41 -7
  115. infrahub/core/schema/definitions/core/permission.py +16 -2
  116. infrahub/core/schema/definitions/core/profile.py +16 -2
  117. infrahub/core/schema/definitions/core/propose_change.py +24 -4
  118. infrahub/core/schema/definitions/core/propose_change_comment.py +23 -11
  119. infrahub/core/schema/definitions/core/propose_change_validator.py +50 -21
  120. infrahub/core/schema/definitions/core/repository.py +10 -0
  121. infrahub/core/schema/definitions/core/resource_pool.py +8 -1
  122. infrahub/core/schema/definitions/core/template.py +19 -2
  123. infrahub/core/schema/definitions/core/transform.py +11 -5
  124. infrahub/core/schema/definitions/core/webhook.py +27 -9
  125. infrahub/core/schema/manager.py +63 -43
  126. infrahub/core/schema/relationship_schema.py +6 -2
  127. infrahub/core/schema/schema_branch.py +115 -11
  128. infrahub/core/task/task.py +4 -2
  129. infrahub/core/utils.py +3 -25
  130. infrahub/core/validators/aggregated_checker.py +1 -1
  131. infrahub/core/validators/attribute/choices.py +1 -1
  132. infrahub/core/validators/attribute/enum.py +1 -1
  133. infrahub/core/validators/attribute/kind.py +6 -3
  134. infrahub/core/validators/attribute/length.py +1 -1
  135. infrahub/core/validators/attribute/min_max.py +1 -1
  136. infrahub/core/validators/attribute/number_pool.py +1 -1
  137. infrahub/core/validators/attribute/optional.py +1 -1
  138. infrahub/core/validators/attribute/regex.py +1 -1
  139. infrahub/core/validators/determiner.py +3 -3
  140. infrahub/core/validators/node/attribute.py +1 -1
  141. infrahub/core/validators/node/relationship.py +1 -1
  142. infrahub/core/validators/relationship/peer.py +1 -1
  143. infrahub/database/__init__.py +4 -4
  144. infrahub/dependencies/builder/constraint/grouped/node_runner.py +2 -0
  145. infrahub/dependencies/builder/constraint/relationship_manager/profiles_removal.py +8 -0
  146. infrahub/dependencies/registry.py +2 -0
  147. infrahub/display_labels/tasks.py +12 -3
  148. infrahub/git/integrator.py +18 -18
  149. infrahub/git/tasks.py +1 -1
  150. infrahub/git/utils.py +1 -1
  151. infrahub/graphql/app.py +2 -2
  152. infrahub/graphql/constants.py +3 -0
  153. infrahub/graphql/context.py +1 -1
  154. infrahub/graphql/field_extractor.py +1 -1
  155. infrahub/graphql/initialization.py +11 -0
  156. infrahub/graphql/loaders/account.py +134 -0
  157. infrahub/graphql/loaders/node.py +5 -12
  158. infrahub/graphql/loaders/peers.py +5 -7
  159. infrahub/graphql/manager.py +175 -21
  160. infrahub/graphql/metadata.py +91 -0
  161. infrahub/graphql/mutations/account.py +6 -6
  162. infrahub/graphql/mutations/attribute.py +0 -2
  163. infrahub/graphql/mutations/branch.py +9 -5
  164. infrahub/graphql/mutations/computed_attribute.py +1 -1
  165. infrahub/graphql/mutations/display_label.py +1 -1
  166. infrahub/graphql/mutations/hfid.py +1 -1
  167. infrahub/graphql/mutations/ipam.py +4 -6
  168. infrahub/graphql/mutations/main.py +9 -4
  169. infrahub/graphql/mutations/profile.py +16 -22
  170. infrahub/graphql/mutations/proposed_change.py +4 -4
  171. infrahub/graphql/mutations/relationship.py +40 -10
  172. infrahub/graphql/mutations/repository.py +14 -12
  173. infrahub/graphql/mutations/schema.py +2 -2
  174. infrahub/graphql/order.py +14 -0
  175. infrahub/graphql/queries/branch.py +62 -6
  176. infrahub/graphql/queries/diff/tree.py +5 -5
  177. infrahub/graphql/queries/resource_manager.py +25 -24
  178. infrahub/graphql/resolvers/account_metadata.py +84 -0
  179. infrahub/graphql/resolvers/ipam.py +6 -8
  180. infrahub/graphql/resolvers/many_relationship.py +77 -35
  181. infrahub/graphql/resolvers/resolver.py +59 -14
  182. infrahub/graphql/resolvers/single_relationship.py +87 -23
  183. infrahub/graphql/subscription/graphql_query.py +2 -0
  184. infrahub/graphql/types/__init__.py +0 -1
  185. infrahub/graphql/types/attribute.py +10 -5
  186. infrahub/graphql/types/branch.py +40 -53
  187. infrahub/graphql/types/enums.py +3 -0
  188. infrahub/graphql/types/metadata.py +28 -0
  189. infrahub/graphql/types/node.py +22 -2
  190. infrahub/graphql/types/relationship.py +10 -2
  191. infrahub/graphql/types/standard_node.py +12 -7
  192. infrahub/hfid/tasks.py +12 -3
  193. infrahub/lock.py +7 -0
  194. infrahub/menu/repository.py +1 -1
  195. infrahub/patch/queries/base.py +1 -1
  196. infrahub/pools/number.py +1 -8
  197. infrahub/profiles/gather.py +56 -0
  198. infrahub/profiles/mandatory_fields_checker.py +116 -0
  199. infrahub/profiles/models.py +66 -0
  200. infrahub/profiles/node_applier.py +154 -13
  201. infrahub/profiles/queries/get_profile_data.py +143 -31
  202. infrahub/profiles/tasks.py +79 -27
  203. infrahub/profiles/triggers.py +22 -0
  204. infrahub/proposed_change/action_checker.py +1 -1
  205. infrahub/proposed_change/tasks.py +4 -1
  206. infrahub/services/__init__.py +1 -1
  207. infrahub/services/adapters/cache/nats.py +1 -1
  208. infrahub/services/adapters/cache/redis.py +7 -0
  209. infrahub/tasks/artifact.py +1 -0
  210. infrahub/transformations/tasks.py +2 -2
  211. infrahub/trigger/catalogue.py +2 -0
  212. infrahub/trigger/models.py +1 -0
  213. infrahub/trigger/setup.py +3 -3
  214. infrahub/trigger/tasks.py +3 -0
  215. infrahub/validators/tasks.py +1 -0
  216. infrahub/webhook/gather.py +1 -1
  217. infrahub/webhook/models.py +1 -1
  218. infrahub/webhook/tasks.py +23 -7
  219. infrahub/workers/dependencies.py +9 -3
  220. infrahub/workers/infrahub_async.py +13 -4
  221. infrahub/workflows/catalogue.py +19 -0
  222. infrahub_sdk/analyzer.py +2 -2
  223. infrahub_sdk/branch.py +12 -39
  224. infrahub_sdk/checks.py +4 -4
  225. infrahub_sdk/client.py +36 -0
  226. infrahub_sdk/ctl/cli_commands.py +2 -1
  227. infrahub_sdk/ctl/graphql.py +15 -4
  228. infrahub_sdk/ctl/utils.py +2 -2
  229. infrahub_sdk/enums.py +6 -0
  230. infrahub_sdk/graphql/renderers.py +21 -0
  231. infrahub_sdk/graphql/utils.py +85 -0
  232. infrahub_sdk/node/attribute.py +12 -2
  233. infrahub_sdk/node/constants.py +12 -0
  234. infrahub_sdk/node/metadata.py +69 -0
  235. infrahub_sdk/node/node.py +65 -14
  236. infrahub_sdk/node/property.py +3 -0
  237. infrahub_sdk/node/related_node.py +37 -5
  238. infrahub_sdk/node/relationship.py +18 -1
  239. infrahub_sdk/operation.py +2 -2
  240. infrahub_sdk/schema/repository.py +1 -2
  241. infrahub_sdk/transforms.py +2 -2
  242. infrahub_sdk/types.py +18 -2
  243. {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/METADATA +17 -16
  244. {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/RECORD +252 -231
  245. infrahub_testcontainers/container.py +3 -3
  246. infrahub_testcontainers/docker-compose-cluster.test.yml +7 -7
  247. infrahub_testcontainers/docker-compose.test.yml +13 -5
  248. infrahub_testcontainers/models.py +3 -3
  249. infrahub_testcontainers/performance_test.py +1 -1
  250. infrahub/graphql/models.py +0 -6
  251. {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/WHEEL +0 -0
  252. {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/entry_points.txt +0 -0
  253. {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -49,7 +49,9 @@ log = get_logger()
49
49
 
50
50
 
51
51
  class DiffRepository:
52
- def __init__(self, db: InfrahubDatabase, deserializer: EnrichedDiffDeserializer, max_save_batch_size: int = 1000):
52
+ def __init__(
53
+ self, db: InfrahubDatabase, deserializer: EnrichedDiffDeserializer, max_save_batch_size: int = 1000
54
+ ) -> None:
53
55
  self.db = db
54
56
  self.deserializer = deserializer
55
57
  self.max_save_batch_size = max_save_batch_size
@@ -1 +1 @@
1
- GRAPH_VERSION = 48
1
+ GRAPH_VERSION = 50
@@ -165,7 +165,7 @@ class ConstraintManagerBase:
165
165
  constraint_node_class: Optional[type[ConstraintItem]] = ConstraintItem
166
166
  constraint_rel_class: Optional[type[ConstraintItem]] = ConstraintItem
167
167
 
168
- def __init__(self, db: InfrahubDatabase):
168
+ def __init__(self, db: InfrahubDatabase) -> None:
169
169
  self.db = db
170
170
 
171
171
  self.nodes: list[ConstraintItem] = []
@@ -176,12 +176,12 @@ class ConstraintManagerBase:
176
176
  return self.nodes + self.rels
177
177
 
178
178
  @classmethod
179
- def from_graph_schema(cls, db: InfrahubDatabase, schema: dict[str, dict[str, BaseModel]]) -> Self:
179
+ def from_graph_schema(cls, db: InfrahubDatabase, schema: dict[str, dict[str, type[BaseModel]]]) -> Self:
180
180
  manager = cls(db=db)
181
181
 
182
182
  # Process the nodes first
183
183
  for schema_item in schema["nodes"].values():
184
- properties_class: BaseModel = schema_item.model_fields["properties"].annotation # type: ignore[assignment]
184
+ properties_class: type[BaseModel] = schema_item.model_fields["properties"].annotation # type: ignore[assignment]
185
185
  default_label = str(schema_item.model_fields["default_label"].default)
186
186
  for field_name, field in properties_class.model_fields.items():
187
187
  clean_field_name = field.alias or field_name
@@ -95,9 +95,6 @@ class GraphRelationshipRelationships(BaseModel):
95
95
  HAS_OWNER: GraphRelationship = Field(
96
96
  GraphRelationship(peer="Node", direction=GraphRelDirection.OUTBOUND), description=""
97
97
  )
98
- IS_VISIBLE: GraphRelationship = Field(
99
- GraphRelationship(peer="Boolean", direction=GraphRelDirection.OUTBOUND), description=""
100
- )
101
98
  IS_PROTECTED: GraphRelationship = Field(
102
99
  GraphRelationship(peer="Boolean", direction=GraphRelDirection.OUTBOUND), description=""
103
100
  )
@@ -133,9 +130,6 @@ class GraphAttributeRelationships(BaseModel):
133
130
  HAS_OWNER: GraphRelationship = Field(
134
131
  GraphRelationship(peer="Node", direction=GraphRelDirection.OUTBOUND), description=""
135
132
  )
136
- IS_VISIBLE: GraphRelationship = Field(
137
- GraphRelationship(peer="Boolean", direction=GraphRelDirection.OUTBOUND), description=""
138
- )
139
133
  IS_PROTECTED: GraphRelationship = Field(
140
134
  GraphRelationship(peer="Boolean", direction=GraphRelDirection.OUTBOUND), description=""
141
135
  )
@@ -208,9 +202,6 @@ class GraphBooleanProperties(BaseModel):
208
202
 
209
203
 
210
204
  class GraphBooleanRelationships(BaseModel):
211
- IS_VISIBLE: GraphRelationship = Field(
212
- GraphRelationship(peer="Attribute|Relationship", direction=GraphRelDirection.INBOUND), description=""
213
- )
214
205
  IS_PROTECTED: GraphRelationship = Field(
215
206
  GraphRelationship(peer="Attribute|Relationship", direction=GraphRelDirection.INBOUND), description=""
216
207
  )
@@ -243,7 +234,7 @@ class GraphRelationshipDefault(BaseModel):
243
234
  hierarchy: Optional[str] = Field(None, description="Name of the hierarchy this relationship is part of")
244
235
 
245
236
 
246
- def get_graph_schema() -> dict[str, dict[str, Any]]:
237
+ def get_graph_schema() -> dict[str, dict[str, type[Any]]]:
247
238
  """Generate the graph schema dictionary containing nodes and relationships."""
248
239
  graph_node_list: list[type[GraphVertex]] = [
249
240
  GraphNodeNode,
@@ -265,10 +256,9 @@ def get_graph_schema() -> dict[str, dict[str, Any]]:
265
256
  "IS_RELATED": GraphRelationshipDefault,
266
257
  "HAS_SOURCE": GraphRelationshipDefault,
267
258
  "HAS_OWNER": GraphRelationshipDefault,
268
- "IS_VISIBLE": GraphRelationshipDefault,
269
259
  "IS_PROTECTED": GraphRelationshipDefault,
270
260
  },
271
261
  }
272
262
 
273
263
 
274
- GRAPH_SCHEMA: dict[str, dict[str, Any]] = get_graph_schema()
264
+ GRAPH_SCHEMA: dict[str, dict[str, type[Any]]] = get_graph_schema()
@@ -101,16 +101,18 @@ class IpamReconciler:
101
101
  )
102
102
  await query.execute(db=self.db)
103
103
 
104
- ip_node_uuid = query.get_ip_node_uuid()
105
- if not ip_node_uuid:
104
+ data = query.get_data()
105
+ if not data or not data.ip_node_uuid:
106
106
  node_type = InfrahubKind.IPPREFIX
107
107
  if isinstance(ip_value, ipaddress.IPv6Interface | ipaddress.IPv4Interface):
108
108
  node_type = InfrahubKind.IPADDRESS
109
109
  raise NodeNotFoundError(node_type=node_type, identifier=str(ip_value))
110
- current_parent_uuid = query.get_current_parent_uuid()
111
- calculated_parent_uuid = query.get_calculated_parent_uuid()
112
- current_children_uuids = set(query.get_current_children_uuids())
113
- calculated_children_uuids = set(query.get_calculated_children_uuids())
110
+
111
+ ip_node_uuid = data.ip_node_uuid
112
+ current_parent_uuid = data.current_parent_uuid
113
+ calculated_parent_uuid = data.calculated_parent_uuid
114
+ current_children_uuids = set(data.current_children_uuids)
115
+ calculated_children_uuids = set(data.calculated_children_uuids)
114
116
 
115
117
  all_uuids: set[str] = set()
116
118
  all_uuids = (all_uuids | {ip_node_uuid}) if ip_node_uuid else all_uuids
@@ -40,25 +40,18 @@ class PrefixUtilizationGetter:
40
40
  )
41
41
  await query.execute(db=self.db)
42
42
 
43
- for result in query.get_results():
44
- prefix_node = result.get_node("pfx")
45
- prefix_id = str(prefix_node.get("uuid"))
46
- branch_name = str(result.get("branch"))
47
- child_node = result.get_node("child")
48
- if InfrahubKind.IPADDRESS in child_node.labels:
43
+ for item in query.get_data():
44
+ if InfrahubKind.IPADDRESS in item.child_labels:
49
45
  child_type = PrefixMemberType.ADDRESS
50
46
  else:
51
47
  child_type = PrefixMemberType.PREFIX
52
- child_value_node = result.get_node("av")
53
- child_prefixlen = child_value_node.get("prefixlen")
54
- child_ip_value = child_value_node.get("value")
55
48
 
56
- if prefix_id not in self._results_by_prefix_id:
57
- self._results_by_prefix_id[prefix_id] = {}
58
- if branch_name not in self._results_by_prefix_id[prefix_id]:
59
- self._results_by_prefix_id[prefix_id][branch_name] = []
60
- self._results_by_prefix_id[prefix_id][branch_name].append(
61
- PrefixChildDetails(child_type=child_type, prefixlen=child_prefixlen, ip_value=child_ip_value)
49
+ if item.prefix_uuid not in self._results_by_prefix_id:
50
+ self._results_by_prefix_id[item.prefix_uuid] = {}
51
+ if item.branch not in self._results_by_prefix_id[item.prefix_uuid]:
52
+ self._results_by_prefix_id[item.prefix_uuid][item.branch] = []
53
+ self._results_by_prefix_id[item.prefix_uuid][item.branch].append(
54
+ PrefixChildDetails(child_type=child_type, prefixlen=item.prefixlen, ip_value=item.ip_value)
62
55
  )
63
56
 
64
57
  async def get_children(