infrahub-server 1.1.6__py3-none-any.whl → 1.2.0rc0__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 (346) hide show
  1. infrahub/api/artifact.py +16 -4
  2. infrahub/api/dependencies.py +8 -0
  3. infrahub/api/oauth2.py +0 -1
  4. infrahub/api/oidc.py +0 -1
  5. infrahub/api/query.py +18 -7
  6. infrahub/api/schema.py +32 -6
  7. infrahub/api/transformation.py +12 -5
  8. infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +2 -4
  9. infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +26 -25
  10. infrahub/cli/__init__.py +0 -2
  11. infrahub/cli/db.py +6 -7
  12. infrahub/cli/events.py +8 -3
  13. infrahub/cli/git_agent.py +9 -7
  14. infrahub/cli/tasks.py +4 -6
  15. infrahub/computed_attribute/tasks.py +63 -17
  16. infrahub/computed_attribute/triggers.py +90 -0
  17. infrahub/config.py +1 -1
  18. infrahub/context.py +39 -0
  19. infrahub/core/account.py +5 -8
  20. infrahub/core/attribute.py +53 -21
  21. infrahub/core/branch/models.py +4 -4
  22. infrahub/core/branch/tasks.py +89 -130
  23. infrahub/core/changelog/__init__.py +0 -0
  24. infrahub/core/changelog/diff.py +232 -0
  25. infrahub/core/changelog/models.py +488 -0
  26. infrahub/core/constants/__init__.py +19 -2
  27. infrahub/core/constants/infrahubkind.py +1 -0
  28. infrahub/core/diff/combiner.py +12 -8
  29. infrahub/core/diff/coordinator.py +49 -70
  30. infrahub/core/diff/data_check_synchronizer.py +86 -7
  31. infrahub/core/diff/enricher/aggregated.py +3 -3
  32. infrahub/core/diff/enricher/cardinality_one.py +2 -7
  33. infrahub/core/diff/enricher/hierarchy.py +5 -3
  34. infrahub/core/diff/enricher/labels.py +14 -4
  35. infrahub/core/diff/enricher/path_identifier.py +3 -9
  36. infrahub/core/diff/enricher/summary_counts.py +3 -1
  37. infrahub/core/diff/merger/merger.py +8 -4
  38. infrahub/core/diff/model/path.py +47 -29
  39. infrahub/core/diff/query/all_conflicts.py +6 -3
  40. infrahub/core/diff/query/artifact.py +1 -1
  41. infrahub/core/diff/query/delete_query.py +1 -1
  42. infrahub/core/diff/query/diff_get.py +3 -2
  43. infrahub/core/diff/query/diff_summary.py +1 -1
  44. infrahub/core/diff/query/field_specifiers.py +3 -1
  45. infrahub/core/diff/query/field_summary.py +3 -2
  46. infrahub/core/diff/query/filters.py +12 -1
  47. infrahub/core/diff/query/get_conflict_query.py +1 -1
  48. infrahub/core/diff/query/has_conflicts_query.py +6 -3
  49. infrahub/core/diff/query/merge.py +3 -3
  50. infrahub/core/diff/query/{drop_tracking_id.py → merge_tracking_id.py} +4 -4
  51. infrahub/core/diff/query/roots_metadata.py +9 -2
  52. infrahub/core/diff/query/save.py +151 -66
  53. infrahub/core/diff/query/summary_counts_enricher.py +220 -0
  54. infrahub/core/diff/query/time_range_query.py +3 -2
  55. infrahub/core/diff/query/update_conflict_query.py +1 -1
  56. infrahub/core/diff/query_parser.py +49 -24
  57. infrahub/core/diff/repository/deserializer.py +24 -25
  58. infrahub/core/diff/repository/repository.py +76 -20
  59. infrahub/core/diff/tasks.py +9 -8
  60. infrahub/core/enums.py +1 -1
  61. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  62. infrahub/core/ipam/reconciler.py +1 -1
  63. infrahub/core/ipam/tasks.py +2 -3
  64. infrahub/core/manager.py +18 -13
  65. infrahub/core/merge.py +5 -2
  66. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  67. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  68. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  69. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  70. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  71. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  72. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  73. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  74. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  75. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  76. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  77. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  78. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  79. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  80. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  81. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  82. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
  83. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
  84. infrahub/core/migrations/query/attribute_add.py +1 -1
  85. infrahub/core/migrations/query/attribute_rename.py +1 -1
  86. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  87. infrahub/core/migrations/query/node_duplicate.py +1 -1
  88. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  89. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  90. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  91. infrahub/core/migrations/schema/node_remove.py +1 -1
  92. infrahub/core/migrations/schema/tasks.py +5 -5
  93. infrahub/core/migrations/shared.py +4 -4
  94. infrahub/core/models.py +7 -8
  95. infrahub/core/node/__init__.py +161 -40
  96. infrahub/core/node/base.py +1 -1
  97. infrahub/core/node/constraints/grouped_uniqueness.py +9 -2
  98. infrahub/core/node/delete_validator.py +4 -4
  99. infrahub/core/node/ipam.py +13 -8
  100. infrahub/core/node/permissions.py +4 -0
  101. infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
  102. infrahub/core/node/standard.py +3 -5
  103. infrahub/core/property.py +1 -1
  104. infrahub/core/protocols.py +4 -0
  105. infrahub/core/protocols_base.py +4 -2
  106. infrahub/core/query/__init__.py +2 -5
  107. infrahub/core/query/attribute.py +9 -9
  108. infrahub/core/query/branch.py +5 -5
  109. infrahub/core/query/delete.py +1 -1
  110. infrahub/core/query/diff.py +45 -7
  111. infrahub/core/query/ipam.py +4 -4
  112. infrahub/core/query/node.py +19 -14
  113. infrahub/core/query/relationship.py +10 -11
  114. infrahub/core/query/resource_manager.py +13 -11
  115. infrahub/core/query/standard_node.py +6 -6
  116. infrahub/core/query/task.py +3 -3
  117. infrahub/core/query/task_log.py +1 -1
  118. infrahub/core/query/utils.py +5 -5
  119. infrahub/core/registry.py +0 -2
  120. infrahub/core/relationship/constraints/count.py +1 -1
  121. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  122. infrahub/core/relationship/model.py +66 -26
  123. infrahub/core/schema/__init__.py +6 -4
  124. infrahub/core/schema/basenode_schema.py +1 -3
  125. infrahub/core/schema/definitions/core.py +14 -2
  126. infrahub/core/schema/definitions/internal.py +16 -0
  127. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  128. infrahub/core/schema/generated/node_schema.py +5 -0
  129. infrahub/core/schema/generic_schema.py +5 -1
  130. infrahub/core/schema/manager.py +45 -42
  131. infrahub/core/schema/node_schema.py +4 -0
  132. infrahub/core/schema/profile_schema.py +4 -0
  133. infrahub/core/schema/relationship_schema.py +2 -2
  134. infrahub/core/schema/schema_branch.py +248 -14
  135. infrahub/core/schema/template_schema.py +36 -0
  136. infrahub/core/task/user_task.py +7 -5
  137. infrahub/core/timestamp.py +1 -1
  138. infrahub/core/utils.py +3 -2
  139. infrahub/core/validators/attribute/choices.py +1 -1
  140. infrahub/core/validators/attribute/enum.py +1 -1
  141. infrahub/core/validators/attribute/kind.py +1 -1
  142. infrahub/core/validators/attribute/length.py +1 -1
  143. infrahub/core/validators/attribute/optional.py +1 -1
  144. infrahub/core/validators/attribute/regex.py +1 -1
  145. infrahub/core/validators/attribute/unique.py +1 -1
  146. infrahub/core/validators/checks_runner.py +37 -0
  147. infrahub/core/validators/node/generate_profile.py +1 -1
  148. infrahub/core/validators/node/hierarchy.py +1 -1
  149. infrahub/core/validators/query.py +1 -1
  150. infrahub/core/validators/relationship/count.py +1 -1
  151. infrahub/core/validators/relationship/optional.py +1 -1
  152. infrahub/core/validators/relationship/peer.py +1 -1
  153. infrahub/core/validators/tasks.py +8 -6
  154. infrahub/core/validators/uniqueness/query.py +20 -17
  155. infrahub/database/__init__.py +15 -2
  156. infrahub/database/memgraph.py +1 -1
  157. infrahub/dependencies/builder/constraint/grouped/node_runner.py +0 -2
  158. infrahub/dependencies/builder/diff/combiner.py +1 -1
  159. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  160. infrahub/dependencies/builder/diff/coordinator.py +0 -2
  161. infrahub/dependencies/builder/diff/deserializer.py +1 -1
  162. infrahub/dependencies/builder/diff/enricher/summary_counts.py +1 -1
  163. infrahub/events/branch_action.py +47 -21
  164. infrahub/events/group_action.py +73 -0
  165. infrahub/events/models.py +159 -51
  166. infrahub/events/node_action.py +74 -8
  167. infrahub/events/repository_action.py +8 -8
  168. infrahub/events/schema_action.py +21 -8
  169. infrahub/generators/tasks.py +12 -13
  170. infrahub/git/base.py +3 -5
  171. infrahub/git/constants.py +0 -1
  172. infrahub/git/integrator.py +36 -35
  173. infrahub/git/repository.py +7 -8
  174. infrahub/git/tasks.py +43 -107
  175. infrahub/git_credential/helper.py +2 -3
  176. infrahub/graphql/analyzer.py +572 -11
  177. infrahub/graphql/app.py +34 -26
  178. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  179. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  180. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  181. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  182. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  183. infrahub/graphql/enums.py +1 -1
  184. infrahub/graphql/initialization.py +5 -1
  185. infrahub/graphql/loaders/node.py +2 -2
  186. infrahub/graphql/manager.py +59 -54
  187. infrahub/graphql/mutations/account.py +20 -13
  188. infrahub/graphql/mutations/artifact_definition.py +16 -12
  189. infrahub/graphql/mutations/branch.py +61 -40
  190. infrahub/graphql/mutations/computed_attribute.py +19 -13
  191. infrahub/graphql/mutations/diff.py +37 -9
  192. infrahub/graphql/mutations/diff_conflict.py +9 -8
  193. infrahub/graphql/mutations/graphql_query.py +19 -11
  194. infrahub/graphql/mutations/ipam.py +21 -19
  195. infrahub/graphql/mutations/main.py +197 -44
  196. infrahub/graphql/mutations/menu.py +8 -8
  197. infrahub/graphql/mutations/proposed_change.py +36 -28
  198. infrahub/graphql/mutations/relationship.py +302 -105
  199. infrahub/graphql/mutations/repository.py +41 -35
  200. infrahub/graphql/mutations/resource_manager.py +26 -26
  201. infrahub/graphql/mutations/schema.py +51 -33
  202. infrahub/graphql/mutations/tasks.py +16 -10
  203. infrahub/graphql/parser.py +1 -1
  204. infrahub/graphql/permissions.py +6 -4
  205. infrahub/graphql/queries/account.py +22 -18
  206. infrahub/graphql/queries/branch.py +6 -4
  207. infrahub/graphql/queries/diff/tree.py +48 -42
  208. infrahub/graphql/queries/event.py +112 -0
  209. infrahub/graphql/queries/internal.py +3 -3
  210. infrahub/graphql/queries/ipam.py +23 -18
  211. infrahub/graphql/queries/relationship.py +11 -10
  212. infrahub/graphql/queries/resource_manager.py +43 -27
  213. infrahub/graphql/queries/search.py +9 -8
  214. infrahub/graphql/queries/status.py +12 -9
  215. infrahub/graphql/queries/task.py +11 -9
  216. infrahub/graphql/resolvers/resolver.py +69 -43
  217. infrahub/graphql/resolvers/single_relationship.py +16 -10
  218. infrahub/graphql/schema.py +2 -0
  219. infrahub/graphql/subscription/__init__.py +1 -1
  220. infrahub/graphql/subscription/events.py +1 -1
  221. infrahub/graphql/subscription/graphql_query.py +8 -8
  222. infrahub/graphql/types/branch.py +2 -2
  223. infrahub/graphql/types/common.py +6 -1
  224. infrahub/graphql/types/enums.py +2 -0
  225. infrahub/graphql/types/event.py +100 -0
  226. infrahub/graphql/types/interface.py +2 -2
  227. infrahub/graphql/types/node.py +3 -3
  228. infrahub/graphql/types/permission.py +2 -2
  229. infrahub/graphql/types/relationship.py +3 -3
  230. infrahub/graphql/types/standard_node.py +9 -11
  231. infrahub/graphql/utils.py +28 -182
  232. infrahub/groups/tasks.py +2 -3
  233. infrahub/lock.py +1 -1
  234. infrahub/menu/constants.py +1 -0
  235. infrahub/menu/generator.py +14 -3
  236. infrahub/menu/menu.py +116 -127
  237. infrahub/menu/models.py +4 -4
  238. infrahub/message_bus/messages/__init__.py +0 -4
  239. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  240. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  241. infrahub/message_bus/operations/__init__.py +3 -5
  242. infrahub/message_bus/operations/check/__init__.py +2 -2
  243. infrahub/message_bus/operations/check/generator.py +1 -3
  244. infrahub/message_bus/operations/check/repository.py +1 -1
  245. infrahub/message_bus/operations/event/branch.py +7 -3
  246. infrahub/message_bus/operations/event/schema.py +1 -1
  247. infrahub/message_bus/operations/finalize/validator.py +1 -1
  248. infrahub/message_bus/operations/git/file.py +2 -2
  249. infrahub/message_bus/operations/git/repository.py +1 -1
  250. infrahub/message_bus/operations/requests/__init__.py +0 -2
  251. infrahub/message_bus/operations/requests/generator_definition.py +1 -1
  252. infrahub/message_bus/operations/requests/proposed_change.py +26 -11
  253. infrahub/message_bus/operations/requests/repository.py +2 -2
  254. infrahub/message_bus/operations/send/echo.py +1 -1
  255. infrahub/message_bus/types.py +1 -1
  256. infrahub/permissions/__init__.py +2 -1
  257. infrahub/permissions/types.py +26 -0
  258. infrahub/pools/prefix.py +29 -165
  259. infrahub/prefect_server/__init__.py +0 -0
  260. infrahub/prefect_server/app.py +18 -0
  261. infrahub/prefect_server/database.py +20 -0
  262. infrahub/prefect_server/events.py +28 -0
  263. infrahub/prefect_server/models.py +46 -0
  264. infrahub/proposed_change/models.py +15 -1
  265. infrahub/proposed_change/tasks.py +173 -35
  266. infrahub/pytest_plugin.py +4 -4
  267. infrahub/server.py +12 -11
  268. infrahub/services/__init__.py +147 -62
  269. infrahub/services/adapters/cache/__init__.py +7 -5
  270. infrahub/services/adapters/cache/nats.py +40 -22
  271. infrahub/services/adapters/cache/redis.py +0 -4
  272. infrahub/services/adapters/event/__init__.py +10 -18
  273. infrahub/services/adapters/http/__init__.py +0 -5
  274. infrahub/services/adapters/http/httpx.py +22 -15
  275. infrahub/services/adapters/message_bus/__init__.py +23 -6
  276. infrahub/services/adapters/message_bus/local.py +8 -6
  277. infrahub/services/adapters/message_bus/nats.py +12 -6
  278. infrahub/services/adapters/message_bus/rabbitmq.py +22 -9
  279. infrahub/services/adapters/workflow/__init__.py +11 -8
  280. infrahub/services/adapters/workflow/local.py +28 -7
  281. infrahub/services/adapters/workflow/worker.py +23 -7
  282. infrahub/services/component.py +38 -35
  283. infrahub/services/scheduler.py +32 -29
  284. infrahub/storage.py +2 -4
  285. infrahub/task_manager/constants.py +1 -1
  286. infrahub/task_manager/event.py +182 -0
  287. infrahub/task_manager/models.py +125 -1
  288. infrahub/task_manager/task.py +1 -1
  289. infrahub/tasks/artifact.py +14 -16
  290. infrahub/tasks/registry.py +1 -1
  291. infrahub/tasks/telemetry.py +13 -14
  292. infrahub/transformations/tasks.py +3 -5
  293. infrahub/trigger/__init__.py +0 -0
  294. infrahub/trigger/catalogue.py +15 -0
  295. infrahub/trigger/constants.py +9 -0
  296. infrahub/trigger/models.py +69 -0
  297. infrahub/trigger/tasks.py +85 -0
  298. infrahub/types.py +1 -1
  299. infrahub/utils.py +1 -1
  300. infrahub/webhook/constants.py +0 -2
  301. infrahub/webhook/models.py +8 -2
  302. infrahub/webhook/tasks.py +20 -73
  303. infrahub/webhook/triggers.py +20 -0
  304. infrahub/workers/infrahub_async.py +36 -25
  305. infrahub/workers/utils.py +63 -0
  306. infrahub/workflows/catalogue.py +13 -37
  307. infrahub/workflows/initialization.py +6 -8
  308. infrahub/workflows/models.py +3 -5
  309. infrahub/workflows/utils.py +1 -1
  310. infrahub_sdk/ctl/check.py +3 -3
  311. infrahub_sdk/ctl/cli_commands.py +11 -10
  312. infrahub_sdk/ctl/exceptions.py +0 -6
  313. infrahub_sdk/ctl/exporter.py +1 -1
  314. infrahub_sdk/ctl/generator.py +5 -5
  315. infrahub_sdk/ctl/importer.py +3 -2
  316. infrahub_sdk/ctl/menu.py +1 -1
  317. infrahub_sdk/ctl/object.py +1 -1
  318. infrahub_sdk/ctl/repository.py +23 -15
  319. infrahub_sdk/ctl/schema.py +2 -2
  320. infrahub_sdk/ctl/utils.py +4 -3
  321. infrahub_sdk/ctl/validate.py +2 -1
  322. infrahub_sdk/exceptions.py +6 -0
  323. infrahub_sdk/generator.py +3 -0
  324. infrahub_sdk/node.py +2 -2
  325. infrahub_sdk/schema/__init__.py +14 -2
  326. infrahub_sdk/schema/main.py +7 -0
  327. infrahub_sdk/utils.py +11 -1
  328. infrahub_sdk/yaml.py +2 -3
  329. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/METADATA +46 -12
  330. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/RECORD +338 -321
  331. infrahub_testcontainers/container.py +14 -6
  332. infrahub_testcontainers/docker-compose.test.yml +24 -5
  333. infrahub_testcontainers/haproxy.cfg +43 -0
  334. infrahub_testcontainers/helpers.py +85 -1
  335. infrahub/core/branch/constants.py +0 -2
  336. infrahub/graphql/query.py +0 -52
  337. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  338. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  339. infrahub/schema/constants.py +0 -1
  340. infrahub/schema/tasks.py +0 -76
  341. infrahub/services/adapters/database/__init__.py +0 -9
  342. infrahub_sdk/ctl/_file.py +0 -13
  343. /infrahub/{schema → artifacts}/__init__.py +0 -0
  344. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/LICENSE.txt +0 -0
  345. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/WHEEL +0 -0
  346. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/entry_points.txt +0 -0
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING, Any, Optional, Union
4
4
 
5
- from graphene import Argument, Boolean, DateTime, Field, InputObjectType, Int, List, ObjectType, String
5
+ from graphene import Argument, Boolean, DateTime, Field, InputObjectType, Int, List, NonNull, ObjectType, String
6
6
  from graphene import Enum as GrapheneEnum
7
7
  from infrahub_sdk.utils import extract_fields
8
8
 
@@ -75,7 +75,7 @@ class DiffAttribute(DiffSummaryCounts):
75
75
  last_changed_at = DateTime(required=True)
76
76
  status = Field(GrapheneDiffActionEnum, required=True)
77
77
  path_identifier = String(required=True)
78
- properties = List(DiffProperty)
78
+ properties = List(NonNull(DiffProperty))
79
79
  contains_conflict = Boolean(required=True)
80
80
  conflict = Field(ConflictDetails, required=False)
81
81
 
@@ -88,7 +88,7 @@ class DiffSingleRelationship(DiffSummaryCounts):
88
88
  path_identifier = String(required=True)
89
89
  contains_conflict = Boolean(required=True)
90
90
  conflict = Field(ConflictDetails, required=False)
91
- properties = List(DiffProperty)
91
+ properties = List(NonNull(DiffProperty))
92
92
 
93
93
 
94
94
  class DiffRelationship(DiffSummaryCounts):
@@ -98,7 +98,7 @@ class DiffRelationship(DiffSummaryCounts):
98
98
  cardinality = Field(GrapheneCardinalityEnum, required=True)
99
99
  status = Field(GrapheneDiffActionEnum, required=True)
100
100
  path_identifier = String(required=True)
101
- elements = List(DiffSingleRelationship, required=True)
101
+ elements = List(NonNull(DiffSingleRelationship), required=True)
102
102
  contains_conflict = Boolean(required=True)
103
103
 
104
104
 
@@ -118,8 +118,8 @@ class DiffNode(DiffSummaryCounts):
118
118
  contains_conflict = Boolean(required=True)
119
119
  last_changed_at = DateTime(required=False)
120
120
  parent = Field(DiffNodeParent, required=False)
121
- attributes = List(DiffAttribute, required=True)
122
- relationships = List(DiffRelationship, required=True)
121
+ attributes = List(NonNull(DiffAttribute), required=True)
122
+ relationships = List(NonNull(DiffRelationship), required=True)
123
123
 
124
124
 
125
125
  class DiffTree(DiffSummaryCounts):
@@ -130,7 +130,7 @@ class DiffTree(DiffSummaryCounts):
130
130
  num_untracked_base_changes = Int(required=False)
131
131
  num_untracked_diff_changes = Int(required=False)
132
132
  name = String(required=False)
133
- nodes = List(DiffNode)
133
+ nodes = List(NonNull(DiffNode))
134
134
 
135
135
 
136
136
  class DiffTreeSummary(DiffSummaryCounts):
@@ -145,10 +145,10 @@ class DiffTreeSummary(DiffSummaryCounts):
145
145
 
146
146
  class DiffTreeResolver:
147
147
  async def to_diff_tree(
148
- self, enriched_diff_root: EnrichedDiffRoot, context: GraphqlContext | None = None
148
+ self, enriched_diff_root: EnrichedDiffRoot, graphql_context: GraphqlContext | None = None
149
149
  ) -> DiffTree:
150
150
  all_nodes = list(enriched_diff_root.nodes)
151
- tree_nodes = [self.to_diff_node(enriched_node=e_node, context=context) for e_node in all_nodes]
151
+ tree_nodes = [self.to_diff_node(enriched_node=e_node, graphql_context=graphql_context) for e_node in all_nodes]
152
152
  name = None
153
153
  if enriched_diff_root.tracking_id and isinstance(enriched_diff_root.tracking_id, NameTrackingId):
154
154
  name = enriched_diff_root.tracking_id.name
@@ -165,21 +165,22 @@ class DiffTreeResolver:
165
165
  num_conflicts=enriched_diff_root.num_conflicts,
166
166
  )
167
167
 
168
- def to_diff_node(self, enriched_node: EnrichedDiffNode, context: GraphqlContext | None = None) -> DiffNode:
168
+ def to_diff_node(self, enriched_node: EnrichedDiffNode, graphql_context: GraphqlContext | None = None) -> DiffNode:
169
169
  diff_attributes = [
170
- self.to_diff_attribute(enriched_attribute=e_attr, context=context) for e_attr in enriched_node.attributes
170
+ self.to_diff_attribute(enriched_attribute=e_attr, graphql_context=graphql_context)
171
+ for e_attr in enriched_node.attributes
171
172
  ]
172
173
  diff_relationships = [
173
- self.to_diff_relationship(enriched_relationship=e_rel, context=context)
174
+ self.to_diff_relationship(enriched_relationship=e_rel, graphql_context=graphql_context)
174
175
  for e_rel in enriched_node.relationships
175
176
  if e_rel.include_in_response
176
177
  ]
177
178
  conflict = None
178
179
  if enriched_node.conflict:
179
- conflict = self.to_diff_conflict(enriched_conflict=enriched_node.conflict, context=context)
180
+ conflict = self.to_diff_conflict(enriched_conflict=enriched_node.conflict, graphql_context=graphql_context)
180
181
 
181
182
  parent = None
182
- if parent_info := enriched_node.get_parent_info(context=context):
183
+ if parent_info := enriched_node.get_parent_info(graphql_context=graphql_context):
183
184
  parent = DiffNodeParent(
184
185
  uuid=parent_info.node.uuid,
185
186
  kind=parent_info.node.kind,
@@ -205,10 +206,11 @@ class DiffTreeResolver:
205
206
  )
206
207
 
207
208
  def to_diff_attribute(
208
- self, enriched_attribute: EnrichedDiffAttribute, context: GraphqlContext | None = None
209
+ self, enriched_attribute: EnrichedDiffAttribute, graphql_context: GraphqlContext | None = None
209
210
  ) -> DiffAttribute:
210
211
  diff_properties = [
211
- self.to_diff_property(enriched_property=e_prop, context=context) for e_prop in enriched_attribute.properties
212
+ self.to_diff_property(enriched_property=e_prop, graphql_context=graphql_context)
213
+ for e_prop in enriched_attribute.properties
212
214
  ]
213
215
  conflict = None
214
216
  for diff_prop in diff_properties:
@@ -230,10 +232,10 @@ class DiffTreeResolver:
230
232
  )
231
233
 
232
234
  def to_diff_relationship(
233
- self, enriched_relationship: EnrichedDiffRelationship, context: GraphqlContext | None = None
235
+ self, enriched_relationship: EnrichedDiffRelationship, graphql_context: GraphqlContext | None = None
234
236
  ) -> DiffRelationship:
235
237
  diff_elements = [
236
- self.to_diff_relationship_element(enriched_element=element, context=context)
238
+ self.to_diff_relationship_element(enriched_element=element, graphql_context=graphql_context)
237
239
  for element in enriched_relationship.relationships
238
240
  ]
239
241
  return DiffRelationship(
@@ -252,12 +254,14 @@ class DiffTreeResolver:
252
254
  )
253
255
 
254
256
  def to_diff_relationship_element(
255
- self, enriched_element: EnrichedDiffSingleRelationship, context: GraphqlContext | None = None
257
+ self, enriched_element: EnrichedDiffSingleRelationship, graphql_context: GraphqlContext | None = None
256
258
  ) -> DiffSingleRelationship:
257
259
  diff_properties = [self.to_diff_property(e_prop) for e_prop in enriched_element.properties]
258
260
  conflict = None
259
261
  if enriched_element.conflict:
260
- conflict = self.to_diff_conflict(enriched_conflict=enriched_element.conflict, context=context)
262
+ conflict = self.to_diff_conflict(
263
+ enriched_conflict=enriched_element.conflict, graphql_context=graphql_context
264
+ )
261
265
  return DiffSingleRelationship(
262
266
  last_changed_at=enriched_element.changed_at.obj,
263
267
  status=enriched_element.action,
@@ -274,11 +278,13 @@ class DiffTreeResolver:
274
278
  )
275
279
 
276
280
  def to_diff_property(
277
- self, enriched_property: EnrichedDiffProperty, context: GraphqlContext | None = None
281
+ self, enriched_property: EnrichedDiffProperty, graphql_context: GraphqlContext | None = None
278
282
  ) -> DiffProperty:
279
283
  conflict = None
280
284
  if enriched_property.conflict:
281
- conflict = self.to_diff_conflict(enriched_conflict=enriched_property.conflict, context=context)
285
+ conflict = self.to_diff_conflict(
286
+ enriched_conflict=enriched_property.conflict, graphql_context=graphql_context
287
+ )
282
288
  return DiffProperty(
283
289
  property_type=enriched_property.property_type.value,
284
290
  last_changed_at=enriched_property.changed_at.obj,
@@ -294,7 +300,7 @@ class DiffTreeResolver:
294
300
  def to_diff_conflict(
295
301
  self,
296
302
  enriched_conflict: EnrichedDiffConflict,
297
- context: GraphqlContext | None = None, # pylint: disable=unused-argument
303
+ graphql_context: GraphqlContext | None = None, # noqa: ARG002
298
304
  ) -> ConflictDetails:
299
305
  return ConflictDetails(
300
306
  uuid=enriched_conflict.uuid,
@@ -366,10 +372,9 @@ class DiffTreeResolver:
366
372
  if diff_branch_name:
367
373
  diff_response.num_untracked_diff_changes = branch_change_map.get(diff_branch_name, 0)
368
374
 
369
- # pylint: disable=unused-argument
370
375
  async def resolve(
371
376
  self,
372
- root: dict,
377
+ root: dict, # noqa: ARG002
373
378
  info: GraphQLResolveInfo,
374
379
  branch: str | None = None,
375
380
  name: str | None = None,
@@ -382,10 +387,10 @@ class DiffTreeResolver:
382
387
  offset: int | None = None,
383
388
  ) -> Optional[Union[list[dict[str, Any]], dict[str, Any]]]:
384
389
  component_registry = get_component_registry()
385
- context: GraphqlContext = info.context
386
- base_branch = await registry.get_branch(db=context.db, branch=registry.default_branch)
387
- diff_branch = await registry.get_branch(db=context.db, branch=branch)
388
- diff_repo = await component_registry.get_component(DiffRepository, db=context.db, branch=diff_branch)
390
+ graphql_context: GraphqlContext = info.context
391
+ base_branch = await registry.get_branch(db=graphql_context.db, branch=registry.default_branch)
392
+ diff_branch = await registry.get_branch(db=graphql_context.db, branch=branch)
393
+ diff_repo = await component_registry.get_component(DiffRepository, db=graphql_context.db, branch=diff_branch)
389
394
  branch_start_timestamp = Timestamp(diff_branch.get_branched_from())
390
395
  if from_time:
391
396
  from_timestamp = Timestamp(from_time.isoformat())
@@ -394,7 +399,7 @@ class DiffTreeResolver:
394
399
  if to_time:
395
400
  to_timestamp = Timestamp(to_time.isoformat())
396
401
  else:
397
- to_timestamp = context.at or Timestamp()
402
+ to_timestamp = graphql_context.at or Timestamp()
398
403
 
399
404
  # Convert filters to dict and merge root_node_uuids for compatibility
400
405
  filters_dict = dict(filters or {})
@@ -428,12 +433,12 @@ class DiffTreeResolver:
428
433
  enriched_diff = enriched_diffs[0]
429
434
 
430
435
  full_fields = await extract_fields(info.field_nodes[0].selection_set)
431
- diff_tree = await self.to_diff_tree(enriched_diff_root=enriched_diff, context=context)
436
+ diff_tree = await self.to_diff_tree(enriched_diff_root=enriched_diff, graphql_context=graphql_context)
432
437
  need_base_changes = "num_untracked_base_changes" in full_fields
433
438
  need_branch_changes = "num_untracked_diff_changes" in full_fields
434
439
  if need_base_changes or need_branch_changes:
435
440
  await self._add_untracked_fields(
436
- db=context.db,
441
+ db=graphql_context.db,
437
442
  diff_response=diff_tree,
438
443
  from_time=enriched_diff.to_time,
439
444
  base_branch_name=base_branch.name if need_base_changes else None,
@@ -441,10 +446,9 @@ class DiffTreeResolver:
441
446
  )
442
447
  return await self.to_graphql(fields=full_fields, diff_object=diff_tree)
443
448
 
444
- # pylint: disable=unused-argument
445
449
  async def summary(
446
450
  self,
447
- root: dict,
451
+ root: dict, # noqa: ARG002
448
452
  info: GraphQLResolveInfo,
449
453
  branch: str | None = None,
450
454
  from_time: datetime | None = None,
@@ -452,10 +456,10 @@ class DiffTreeResolver:
452
456
  filters: dict | None = None,
453
457
  ) -> Optional[Union[list[dict[str, Any]], dict[str, Any]]]:
454
458
  component_registry = get_component_registry()
455
- context: GraphqlContext = info.context
456
- base_branch = await registry.get_branch(db=context.db, branch=registry.default_branch)
457
- diff_branch = await registry.get_branch(db=context.db, branch=branch)
458
- diff_repo = await component_registry.get_component(DiffRepository, db=context.db, branch=diff_branch)
459
+ graphql_context: GraphqlContext = info.context
460
+ base_branch = await registry.get_branch(db=graphql_context.db, branch=registry.default_branch)
461
+ diff_branch = await registry.get_branch(db=graphql_context.db, branch=branch)
462
+ diff_repo = await component_registry.get_component(DiffRepository, db=graphql_context.db, branch=diff_branch)
459
463
  branch_start_timestamp = Timestamp(diff_branch.get_branched_from())
460
464
  if from_time:
461
465
  from_timestamp = Timestamp(from_time.isoformat())
@@ -464,7 +468,7 @@ class DiffTreeResolver:
464
468
  if to_time:
465
469
  to_timestamp = Timestamp(to_time.isoformat())
466
470
  else:
467
- to_timestamp = context.at or Timestamp()
471
+ to_timestamp = graphql_context.at or Timestamp()
468
472
 
469
473
  filters_dict = dict(filters or {})
470
474
 
@@ -490,7 +494,7 @@ class DiffTreeResolver:
490
494
  need_branch_changes = "num_untracked_diff_changes" in full_fields
491
495
  if need_base_changes or need_branch_changes:
492
496
  await self._add_untracked_fields(
493
- db=context.db,
497
+ db=graphql_context.db,
494
498
  diff_response=diff_tree_summary,
495
499
  from_time=summary.to_time,
496
500
  base_branch_name=base_branch.name if need_base_changes else None,
@@ -519,7 +523,6 @@ class DiffTreeQueryFilters(InputObjectType):
519
523
  DiffTreeQuery = Field(
520
524
  DiffTree,
521
525
  name=String(),
522
- resolver=DiffTreeResolver().resolve,
523
526
  branch=String(),
524
527
  from_time=DateTime(),
525
528
  to_time=DateTime(),
@@ -528,14 +531,17 @@ DiffTreeQuery = Field(
528
531
  filters=DiffTreeQueryFilters(),
529
532
  limit=Int(),
530
533
  offset=Int(),
534
+ resolver=DiffTreeResolver().resolve,
535
+ required=False,
531
536
  )
532
537
 
533
538
  DiffTreeSummaryQuery = Field(
534
539
  DiffTreeSummary,
535
540
  name=String(),
536
- resolver=DiffTreeResolver().summary,
537
541
  branch=String(),
538
542
  from_time=DateTime(),
539
543
  to_time=DateTime(),
540
544
  filters=DiffTreeQueryFilters(),
545
+ resolver=DiffTreeResolver().summary,
546
+ required=False,
541
547
  )
@@ -0,0 +1,112 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from graphene import Boolean, DateTime, Field, Int, List, NonNull, ObjectType, String
6
+ from infrahub_sdk.utils import extract_fields_first_node
7
+
8
+ from infrahub.exceptions import ValidationError
9
+ from infrahub.graphql.types.event import EventNodes
10
+ from infrahub.task_manager.event import PrefectEvent
11
+ from infrahub.task_manager.models import InfrahubEventFilter
12
+
13
+ if TYPE_CHECKING:
14
+ from datetime import datetime
15
+
16
+ from graphql import GraphQLResolveInfo
17
+
18
+
19
+ class Events(ObjectType):
20
+ edges = List(NonNull(EventNodes), required=True)
21
+ count = Int(required=True)
22
+
23
+ @staticmethod
24
+ async def resolve(
25
+ root: dict, # noqa: ARG004
26
+ info: GraphQLResolveInfo,
27
+ limit: int = 10,
28
+ has_children: bool | None = None,
29
+ level: int | None = None,
30
+ offset: int | None = None,
31
+ account__ids: list[str] | None = None,
32
+ ids: list[str] | None = None,
33
+ branches: list[str] | None = None,
34
+ event_type: list[str] | None = None,
35
+ related_node__ids: list[str] | None = None,
36
+ primary_node__ids: list[str] | None = None,
37
+ parent__ids: list[str] | None = None,
38
+ since: datetime | None = None,
39
+ until: datetime | None = None,
40
+ ) -> dict[str, Any]:
41
+ ids = ids or []
42
+ if limit > 50:
43
+ # Prefect restricts this to 50
44
+ raise ValidationError(input_value="The parameter 'limit' can't be above 50")
45
+
46
+ event_filter = InfrahubEventFilter.from_filters(
47
+ ids=ids,
48
+ branches=branches,
49
+ account__ids=account__ids,
50
+ has_children=has_children,
51
+ event_type=event_type,
52
+ related_node__ids=related_node__ids,
53
+ primary_node__ids=primary_node__ids,
54
+ parent__ids=parent__ids,
55
+ since=since,
56
+ until=until,
57
+ level=level,
58
+ )
59
+
60
+ return await Events.query(
61
+ info=info,
62
+ event_filter=event_filter,
63
+ limit=limit,
64
+ offset=offset,
65
+ )
66
+
67
+ @classmethod
68
+ async def query(
69
+ cls,
70
+ info: GraphQLResolveInfo,
71
+ event_filter: InfrahubEventFilter,
72
+ limit: int,
73
+ offset: int | None = None,
74
+ ) -> dict[str, Any]:
75
+ fields = await extract_fields_first_node(info)
76
+
77
+ prefect_tasks = await PrefectEvent.query(
78
+ fields=fields,
79
+ event_filter=event_filter,
80
+ limit=limit,
81
+ offset=offset,
82
+ )
83
+ return {
84
+ "count": prefect_tasks.get("count", 0),
85
+ "edges": prefect_tasks.get("edges", []),
86
+ }
87
+
88
+
89
+ Event = Field(
90
+ Events,
91
+ limit=Int(required=False),
92
+ offset=Int(required=False),
93
+ level=Int(required=False),
94
+ has_children=Boolean(required=False, description="Filter events based on if they can have children or not"),
95
+ event_type=List(NonNull(String), description="Filter events that match a specific type"),
96
+ primary_node__ids=List(
97
+ NonNull(String), description="Filter events where the primary node id is within indicated node ids"
98
+ ),
99
+ related_node__ids=List(
100
+ NonNull(String), description="Filter events where the related node ids are within indicated node ids"
101
+ ),
102
+ parent__ids=List(
103
+ NonNull(String), description="Search events that has any of the indicated event ids listed as parents"
104
+ ),
105
+ since=DateTime(required=False, description="Search events since this timestamp, defaults to 180 days back"),
106
+ until=DateTime(required=False, description="Search events until this timestamp, defaults the current time"),
107
+ branches=List(NonNull(String), required=False, description="Filter the query to specific branches"),
108
+ account__ids=List(NonNull(String), required=False, description="Filter the query to specific accounts"),
109
+ ids=List(NonNull(String)),
110
+ resolver=Events.resolve,
111
+ required=True,
112
+ )
@@ -17,10 +17,10 @@ class Info(ObjectType):
17
17
 
18
18
  @staticmethod
19
19
  async def resolve(
20
- root: dict, # pylint: disable=unused-argument
21
- info: GraphQLResolveInfo, # pylint: disable=unused-argument
20
+ root: dict, # noqa: ARG004
21
+ info: GraphQLResolveInfo, # noqa: ARG004
22
22
  ) -> dict[str, str]:
23
23
  return {"deployment_id": str(registry.id), "version": __version__}
24
24
 
25
25
 
26
- InfrahubInfo = Field(Info, resolver=Info.resolve)
26
+ InfrahubInfo = Field(Info, resolver=Info.resolve, required=True)
@@ -4,13 +4,14 @@ import ipaddress
4
4
  from typing import TYPE_CHECKING, Optional
5
5
 
6
6
  from graphene import Field, Int, ObjectType, String
7
+ from netaddr import IPSet
7
8
 
8
9
  from infrahub.core.constants import InfrahubKind
9
10
  from infrahub.core.manager import NodeManager
10
11
  from infrahub.core.query.ipam import get_ip_addresses, get_subnets
11
12
  from infrahub.exceptions import NodeNotFoundError, ValidationError
12
13
  from infrahub.pools.address import get_available
13
- from infrahub.pools.prefix import PrefixPool
14
+ from infrahub.pools.prefix import get_next_available_prefix
14
15
 
15
16
  if TYPE_CHECKING:
16
17
  from graphql import GraphQLResolveInfo
@@ -23,18 +24,18 @@ class IPAddressGetNextAvailable(ObjectType):
23
24
 
24
25
  @staticmethod
25
26
  async def resolve(
26
- root: dict, # pylint: disable=unused-argument
27
+ root: dict, # noqa: ARG004
27
28
  info: GraphQLResolveInfo,
28
29
  prefix_id: str,
29
30
  prefix_length: Optional[int] = None,
30
31
  ) -> dict[str, str]:
31
- context: GraphqlContext = info.context
32
+ graphql_context: GraphqlContext = info.context
32
33
 
33
- prefix = await NodeManager.get_one(id=prefix_id, db=context.db, branch=context.branch)
34
+ prefix = await NodeManager.get_one(id=prefix_id, db=graphql_context.db, branch=graphql_context.branch)
34
35
 
35
36
  if not prefix:
36
37
  raise NodeNotFoundError(
37
- branch_name=context.branch.name, node_type=InfrahubKind.IPPREFIX, identifier=prefix_id
38
+ branch_name=graphql_context.branch.name, node_type=InfrahubKind.IPPREFIX, identifier=prefix_id
38
39
  )
39
40
 
40
41
  ip_prefix = ipaddress.ip_network(prefix.prefix.value) # type: ignore[attr-defined]
@@ -43,12 +44,12 @@ class IPAddressGetNextAvailable(ObjectType):
43
44
  if not ip_prefix.prefixlen <= prefix_length <= ip_prefix.max_prefixlen:
44
45
  raise ValidationError(input_value="Invalid prefix length for current selected prefix")
45
46
 
46
- namespace = await prefix.ip_namespace.get_peer(db=context.db) # type: ignore[attr-defined]
47
+ namespace = await prefix.ip_namespace.get_peer(db=graphql_context.db) # type: ignore[attr-defined]
47
48
  addresses = await get_ip_addresses(
48
- db=context.db,
49
+ db=graphql_context.db,
49
50
  ip_prefix=ip_prefix,
50
51
  namespace=namespace,
51
- branch=context.branch,
52
+ branch=graphql_context.branch,
52
53
  )
53
54
 
54
55
  available = get_available(
@@ -70,33 +71,35 @@ class IPPrefixGetNextAvailable(ObjectType):
70
71
 
71
72
  @staticmethod
72
73
  async def resolve(
73
- root: dict, # pylint: disable=unused-argument
74
+ root: dict, # noqa: ARG004
74
75
  info: GraphQLResolveInfo,
75
76
  prefix_id: str,
76
77
  prefix_length: int,
77
78
  ) -> dict[str, str]:
78
- context: GraphqlContext = info.context
79
+ graphql_context: GraphqlContext = info.context
79
80
 
80
- prefix = await NodeManager.get_one(id=prefix_id, db=context.db, branch=context.branch)
81
+ prefix = await NodeManager.get_one(id=prefix_id, db=graphql_context.db, branch=graphql_context.branch)
81
82
 
82
83
  if not prefix:
83
84
  raise NodeNotFoundError(
84
- branch_name=context.branch.name, node_type=InfrahubKind.IPPREFIX, identifier=prefix_id
85
+ branch_name=graphql_context.branch.name, node_type=InfrahubKind.IPPREFIX, identifier=prefix_id
85
86
  )
86
87
 
87
- namespace = await prefix.ip_namespace.get_peer(db=context.db) # type: ignore[attr-defined]
88
+ namespace = await prefix.ip_namespace.get_peer(db=graphql_context.db) # type: ignore[attr-defined]
88
89
  subnets = await get_subnets(
89
- db=context.db,
90
+ db=graphql_context.db,
90
91
  ip_prefix=ipaddress.ip_network(prefix.prefix.value), # type: ignore[attr-defined]
91
92
  namespace=namespace,
92
- branch=context.branch,
93
+ branch=graphql_context.branch,
93
94
  )
94
95
 
95
- pool = PrefixPool(prefix.prefix.value) # type: ignore[attr-defined]
96
+ pool = IPSet([prefix.prefix.value])
96
97
  for subnet in subnets:
97
- pool.reserve(subnet=str(subnet.prefix))
98
+ pool.remove(addr=str(subnet.prefix))
99
+
100
+ prefix_ver = ipaddress.ip_network(prefix.prefix.value).version
101
+ next_available = get_next_available_prefix(pool=pool, prefix_length=prefix_length, prefix_ver=prefix_ver)
98
102
 
99
- next_available = pool.get(prefixlen=prefix_length)
100
103
  return {"prefix": str(next_available)}
101
104
 
102
105
 
@@ -105,6 +108,7 @@ InfrahubIPAddressGetNextAvailable = Field(
105
108
  prefix_id=String(required=True),
106
109
  prefix_length=Int(required=False),
107
110
  resolver=IPAddressGetNextAvailable.resolve,
111
+ required=True,
108
112
  )
109
113
 
110
114
 
@@ -113,4 +117,5 @@ InfrahubIPPrefixGetNextAvailable = Field(
113
117
  prefix_id=String(required=True),
114
118
  prefix_length=Int(required=False),
115
119
  resolver=IPPrefixGetNextAvailable.resolve,
120
+ required=True,
116
121
  )
@@ -15,30 +15,30 @@ if TYPE_CHECKING:
15
15
 
16
16
 
17
17
  class Relationships(ObjectType):
18
- edges = List(RelationshipNode)
19
- count = Int()
18
+ edges = List(of_type=NonNull(RelationshipNode), required=True)
19
+ count = Int(required=True)
20
20
 
21
21
  @staticmethod
22
22
  async def resolve(
23
- root: dict, # pylint: disable=unused-argument
23
+ root: dict, # noqa: ARG004
24
24
  info: GraphQLResolveInfo,
25
25
  ids: list[str],
26
26
  limit: int = 10,
27
27
  offset: int = 0,
28
28
  excluded_namespaces: Optional[list[str]] = None,
29
29
  ) -> dict[str, Any]:
30
- context: GraphqlContext = info.context
30
+ graphql_context: GraphqlContext = info.context
31
31
 
32
32
  fields = await extract_fields_first_node(info)
33
33
  excluded_namespaces = excluded_namespaces or []
34
34
 
35
35
  response: dict[str, Any] = {"edges": [], "count": None}
36
36
 
37
- async with context.db.start_session() as db:
37
+ async with graphql_context.db.start_session() as db:
38
38
  query = await RelationshipGetByIdentifierQuery.init(
39
39
  db=db,
40
- branch=context.branch,
41
- at=context.at,
40
+ branch=graphql_context.branch,
41
+ at=graphql_context.at,
42
42
  identifiers=ids,
43
43
  excluded_namespaces=excluded_namespaces,
44
44
  limit=limit,
@@ -74,9 +74,10 @@ class Relationships(ObjectType):
74
74
 
75
75
  Relationship = Field(
76
76
  Relationships,
77
- resolver=Relationships.resolve,
78
- limit=Int(required=False),
79
- offset=Int(required=False),
80
77
  ids=List(NonNull(String), required=True),
81
78
  excluded_namespaces=List(String),
79
+ limit=Int(required=False),
80
+ offset=Int(required=False),
81
+ resolver=Relationships.resolve,
82
+ required=True,
82
83
  )