infrahub-server 1.2.0rc0__py3-none-any.whl → 1.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. infrahub/api/dependencies.py +6 -6
  2. infrahub/api/diff/validation_models.py +7 -7
  3. infrahub/api/schema.py +1 -1
  4. infrahub/artifacts/models.py +5 -3
  5. infrahub/artifacts/tasks.py +3 -5
  6. infrahub/cli/__init__.py +13 -9
  7. infrahub/cli/constants.py +3 -0
  8. infrahub/cli/db.py +165 -183
  9. infrahub/cli/upgrade.py +146 -0
  10. infrahub/computed_attribute/gather.py +185 -0
  11. infrahub/computed_attribute/models.py +240 -12
  12. infrahub/computed_attribute/tasks.py +77 -441
  13. infrahub/computed_attribute/triggers.py +13 -47
  14. infrahub/config.py +43 -32
  15. infrahub/context.py +14 -0
  16. infrahub/core/account.py +4 -4
  17. infrahub/core/attribute.py +58 -58
  18. infrahub/core/branch/tasks.py +74 -22
  19. infrahub/core/changelog/diff.py +95 -36
  20. infrahub/core/changelog/models.py +217 -43
  21. infrahub/core/constants/__init__.py +28 -0
  22. infrahub/core/constants/infrahubkind.py +2 -0
  23. infrahub/core/constants/schema.py +2 -0
  24. infrahub/core/constraint/node/runner.py +9 -8
  25. infrahub/core/diff/branch_differ.py +10 -10
  26. infrahub/core/diff/enricher/cardinality_one.py +5 -0
  27. infrahub/core/diff/enricher/hierarchy.py +17 -4
  28. infrahub/core/diff/enricher/labels.py +5 -0
  29. infrahub/core/diff/enricher/path_identifier.py +4 -0
  30. infrahub/core/diff/ipam_diff_parser.py +4 -5
  31. infrahub/core/diff/model/diff.py +27 -27
  32. infrahub/core/diff/model/path.py +32 -9
  33. infrahub/core/diff/parent_node_adder.py +78 -0
  34. infrahub/core/diff/payload_builder.py +13 -2
  35. infrahub/core/diff/query/filters.py +2 -2
  36. infrahub/core/diff/query/merge.py +20 -17
  37. infrahub/core/diff/query/save.py +188 -182
  38. infrahub/core/diff/query/summary_counts_enricher.py +51 -4
  39. infrahub/core/diff/query_parser.py +4 -4
  40. infrahub/core/diff/repository/deserializer.py +8 -3
  41. infrahub/core/diff/repository/repository.py +156 -38
  42. infrahub/core/diff/tasks.py +4 -4
  43. infrahub/core/graph/__init__.py +1 -1
  44. infrahub/core/graph/index.py +3 -0
  45. infrahub/core/initialization.py +1 -10
  46. infrahub/core/ipam/constants.py +3 -4
  47. infrahub/core/ipam/reconciler.py +12 -12
  48. infrahub/core/ipam/utilization.py +10 -13
  49. infrahub/core/manager.py +36 -36
  50. infrahub/core/merge.py +7 -7
  51. infrahub/core/migrations/__init__.py +2 -3
  52. infrahub/core/migrations/graph/__init__.py +12 -3
  53. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
  54. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
  55. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
  56. infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
  57. infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
  58. infrahub/core/migrations/graph/m022_add_generate_template_attr.py +48 -0
  59. infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
  60. infrahub/core/migrations/query/attribute_add.py +2 -2
  61. infrahub/core/migrations/query/node_duplicate.py +43 -26
  62. infrahub/core/migrations/query/schema_attribute_update.py +2 -2
  63. infrahub/core/migrations/schema/models.py +19 -4
  64. infrahub/core/migrations/schema/node_remove.py +26 -12
  65. infrahub/core/migrations/schema/tasks.py +2 -2
  66. infrahub/core/migrations/shared.py +16 -16
  67. infrahub/core/models.py +15 -6
  68. infrahub/core/node/__init__.py +43 -39
  69. infrahub/core/node/base.py +2 -4
  70. infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
  71. infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
  72. infrahub/core/node/constraints/interface.py +1 -2
  73. infrahub/core/node/delete_validator.py +3 -5
  74. infrahub/core/node/ipam.py +4 -4
  75. infrahub/core/node/permissions.py +7 -7
  76. infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
  77. infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
  78. infrahub/core/node/resource_manager/number_pool.py +3 -3
  79. infrahub/core/path.py +12 -12
  80. infrahub/core/property.py +11 -11
  81. infrahub/core/protocols.py +7 -0
  82. infrahub/core/protocols_base.py +21 -21
  83. infrahub/core/query/__init__.py +33 -33
  84. infrahub/core/query/attribute.py +6 -4
  85. infrahub/core/query/diff.py +3 -3
  86. infrahub/core/query/node.py +82 -32
  87. infrahub/core/query/relationship.py +228 -40
  88. infrahub/core/query/resource_manager.py +2 -0
  89. infrahub/core/query/standard_node.py +3 -3
  90. infrahub/core/query/subquery.py +9 -9
  91. infrahub/core/registry.py +13 -15
  92. infrahub/core/relationship/constraints/count.py +3 -4
  93. infrahub/core/relationship/constraints/peer_kind.py +3 -4
  94. infrahub/core/relationship/constraints/profiles_kind.py +2 -2
  95. infrahub/core/relationship/model.py +51 -59
  96. infrahub/core/schema/attribute_schema.py +16 -8
  97. infrahub/core/schema/basenode_schema.py +105 -44
  98. infrahub/core/schema/computed_attribute.py +3 -3
  99. infrahub/core/schema/definitions/core/__init__.py +147 -0
  100. infrahub/core/schema/definitions/core/account.py +171 -0
  101. infrahub/core/schema/definitions/core/artifact.py +136 -0
  102. infrahub/core/schema/definitions/core/builtin.py +24 -0
  103. infrahub/core/schema/definitions/core/check.py +68 -0
  104. infrahub/core/schema/definitions/core/core.py +17 -0
  105. infrahub/core/schema/definitions/core/generator.py +100 -0
  106. infrahub/core/schema/definitions/core/graphql_query.py +79 -0
  107. infrahub/core/schema/definitions/core/group.py +108 -0
  108. infrahub/core/schema/definitions/core/ipam.py +193 -0
  109. infrahub/core/schema/definitions/core/lineage.py +19 -0
  110. infrahub/core/schema/definitions/core/menu.py +48 -0
  111. infrahub/core/schema/definitions/core/permission.py +163 -0
  112. infrahub/core/schema/definitions/core/profile.py +18 -0
  113. infrahub/core/schema/definitions/core/propose_change.py +97 -0
  114. infrahub/core/schema/definitions/core/propose_change_comment.py +193 -0
  115. infrahub/core/schema/definitions/core/propose_change_validator.py +328 -0
  116. infrahub/core/schema/definitions/core/repository.py +286 -0
  117. infrahub/core/schema/definitions/core/resource_pool.py +170 -0
  118. infrahub/core/schema/definitions/core/template.py +27 -0
  119. infrahub/core/schema/definitions/core/transform.py +96 -0
  120. infrahub/core/schema/definitions/core/webhook.py +134 -0
  121. infrahub/core/schema/definitions/internal.py +16 -16
  122. infrahub/core/schema/dropdown.py +3 -4
  123. infrahub/core/schema/generated/attribute_schema.py +15 -18
  124. infrahub/core/schema/generated/base_node_schema.py +12 -14
  125. infrahub/core/schema/generated/node_schema.py +3 -5
  126. infrahub/core/schema/generated/relationship_schema.py +9 -11
  127. infrahub/core/schema/generic_schema.py +2 -2
  128. infrahub/core/schema/manager.py +20 -9
  129. infrahub/core/schema/node_schema.py +4 -2
  130. infrahub/core/schema/relationship_schema.py +14 -6
  131. infrahub/core/schema/schema_branch.py +292 -144
  132. infrahub/core/schema/schema_branch_computed.py +41 -4
  133. infrahub/core/task/task.py +3 -3
  134. infrahub/core/task/user_task.py +15 -15
  135. infrahub/core/timestamp.py +3 -3
  136. infrahub/core/utils.py +20 -18
  137. infrahub/core/validators/__init__.py +1 -3
  138. infrahub/core/validators/aggregated_checker.py +2 -2
  139. infrahub/core/validators/attribute/choices.py +2 -2
  140. infrahub/core/validators/attribute/enum.py +2 -2
  141. infrahub/core/validators/attribute/kind.py +2 -2
  142. infrahub/core/validators/attribute/length.py +2 -2
  143. infrahub/core/validators/attribute/optional.py +2 -2
  144. infrahub/core/validators/attribute/regex.py +2 -2
  145. infrahub/core/validators/attribute/unique.py +2 -2
  146. infrahub/core/validators/checks_runner.py +25 -2
  147. infrahub/core/validators/determiner.py +1 -3
  148. infrahub/core/validators/interface.py +6 -2
  149. infrahub/core/validators/model.py +22 -3
  150. infrahub/core/validators/models/validate_migration.py +17 -4
  151. infrahub/core/validators/node/attribute.py +2 -2
  152. infrahub/core/validators/node/generate_profile.py +2 -2
  153. infrahub/core/validators/node/hierarchy.py +3 -5
  154. infrahub/core/validators/node/inherit_from.py +27 -5
  155. infrahub/core/validators/node/relationship.py +2 -2
  156. infrahub/core/validators/relationship/count.py +4 -4
  157. infrahub/core/validators/relationship/optional.py +2 -2
  158. infrahub/core/validators/relationship/peer.py +2 -2
  159. infrahub/core/validators/shared.py +2 -2
  160. infrahub/core/validators/tasks.py +8 -0
  161. infrahub/core/validators/uniqueness/checker.py +22 -21
  162. infrahub/core/validators/uniqueness/index.py +2 -2
  163. infrahub/core/validators/uniqueness/model.py +11 -11
  164. infrahub/database/__init__.py +27 -22
  165. infrahub/database/metrics.py +7 -1
  166. infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
  167. infrahub/dependencies/builder/diff/deserializer.py +3 -1
  168. infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
  169. infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
  170. infrahub/dependencies/component/registry.py +2 -2
  171. infrahub/events/__init__.py +25 -2
  172. infrahub/events/artifact_action.py +64 -0
  173. infrahub/events/branch_action.py +33 -22
  174. infrahub/events/generator.py +71 -0
  175. infrahub/events/group_action.py +51 -21
  176. infrahub/events/models.py +18 -19
  177. infrahub/events/node_action.py +88 -37
  178. infrahub/events/repository_action.py +5 -18
  179. infrahub/events/schema_action.py +4 -9
  180. infrahub/events/utils.py +16 -0
  181. infrahub/events/validator_action.py +55 -0
  182. infrahub/exceptions.py +32 -24
  183. infrahub/generators/models.py +2 -3
  184. infrahub/generators/tasks.py +24 -4
  185. infrahub/git/base.py +7 -7
  186. infrahub/git/integrator.py +48 -24
  187. infrahub/git/models.py +101 -9
  188. infrahub/git/repository.py +3 -3
  189. infrahub/git/tasks.py +408 -6
  190. infrahub/git/utils.py +48 -0
  191. infrahub/git/worktree.py +1 -2
  192. infrahub/git_credential/askpass.py +1 -2
  193. infrahub/graphql/analyzer.py +12 -0
  194. infrahub/graphql/app.py +13 -15
  195. infrahub/graphql/context.py +39 -0
  196. infrahub/graphql/initialization.py +3 -0
  197. infrahub/graphql/loaders/node.py +2 -12
  198. infrahub/graphql/loaders/peers.py +77 -0
  199. infrahub/graphql/loaders/shared.py +13 -0
  200. infrahub/graphql/manager.py +17 -19
  201. infrahub/graphql/mutations/artifact_definition.py +5 -5
  202. infrahub/graphql/mutations/branch.py +26 -1
  203. infrahub/graphql/mutations/computed_attribute.py +9 -5
  204. infrahub/graphql/mutations/diff.py +23 -11
  205. infrahub/graphql/mutations/diff_conflict.py +5 -0
  206. infrahub/graphql/mutations/generator.py +83 -0
  207. infrahub/graphql/mutations/graphql_query.py +5 -5
  208. infrahub/graphql/mutations/ipam.py +54 -74
  209. infrahub/graphql/mutations/main.py +195 -132
  210. infrahub/graphql/mutations/menu.py +7 -7
  211. infrahub/graphql/mutations/models.py +2 -4
  212. infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
  213. infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
  214. infrahub/graphql/mutations/node_getter/by_id.py +1 -3
  215. infrahub/graphql/mutations/node_getter/interface.py +1 -2
  216. infrahub/graphql/mutations/proposed_change.py +7 -7
  217. infrahub/graphql/mutations/relationship.py +93 -19
  218. infrahub/graphql/mutations/repository.py +8 -8
  219. infrahub/graphql/mutations/resource_manager.py +3 -3
  220. infrahub/graphql/mutations/schema.py +19 -4
  221. infrahub/graphql/mutations/webhook.py +137 -0
  222. infrahub/graphql/parser.py +4 -4
  223. infrahub/graphql/permissions.py +1 -10
  224. infrahub/graphql/queries/diff/tree.py +19 -14
  225. infrahub/graphql/queries/event.py +5 -2
  226. infrahub/graphql/queries/ipam.py +2 -2
  227. infrahub/graphql/queries/relationship.py +2 -2
  228. infrahub/graphql/queries/search.py +2 -2
  229. infrahub/graphql/resolvers/many_relationship.py +264 -0
  230. infrahub/graphql/resolvers/resolver.py +13 -110
  231. infrahub/graphql/schema.py +2 -0
  232. infrahub/graphql/subscription/graphql_query.py +2 -0
  233. infrahub/graphql/types/context.py +12 -0
  234. infrahub/graphql/types/event.py +84 -17
  235. infrahub/graphql/types/node.py +2 -2
  236. infrahub/graphql/utils.py +2 -2
  237. infrahub/groups/ancestors.py +29 -0
  238. infrahub/groups/parsers.py +107 -0
  239. infrahub/lock.py +20 -20
  240. infrahub/menu/constants.py +0 -1
  241. infrahub/menu/generator.py +9 -21
  242. infrahub/menu/menu.py +17 -38
  243. infrahub/menu/models.py +117 -16
  244. infrahub/menu/repository.py +111 -0
  245. infrahub/menu/utils.py +5 -8
  246. infrahub/message_bus/__init__.py +11 -13
  247. infrahub/message_bus/messages/__init__.py +1 -21
  248. infrahub/message_bus/messages/check_generator_run.py +3 -3
  249. infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
  250. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
  251. infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
  252. infrahub/message_bus/messages/send_echo_request.py +1 -1
  253. infrahub/message_bus/operations/__init__.py +1 -10
  254. infrahub/message_bus/operations/check/__init__.py +2 -2
  255. infrahub/message_bus/operations/check/generator.py +1 -0
  256. infrahub/message_bus/operations/event/__init__.py +2 -2
  257. infrahub/message_bus/operations/event/worker.py +0 -3
  258. infrahub/message_bus/operations/finalize/validator.py +51 -1
  259. infrahub/message_bus/operations/requests/__init__.py +0 -2
  260. infrahub/message_bus/operations/requests/generator_definition.py +21 -23
  261. infrahub/message_bus/operations/requests/proposed_change.py +14 -10
  262. infrahub/permissions/globals.py +15 -0
  263. infrahub/pools/number.py +2 -4
  264. infrahub/proposed_change/models.py +3 -0
  265. infrahub/proposed_change/tasks.py +58 -45
  266. infrahub/pytest_plugin.py +13 -10
  267. infrahub/server.py +2 -3
  268. infrahub/services/__init__.py +2 -2
  269. infrahub/services/adapters/cache/__init__.py +4 -6
  270. infrahub/services/adapters/cache/nats.py +4 -5
  271. infrahub/services/adapters/cache/redis.py +3 -7
  272. infrahub/services/adapters/event/__init__.py +1 -1
  273. infrahub/services/adapters/message_bus/__init__.py +3 -3
  274. infrahub/services/adapters/message_bus/local.py +2 -2
  275. infrahub/services/adapters/message_bus/nats.py +4 -4
  276. infrahub/services/adapters/message_bus/rabbitmq.py +4 -4
  277. infrahub/services/adapters/workflow/local.py +2 -2
  278. infrahub/services/component.py +5 -5
  279. infrahub/services/protocols.py +7 -7
  280. infrahub/services/scheduler.py +1 -3
  281. infrahub/task_manager/event.py +102 -9
  282. infrahub/task_manager/models.py +27 -7
  283. infrahub/tasks/artifact.py +7 -6
  284. infrahub/telemetry/__init__.py +0 -0
  285. infrahub/telemetry/constants.py +9 -0
  286. infrahub/telemetry/database.py +86 -0
  287. infrahub/telemetry/models.py +65 -0
  288. infrahub/telemetry/task_manager.py +77 -0
  289. infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
  290. infrahub/telemetry/utils.py +11 -0
  291. infrahub/trace.py +4 -4
  292. infrahub/transformations/tasks.py +2 -2
  293. infrahub/trigger/catalogue.py +4 -6
  294. infrahub/trigger/constants.py +0 -8
  295. infrahub/trigger/models.py +54 -5
  296. infrahub/trigger/setup.py +90 -0
  297. infrahub/trigger/tasks.py +35 -84
  298. infrahub/utils.py +11 -1
  299. infrahub/validators/__init__.py +0 -0
  300. infrahub/validators/events.py +42 -0
  301. infrahub/validators/tasks.py +41 -0
  302. infrahub/webhook/gather.py +17 -0
  303. infrahub/webhook/models.py +176 -44
  304. infrahub/webhook/tasks.py +154 -155
  305. infrahub/webhook/triggers.py +31 -7
  306. infrahub/workers/infrahub_async.py +2 -2
  307. infrahub/workers/utils.py +2 -2
  308. infrahub/workflows/catalogue.py +86 -35
  309. infrahub/workflows/initialization.py +8 -2
  310. infrahub/workflows/models.py +27 -1
  311. infrahub/workflows/utils.py +10 -1
  312. infrahub_sdk/client.py +35 -8
  313. infrahub_sdk/config.py +3 -0
  314. infrahub_sdk/context.py +13 -0
  315. infrahub_sdk/ctl/branch.py +3 -2
  316. infrahub_sdk/ctl/cli_commands.py +5 -1
  317. infrahub_sdk/ctl/utils.py +0 -16
  318. infrahub_sdk/exceptions.py +12 -0
  319. infrahub_sdk/generator.py +4 -1
  320. infrahub_sdk/graphql.py +45 -13
  321. infrahub_sdk/node.py +71 -22
  322. infrahub_sdk/protocols.py +21 -8
  323. infrahub_sdk/protocols_base.py +32 -11
  324. infrahub_sdk/query_groups.py +6 -35
  325. infrahub_sdk/schema/__init__.py +55 -26
  326. infrahub_sdk/schema/main.py +8 -0
  327. infrahub_sdk/task/__init__.py +11 -0
  328. infrahub_sdk/task/constants.py +3 -0
  329. infrahub_sdk/task/exceptions.py +25 -0
  330. infrahub_sdk/task/manager.py +551 -0
  331. infrahub_sdk/task/models.py +74 -0
  332. infrahub_sdk/testing/schemas/animal.py +9 -0
  333. infrahub_sdk/timestamp.py +142 -33
  334. infrahub_sdk/utils.py +29 -1
  335. {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +8 -6
  336. {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +349 -293
  337. {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
  338. infrahub_testcontainers/constants.py +2 -0
  339. infrahub_testcontainers/container.py +157 -12
  340. infrahub_testcontainers/docker-compose.test.yml +31 -6
  341. infrahub_testcontainers/helpers.py +18 -73
  342. infrahub_testcontainers/host.py +41 -0
  343. infrahub_testcontainers/measurements.py +93 -0
  344. infrahub_testcontainers/models.py +38 -0
  345. infrahub_testcontainers/performance_test.py +166 -0
  346. infrahub_testcontainers/plugin.py +136 -0
  347. infrahub_testcontainers/prometheus.yml +30 -0
  348. infrahub/core/schema/definitions/core.py +0 -2286
  349. infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
  350. infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
  351. infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
  352. infrahub/message_bus/messages/event_branch_create.py +0 -11
  353. infrahub/message_bus/messages/event_branch_delete.py +0 -11
  354. infrahub/message_bus/messages/event_branch_rebased.py +0 -9
  355. infrahub/message_bus/messages/event_node_mutated.py +0 -15
  356. infrahub/message_bus/messages/event_schema_update.py +0 -9
  357. infrahub/message_bus/messages/request_repository_checks.py +0 -12
  358. infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
  359. infrahub/message_bus/operations/check/repository.py +0 -293
  360. infrahub/message_bus/operations/event/node.py +0 -20
  361. infrahub/message_bus/operations/event/schema.py +0 -17
  362. infrahub/message_bus/operations/requests/repository.py +0 -133
  363. infrahub/webhook/constants.py +0 -1
  364. {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
  365. {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
infrahub_sdk/generator.py CHANGED
@@ -11,6 +11,7 @@ from .exceptions import UninitializedError
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from .client import InfrahubClient
14
+ from .context import RequestContext
14
15
  from .node import InfrahubNode
15
16
  from .store import NodeStore
16
17
 
@@ -29,6 +30,7 @@ class InfrahubGenerator:
29
30
  params: dict | None = None,
30
31
  convert_query_response: bool = False,
31
32
  logger: logging.Logger | None = None,
33
+ request_context: RequestContext | None = None,
32
34
  ) -> None:
33
35
  self.query = query
34
36
  self.branch = branch
@@ -44,6 +46,7 @@ class InfrahubGenerator:
44
46
  self.infrahub_node = infrahub_node
45
47
  self.convert_query_response = convert_query_response
46
48
  self.logger = logger if logger else logging.getLogger("infrahub.tasks")
49
+ self.request_context = request_context
47
50
 
48
51
  @property
49
52
  def store(self) -> NodeStore:
@@ -122,7 +125,7 @@ class InfrahubGenerator:
122
125
  await self._init_client.schema.all(branch=self.branch_name)
123
126
 
124
127
  for kind in data:
125
- if kind in self._init_client.schema.cache[self.branch_name]:
128
+ if kind in self._init_client.schema.cache[self.branch_name].nodes.keys():
126
129
  for result in data[kind].get("edges", []):
127
130
  node = await self.infrahub_node.from_graphql(
128
131
  client=self._init_client, branch=self.branch_name, data=result
infrahub_sdk/graphql.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from enum import Enum
3
4
  from typing import Any
4
5
 
5
6
  from pydantic import BaseModel
@@ -7,19 +8,30 @@ from pydantic import BaseModel
7
8
  VARIABLE_TYPE_MAPPING = ((str, "String!"), (int, "Int!"), (float, "Float!"), (bool, "Boolean!"))
8
9
 
9
10
 
10
- def convert_to_graphql_as_string(value: str | bool | list) -> str:
11
+ def convert_to_graphql_as_string(value: str | bool | list | BaseModel | Enum | Any, convert_enum: bool = False) -> str: # noqa: PLR0911
11
12
  if isinstance(value, str) and value.startswith("$"):
12
13
  return value
14
+ if isinstance(value, Enum):
15
+ if convert_enum:
16
+ return convert_to_graphql_as_string(value=value.value, convert_enum=True)
17
+ return value.name
13
18
  if isinstance(value, str):
14
19
  return f'"{value}"'
15
20
  if isinstance(value, bool):
16
21
  return repr(value).lower()
17
22
  if isinstance(value, list):
18
- values_as_string = [convert_to_graphql_as_string(item) for item in value]
23
+ values_as_string = [convert_to_graphql_as_string(value=item, convert_enum=convert_enum) for item in value]
19
24
  return "[" + ", ".join(values_as_string) + "]"
20
25
  if isinstance(value, BaseModel):
21
26
  data = value.model_dump()
22
- return "{ " + ", ".join(f"{key}: {convert_to_graphql_as_string(val)}" for key, val in data.items()) + " }"
27
+ return (
28
+ "{ "
29
+ + ", ".join(
30
+ f"{key}: {convert_to_graphql_as_string(value=val, convert_enum=convert_enum)}"
31
+ for key, val in data.items()
32
+ )
33
+ + " }"
34
+ )
23
35
 
24
36
  return str(value)
25
37
 
@@ -38,7 +50,7 @@ def render_variables_to_string(data: dict[str, type[str | int | float | bool]])
38
50
  return ", ".join([f"{key}: {value}" for key, value in vars_dict.items()])
39
51
 
40
52
 
41
- def render_query_block(data: dict, offset: int = 4, indentation: int = 4) -> list[str]:
53
+ def render_query_block(data: dict, offset: int = 4, indentation: int = 4, convert_enum: bool = False) -> list[str]:
42
54
  FILTERS_KEY = "@filters"
43
55
  ALIAS_KEY = "@alias"
44
56
  KEYWORDS_TO_SKIP = [FILTERS_KEY, ALIAS_KEY]
@@ -60,25 +72,36 @@ def render_query_block(data: dict, offset: int = 4, indentation: int = 4) -> lis
60
72
 
61
73
  if value.get(FILTERS_KEY):
62
74
  filters_str = ", ".join(
63
- [f"{key2}: {convert_to_graphql_as_string(value2)}" for key2, value2 in value[FILTERS_KEY].items()]
75
+ [
76
+ f"{key2}: {convert_to_graphql_as_string(value=value2, convert_enum=convert_enum)}"
77
+ for key2, value2 in value[FILTERS_KEY].items()
78
+ ]
64
79
  )
65
80
  lines.append(f"{offset_str}{key_str}({filters_str}) " + "{")
66
81
  else:
67
82
  lines.append(f"{offset_str}{key_str} " + "{")
68
83
 
69
- lines.extend(render_query_block(data=value, offset=offset + indentation, indentation=indentation))
84
+ lines.extend(
85
+ render_query_block(
86
+ data=value, offset=offset + indentation, indentation=indentation, convert_enum=convert_enum
87
+ )
88
+ )
70
89
  lines.append(offset_str + "}")
71
90
 
72
91
  return lines
73
92
 
74
93
 
75
- def render_input_block(data: dict, offset: int = 4, indentation: int = 4) -> list[str]:
94
+ def render_input_block(data: dict, offset: int = 4, indentation: int = 4, convert_enum: bool = False) -> list[str]:
76
95
  offset_str = " " * offset
77
96
  lines = []
78
97
  for key, value in data.items():
79
98
  if isinstance(value, dict):
80
99
  lines.append(f"{offset_str}{key}: " + "{")
81
- lines.extend(render_input_block(data=value, offset=offset + indentation, indentation=indentation))
100
+ lines.extend(
101
+ render_input_block(
102
+ data=value, offset=offset + indentation, indentation=indentation, convert_enum=convert_enum
103
+ )
104
+ )
82
105
  lines.append(offset_str + "}")
83
106
  elif isinstance(value, list):
84
107
  lines.append(f"{offset_str}{key}: " + "[")
@@ -90,14 +113,17 @@ def render_input_block(data: dict, offset: int = 4, indentation: int = 4) -> lis
90
113
  data=item,
91
114
  offset=offset + indentation + indentation,
92
115
  indentation=indentation,
116
+ convert_enum=convert_enum,
93
117
  )
94
118
  )
95
119
  lines.append(f"{offset_str}{' ' * indentation}" + "},")
96
120
  else:
97
- lines.append(f"{offset_str}{' ' * indentation}{convert_to_graphql_as_string(item)},")
121
+ lines.append(
122
+ f"{offset_str}{' ' * indentation}{convert_to_graphql_as_string(value=item, convert_enum=convert_enum)},"
123
+ )
98
124
  lines.append(offset_str + "]")
99
125
  else:
100
- lines.append(f"{offset_str}{key}: {convert_to_graphql_as_string(value)}")
126
+ lines.append(f"{offset_str}{key}: {convert_to_graphql_as_string(value=value, convert_enum=convert_enum)}")
101
127
  return lines
102
128
 
103
129
 
@@ -127,9 +153,13 @@ class BaseGraphQLQuery:
127
153
  class Query(BaseGraphQLQuery):
128
154
  query_type = "query"
129
155
 
130
- def render(self) -> str:
156
+ def render(self, convert_enum: bool = False) -> str:
131
157
  lines = [self.render_first_line()]
132
- lines.extend(render_query_block(data=self.query, indentation=self.indentation, offset=self.indentation))
158
+ lines.extend(
159
+ render_query_block(
160
+ data=self.query, indentation=self.indentation, offset=self.indentation, convert_enum=convert_enum
161
+ )
162
+ )
133
163
  lines.append("}")
134
164
 
135
165
  return "\n" + "\n".join(lines) + "\n"
@@ -143,7 +173,7 @@ class Mutation(BaseGraphQLQuery):
143
173
  self.mutation = mutation
144
174
  super().__init__(*args, **kwargs)
145
175
 
146
- def render(self) -> str:
176
+ def render(self, convert_enum: bool = False) -> str:
147
177
  lines = [self.render_first_line()]
148
178
  lines.append(" " * self.indentation + f"{self.mutation}(")
149
179
  lines.extend(
@@ -151,6 +181,7 @@ class Mutation(BaseGraphQLQuery):
151
181
  data=self.input_data,
152
182
  indentation=self.indentation,
153
183
  offset=self.indentation * 2,
184
+ convert_enum=convert_enum,
154
185
  )
155
186
  )
156
187
  lines.append(" " * self.indentation + "){")
@@ -159,6 +190,7 @@ class Mutation(BaseGraphQLQuery):
159
190
  data=self.query,
160
191
  indentation=self.indentation,
161
192
  offset=self.indentation * 2,
193
+ convert_enum=convert_enum,
162
194
  )
163
195
  )
164
196
  lines.append(" " * self.indentation + "}")
infrahub_sdk/node.py CHANGED
@@ -22,6 +22,7 @@ if TYPE_CHECKING:
22
22
  from typing_extensions import Self
23
23
 
24
24
  from .client import InfrahubClient, InfrahubClientSync
25
+ from .context import RequestContext
25
26
  from .schema import AttributeSchemaAPI, MainSchemaTypesAPI, RelationshipSchemaAPI
26
27
  from .types import Order
27
28
 
@@ -187,6 +188,7 @@ class RelatedNodeBase:
187
188
  if node_data:
188
189
  self._id = node_data.get("id", None)
189
190
  self._hfid = node_data.get("hfid", None)
191
+ self._kind = node_data.get("kind", None)
190
192
  self._display_label = node_data.get("display_label", None)
191
193
  self._typename = node_data.get("__typename", None)
192
194
 
@@ -255,6 +257,8 @@ class RelatedNodeBase:
255
257
  data["id"] = self.id
256
258
  elif self.hfid is not None:
257
259
  data["hfid"] = self.hfid
260
+ if self._kind is not None:
261
+ data["kind"] = self._kind
258
262
 
259
263
  for prop_name in self._properties:
260
264
  if getattr(self, prop_name) is not None:
@@ -766,6 +770,16 @@ class InfrahubNodeBase:
766
770
  Attribute(name=attr_name, schema=attr_schema, data=attr_data),
767
771
  )
768
772
 
773
+ def _get_request_context(self, request_context: RequestContext | None = None) -> dict[str, Any] | None:
774
+ if request_context:
775
+ return request_context.model_dump(exclude_none=True)
776
+
777
+ client: InfrahubClient | InfrahubClientSync | None = getattr(self, "_client", None)
778
+ if not client or not client.request_context:
779
+ return None
780
+
781
+ return client.request_context.model_dump(exclude_none=True)
782
+
769
783
  def _init_relationships(self, data: dict | None = None) -> None:
770
784
  pass
771
785
 
@@ -794,7 +808,12 @@ class InfrahubNodeBase:
794
808
  def get_raw_graphql_data(self) -> dict | None:
795
809
  return self._data
796
810
 
797
- def _generate_input_data(self, exclude_unmodified: bool = False, exclude_hfid: bool = False) -> dict[str, dict]: # noqa: C901
811
+ def _generate_input_data( # noqa: C901
812
+ self,
813
+ exclude_unmodified: bool = False,
814
+ exclude_hfid: bool = False,
815
+ request_context: RequestContext | None = None,
816
+ ) -> dict[str, dict]:
798
817
  """Generate a dictionary that represent the input data required by a mutation.
799
818
 
800
819
  Returns:
@@ -872,7 +891,15 @@ class InfrahubNodeBase:
872
891
  elif self.hfid is not None and not exclude_hfid:
873
892
  data["hfid"] = self.hfid
874
893
 
875
- return {"data": {"data": data}, "variables": variables, "mutation_variables": mutation_variables}
894
+ mutation_payload = {"data": data}
895
+ if context_data := self._get_request_context(request_context=request_context):
896
+ mutation_payload["context"] = context_data
897
+
898
+ return {
899
+ "data": mutation_payload,
900
+ "variables": variables,
901
+ "mutation_variables": mutation_variables,
902
+ }
876
903
 
877
904
  @staticmethod
878
905
  def _strip_unmodified_dict(data: dict, original_data: dict, variables: dict, item: str) -> None:
@@ -1129,8 +1156,11 @@ class InfrahubNode(InfrahubNodeBase):
1129
1156
  content = await self._client.object_store.get(identifier=artifact.storage_id.value) # type: ignore[attr-defined]
1130
1157
  return content
1131
1158
 
1132
- async def delete(self, timeout: int | None = None) -> None:
1159
+ async def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None:
1133
1160
  input_data = {"data": {"id": self.id}}
1161
+ if context_data := self._get_request_context(request_context=request_context):
1162
+ input_data["context"] = context_data
1163
+
1134
1164
  mutation_query = {"ok": None}
1135
1165
  query = Mutation(
1136
1166
  mutation=f"{self._schema.kind}Delete",
@@ -1145,12 +1175,16 @@ class InfrahubNode(InfrahubNodeBase):
1145
1175
  )
1146
1176
 
1147
1177
  async def save(
1148
- self, allow_upsert: bool = False, update_group_context: bool | None = None, timeout: int | None = None
1178
+ self,
1179
+ allow_upsert: bool = False,
1180
+ update_group_context: bool | None = None,
1181
+ timeout: int | None = None,
1182
+ request_context: RequestContext | None = None,
1149
1183
  ) -> None:
1150
1184
  if self._existing is False or allow_upsert is True:
1151
- await self.create(allow_upsert=allow_upsert, timeout=timeout)
1185
+ await self.create(allow_upsert=allow_upsert, timeout=timeout, request_context=request_context)
1152
1186
  else:
1153
- await self.update(timeout=timeout)
1187
+ await self.update(timeout=timeout, request_context=request_context)
1154
1188
 
1155
1189
  if update_group_context is None and self._client.mode == InfrahubClientMode.TRACKING:
1156
1190
  update_group_context = True
@@ -1379,15 +1413,17 @@ class InfrahubNode(InfrahubNodeBase):
1379
1413
  await related_node.fetch(timeout=timeout)
1380
1414
  setattr(self, rel_name, related_node)
1381
1415
 
1382
- async def create(self, allow_upsert: bool = False, timeout: int | None = None) -> None:
1416
+ async def create(
1417
+ self, allow_upsert: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
1418
+ ) -> None:
1383
1419
  mutation_query = self._generate_mutation_query()
1384
1420
 
1385
1421
  if allow_upsert:
1386
- input_data = self._generate_input_data(exclude_hfid=False)
1422
+ input_data = self._generate_input_data(exclude_hfid=False, request_context=request_context)
1387
1423
  mutation_name = f"{self._schema.kind}Upsert"
1388
1424
  tracker = f"mutation-{str(self._schema.kind).lower()}-upsert"
1389
1425
  else:
1390
- input_data = self._generate_input_data(exclude_hfid=True)
1426
+ input_data = self._generate_input_data(exclude_hfid=True, request_context=request_context)
1391
1427
  mutation_name = f"{self._schema.kind}Create"
1392
1428
  tracker = f"mutation-{str(self._schema.kind).lower()}-create"
1393
1429
  query = Mutation(
@@ -1405,8 +1441,10 @@ class InfrahubNode(InfrahubNodeBase):
1405
1441
  )
1406
1442
  await self._process_mutation_result(mutation_name=mutation_name, response=response, timeout=timeout)
1407
1443
 
1408
- async def update(self, do_full_update: bool = False, timeout: int | None = None) -> None:
1409
- input_data = self._generate_input_data(exclude_unmodified=not do_full_update)
1444
+ async def update(
1445
+ self, do_full_update: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
1446
+ ) -> None:
1447
+ input_data = self._generate_input_data(exclude_unmodified=not do_full_update, request_context=request_context)
1410
1448
  mutation_query = self._generate_mutation_query()
1411
1449
  mutation_name = f"{self._schema.kind}Update"
1412
1450
 
@@ -1635,18 +1673,21 @@ class InfrahubNodeSync(InfrahubNodeBase):
1635
1673
 
1636
1674
  def artifact_generate(self, name: str) -> None:
1637
1675
  self._validate_artifact_support(ARTIFACT_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE)
1638
- artifact = self._client.get(kind="CoreArtifact", definition__name__value=name, object__ids=[self.id])
1676
+ artifact = self._client.get(kind="CoreArtifact", name__value=name, object__ids=[self.id])
1639
1677
  artifact.definition.fetch() # type: ignore[attr-defined]
1640
1678
  artifact.definition.peer.generate([artifact.id]) # type: ignore[attr-defined]
1641
1679
 
1642
1680
  def artifact_fetch(self, name: str) -> str | dict[str, Any]:
1643
1681
  self._validate_artifact_support(ARTIFACT_FETCH_FEATURE_NOT_SUPPORTED_MESSAGE)
1644
- artifact = self._client.get(kind="CoreArtifact", definition__name__value=name, object__ids=[self.id])
1682
+ artifact = self._client.get(kind="CoreArtifact", name__value=name, object__ids=[self.id])
1645
1683
  content = self._client.object_store.get(identifier=artifact.storage_id.value) # type: ignore[attr-defined]
1646
1684
  return content
1647
1685
 
1648
- def delete(self, timeout: int | None = None) -> None:
1686
+ def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None:
1649
1687
  input_data = {"data": {"id": self.id}}
1688
+ if context_data := self._get_request_context(request_context=request_context):
1689
+ input_data["context"] = context_data
1690
+
1650
1691
  mutation_query = {"ok": None}
1651
1692
  query = Mutation(
1652
1693
  mutation=f"{self._schema.kind}Delete",
@@ -1661,12 +1702,16 @@ class InfrahubNodeSync(InfrahubNodeBase):
1661
1702
  )
1662
1703
 
1663
1704
  def save(
1664
- self, allow_upsert: bool = False, update_group_context: bool | None = None, timeout: int | None = None
1705
+ self,
1706
+ allow_upsert: bool = False,
1707
+ update_group_context: bool | None = None,
1708
+ timeout: int | None = None,
1709
+ request_context: RequestContext | None = None,
1665
1710
  ) -> None:
1666
1711
  if self._existing is False or allow_upsert is True:
1667
- self.create(allow_upsert=allow_upsert, timeout=timeout)
1712
+ self.create(allow_upsert=allow_upsert, timeout=timeout, request_context=request_context)
1668
1713
  else:
1669
- self.update(timeout=timeout)
1714
+ self.update(timeout=timeout, request_context=request_context)
1670
1715
 
1671
1716
  if update_group_context is None and self._client.mode == InfrahubClientMode.TRACKING:
1672
1717
  update_group_context = True
@@ -1890,15 +1935,17 @@ class InfrahubNodeSync(InfrahubNodeBase):
1890
1935
  related_node.fetch(timeout=timeout)
1891
1936
  setattr(self, rel_name, related_node)
1892
1937
 
1893
- def create(self, allow_upsert: bool = False, timeout: int | None = None) -> None:
1938
+ def create(
1939
+ self, allow_upsert: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
1940
+ ) -> None:
1894
1941
  mutation_query = self._generate_mutation_query()
1895
1942
 
1896
1943
  if allow_upsert:
1897
- input_data = self._generate_input_data(exclude_hfid=False)
1944
+ input_data = self._generate_input_data(exclude_hfid=False, request_context=request_context)
1898
1945
  mutation_name = f"{self._schema.kind}Upsert"
1899
1946
  tracker = f"mutation-{str(self._schema.kind).lower()}-upsert"
1900
1947
  else:
1901
- input_data = self._generate_input_data(exclude_hfid=True)
1948
+ input_data = self._generate_input_data(exclude_hfid=True, request_context=request_context)
1902
1949
  mutation_name = f"{self._schema.kind}Create"
1903
1950
  tracker = f"mutation-{str(self._schema.kind).lower()}-create"
1904
1951
  query = Mutation(
@@ -1917,8 +1964,10 @@ class InfrahubNodeSync(InfrahubNodeBase):
1917
1964
  )
1918
1965
  self._process_mutation_result(mutation_name=mutation_name, response=response, timeout=timeout)
1919
1966
 
1920
- def update(self, do_full_update: bool = False, timeout: int | None = None) -> None:
1921
- input_data = self._generate_input_data(exclude_unmodified=not do_full_update)
1967
+ def update(
1968
+ self, do_full_update: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
1969
+ ) -> None:
1970
+ input_data = self._generate_input_data(exclude_unmodified=not do_full_update, request_context=request_context)
1922
1971
  mutation_query = self._generate_mutation_query()
1923
1972
  mutation_name = f"{self._schema.kind}Update"
1924
1973
 
infrahub_sdk/protocols.py CHANGED
@@ -29,6 +29,7 @@ if TYPE_CHECKING:
29
29
  StringOptional,
30
30
  )
31
31
 
32
+ # pylint: disable=too-many-ancestors
32
33
 
33
34
  # ---------------------------------------------
34
35
  # ASYNC
@@ -72,7 +73,7 @@ class CoreArtifactTarget(CoreNode):
72
73
 
73
74
 
74
75
  class CoreBasePermission(CoreNode):
75
- decision: Enum
76
+ description: StringOptional
76
77
  identifier: StringOptional
77
78
  roles: RelationshipManager
78
79
 
@@ -107,7 +108,6 @@ class CoreGenericAccount(CoreNode):
107
108
  label: StringOptional
108
109
  description: StringOptional
109
110
  account_type: Enum
110
- role: Enum
111
111
  status: Dropdown
112
112
  tokens: RelationshipManager
113
113
 
@@ -154,6 +154,10 @@ class CoreMenu(CoreNode):
154
154
  children: RelationshipManager
155
155
 
156
156
 
157
+ class CoreObjectTemplate(CoreNode):
158
+ template_name: String
159
+
160
+
157
161
  class CoreProfile(CoreNode):
158
162
  profile_name: String
159
163
  profile_priority: IntegerOptional
@@ -199,6 +203,8 @@ class CoreValidator(CoreNode):
199
203
 
200
204
  class CoreWebhook(CoreNode):
201
205
  name: String
206
+ event_type: Enum
207
+ branch_scope: Dropdown
202
208
  description: StringOptional
203
209
  url: URL
204
210
  validate_certificates: BooleanOptional
@@ -221,7 +227,7 @@ class CoreAccount(LineageOwner, LineageSource, CoreGenericAccount):
221
227
  pass
222
228
 
223
229
 
224
- class CoreAccountGroup(CoreGroup):
230
+ class CoreAccountGroup(LineageOwner, LineageSource, CoreGroup):
225
231
  roles: RelationshipManager
226
232
 
227
233
 
@@ -349,8 +355,8 @@ class CoreGeneratorValidator(CoreValidator):
349
355
 
350
356
 
351
357
  class CoreGlobalPermission(CoreBasePermission):
352
- name: String
353
358
  action: Dropdown
359
+ decision: Enum
354
360
 
355
361
 
356
362
  class CoreGraphQLQuery(CoreNode):
@@ -401,6 +407,7 @@ class CoreObjectPermission(CoreBasePermission):
401
407
  namespace: String
402
408
  name: String
403
409
  action: Enum
410
+ decision: Enum
404
411
 
405
412
 
406
413
  class CoreObjectThread(CoreThread):
@@ -537,7 +544,7 @@ class CoreArtifactTargetSync(CoreNodeSync):
537
544
 
538
545
 
539
546
  class CoreBasePermissionSync(CoreNodeSync):
540
- decision: Enum
547
+ description: StringOptional
541
548
  identifier: StringOptional
542
549
  roles: RelationshipManagerSync
543
550
 
@@ -572,7 +579,6 @@ class CoreGenericAccountSync(CoreNodeSync):
572
579
  label: StringOptional
573
580
  description: StringOptional
574
581
  account_type: Enum
575
- role: Enum
576
582
  status: Dropdown
577
583
  tokens: RelationshipManagerSync
578
584
 
@@ -619,6 +625,10 @@ class CoreMenuSync(CoreNodeSync):
619
625
  children: RelationshipManagerSync
620
626
 
621
627
 
628
+ class CoreObjectTemplateSync(CoreNodeSync):
629
+ template_name: String
630
+
631
+
622
632
  class CoreProfileSync(CoreNodeSync):
623
633
  profile_name: String
624
634
  profile_priority: IntegerOptional
@@ -664,6 +674,8 @@ class CoreValidatorSync(CoreNodeSync):
664
674
 
665
675
  class CoreWebhookSync(CoreNodeSync):
666
676
  name: String
677
+ event_type: Enum
678
+ branch_scope: Dropdown
667
679
  description: StringOptional
668
680
  url: URL
669
681
  validate_certificates: BooleanOptional
@@ -686,7 +698,7 @@ class CoreAccountSync(LineageOwnerSync, LineageSourceSync, CoreGenericAccountSyn
686
698
  pass
687
699
 
688
700
 
689
- class CoreAccountGroupSync(CoreGroupSync):
701
+ class CoreAccountGroupSync(LineageOwnerSync, LineageSourceSync, CoreGroupSync):
690
702
  roles: RelationshipManagerSync
691
703
 
692
704
 
@@ -814,8 +826,8 @@ class CoreGeneratorValidatorSync(CoreValidatorSync):
814
826
 
815
827
 
816
828
  class CoreGlobalPermissionSync(CoreBasePermissionSync):
817
- name: String
818
829
  action: Dropdown
830
+ decision: Enum
819
831
 
820
832
 
821
833
  class CoreGraphQLQuerySync(CoreNodeSync):
@@ -866,6 +878,7 @@ class CoreObjectPermissionSync(CoreBasePermissionSync):
866
878
  namespace: String
867
879
  name: String
868
880
  action: Enum
881
+ decision: Enum
869
882
 
870
883
 
871
884
  class CoreObjectThreadSync(CoreThreadSync):
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
5
5
  if TYPE_CHECKING:
6
6
  import ipaddress
7
7
 
8
+ from .context import RequestContext
8
9
  from .schema import MainSchemaTypes
9
10
 
10
11
 
@@ -169,13 +170,23 @@ class CoreNodeBase(Protocol):
169
170
 
170
171
  @runtime_checkable
171
172
  class CoreNode(CoreNodeBase, Protocol):
172
- async def save(self, allow_upsert: bool = False, update_group_context: bool | None = None) -> None: ...
173
+ async def save(
174
+ self,
175
+ allow_upsert: bool = False,
176
+ update_group_context: bool | None = None,
177
+ timeout: int | None = None,
178
+ request_context: RequestContext | None = None,
179
+ ) -> None: ...
173
180
 
174
- async def delete(self) -> None: ...
181
+ async def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None: ...
175
182
 
176
- async def update(self, do_full_update: bool) -> None: ...
183
+ async def update(
184
+ self, do_full_update: bool, timeout: int | None = None, request_context: RequestContext | None = None
185
+ ) -> None: ...
177
186
 
178
- async def create(self, allow_upsert: bool = False) -> None: ...
187
+ async def create(
188
+ self, allow_upsert: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
189
+ ) -> None: ...
179
190
 
180
191
  async def add_relationships(self, relation_to_update: str, related_nodes: list[str]) -> None: ...
181
192
 
@@ -184,13 +195,23 @@ class CoreNode(CoreNodeBase, Protocol):
184
195
 
185
196
  @runtime_checkable
186
197
  class CoreNodeSync(CoreNodeBase, Protocol):
187
- def save(self, allow_upsert: bool = False, update_group_context: bool | None = None) -> None: ...
188
-
189
- def delete(self) -> None: ...
190
-
191
- def update(self, do_full_update: bool) -> None: ...
192
-
193
- def create(self, allow_upsert: bool = False) -> None: ...
198
+ def save(
199
+ self,
200
+ allow_upsert: bool = False,
201
+ update_group_context: bool | None = None,
202
+ timeout: int | None = None,
203
+ request_context: RequestContext | None = None,
204
+ ) -> None: ...
205
+
206
+ def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None: ...
207
+
208
+ def update(
209
+ self, do_full_update: bool, timeout: int | None = None, request_context: RequestContext | None = None
210
+ ) -> None: ...
211
+
212
+ def create(
213
+ self, allow_upsert: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
214
+ ) -> None: ...
194
215
 
195
216
  def add_relationships(self, relation_to_update: str, related_nodes: list[str]) -> None: ...
196
217