infrahub-server 1.2.0b1__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 (297) 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 +1 -3
  5. infrahub/artifacts/tasks.py +1 -3
  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 +239 -11
  12. infrahub/computed_attribute/tasks.py +77 -442
  13. infrahub/computed_attribute/triggers.py +11 -45
  14. infrahub/config.py +43 -32
  15. infrahub/context.py +14 -0
  16. infrahub/core/account.py +4 -4
  17. infrahub/core/attribute.py +57 -57
  18. infrahub/core/branch/tasks.py +12 -9
  19. infrahub/core/changelog/diff.py +16 -8
  20. infrahub/core/changelog/models.py +189 -26
  21. infrahub/core/constants/__init__.py +5 -1
  22. infrahub/core/constants/infrahubkind.py +2 -0
  23. infrahub/core/constraint/node/runner.py +9 -8
  24. infrahub/core/diff/branch_differ.py +10 -10
  25. infrahub/core/diff/ipam_diff_parser.py +4 -5
  26. infrahub/core/diff/model/diff.py +27 -27
  27. infrahub/core/diff/model/path.py +3 -3
  28. infrahub/core/diff/query/merge.py +20 -17
  29. infrahub/core/diff/query_parser.py +4 -4
  30. infrahub/core/graph/__init__.py +1 -1
  31. infrahub/core/initialization.py +1 -10
  32. infrahub/core/ipam/constants.py +3 -4
  33. infrahub/core/ipam/reconciler.py +12 -12
  34. infrahub/core/ipam/utilization.py +10 -13
  35. infrahub/core/manager.py +34 -34
  36. infrahub/core/merge.py +7 -7
  37. infrahub/core/migrations/__init__.py +2 -3
  38. infrahub/core/migrations/graph/__init__.py +9 -4
  39. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
  40. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
  41. infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
  42. infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
  43. infrahub/core/migrations/graph/{m020_add_generate_template_attr.py → m022_add_generate_template_attr.py} +3 -3
  44. infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
  45. infrahub/core/migrations/query/attribute_add.py +2 -2
  46. infrahub/core/migrations/query/node_duplicate.py +18 -21
  47. infrahub/core/migrations/query/schema_attribute_update.py +2 -2
  48. infrahub/core/migrations/schema/models.py +19 -4
  49. infrahub/core/migrations/schema/tasks.py +2 -2
  50. infrahub/core/migrations/shared.py +16 -16
  51. infrahub/core/models.py +15 -6
  52. infrahub/core/node/__init__.py +29 -28
  53. infrahub/core/node/base.py +2 -4
  54. infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
  55. infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
  56. infrahub/core/node/constraints/interface.py +1 -2
  57. infrahub/core/node/delete_validator.py +3 -5
  58. infrahub/core/node/ipam.py +4 -4
  59. infrahub/core/node/permissions.py +7 -7
  60. infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
  61. infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
  62. infrahub/core/node/resource_manager/number_pool.py +3 -3
  63. infrahub/core/path.py +12 -12
  64. infrahub/core/property.py +11 -11
  65. infrahub/core/protocols.py +5 -0
  66. infrahub/core/protocols_base.py +21 -21
  67. infrahub/core/query/__init__.py +33 -33
  68. infrahub/core/query/attribute.py +6 -4
  69. infrahub/core/query/diff.py +3 -3
  70. infrahub/core/query/node.py +82 -32
  71. infrahub/core/query/relationship.py +24 -24
  72. infrahub/core/query/resource_manager.py +2 -0
  73. infrahub/core/query/standard_node.py +3 -3
  74. infrahub/core/query/subquery.py +9 -9
  75. infrahub/core/registry.py +13 -15
  76. infrahub/core/relationship/constraints/count.py +3 -4
  77. infrahub/core/relationship/constraints/peer_kind.py +3 -4
  78. infrahub/core/relationship/constraints/profiles_kind.py +2 -2
  79. infrahub/core/relationship/model.py +40 -46
  80. infrahub/core/schema/attribute_schema.py +9 -9
  81. infrahub/core/schema/basenode_schema.py +93 -44
  82. infrahub/core/schema/computed_attribute.py +3 -3
  83. infrahub/core/schema/definitions/core/__init__.py +13 -19
  84. infrahub/core/schema/definitions/core/account.py +151 -148
  85. infrahub/core/schema/definitions/core/artifact.py +122 -113
  86. infrahub/core/schema/definitions/core/builtin.py +19 -16
  87. infrahub/core/schema/definitions/core/check.py +61 -53
  88. infrahub/core/schema/definitions/core/core.py +17 -0
  89. infrahub/core/schema/definitions/core/generator.py +89 -85
  90. infrahub/core/schema/definitions/core/graphql_query.py +72 -70
  91. infrahub/core/schema/definitions/core/group.py +96 -93
  92. infrahub/core/schema/definitions/core/ipam.py +176 -235
  93. infrahub/core/schema/definitions/core/lineage.py +18 -16
  94. infrahub/core/schema/definitions/core/menu.py +42 -40
  95. infrahub/core/schema/definitions/core/permission.py +144 -142
  96. infrahub/core/schema/definitions/core/profile.py +16 -27
  97. infrahub/core/schema/definitions/core/propose_change.py +88 -79
  98. infrahub/core/schema/definitions/core/propose_change_comment.py +170 -165
  99. infrahub/core/schema/definitions/core/propose_change_validator.py +290 -288
  100. infrahub/core/schema/definitions/core/repository.py +231 -225
  101. infrahub/core/schema/definitions/core/resource_pool.py +156 -166
  102. infrahub/core/schema/definitions/core/template.py +27 -12
  103. infrahub/core/schema/definitions/core/transform.py +85 -76
  104. infrahub/core/schema/definitions/core/webhook.py +127 -101
  105. infrahub/core/schema/definitions/internal.py +16 -16
  106. infrahub/core/schema/dropdown.py +3 -4
  107. infrahub/core/schema/generated/attribute_schema.py +15 -18
  108. infrahub/core/schema/generated/base_node_schema.py +12 -14
  109. infrahub/core/schema/generated/node_schema.py +3 -5
  110. infrahub/core/schema/generated/relationship_schema.py +9 -11
  111. infrahub/core/schema/generic_schema.py +2 -2
  112. infrahub/core/schema/manager.py +20 -9
  113. infrahub/core/schema/node_schema.py +4 -2
  114. infrahub/core/schema/relationship_schema.py +7 -7
  115. infrahub/core/schema/schema_branch.py +276 -138
  116. infrahub/core/schema/schema_branch_computed.py +41 -4
  117. infrahub/core/task/task.py +3 -3
  118. infrahub/core/task/user_task.py +15 -15
  119. infrahub/core/utils.py +20 -18
  120. infrahub/core/validators/__init__.py +1 -3
  121. infrahub/core/validators/aggregated_checker.py +2 -2
  122. infrahub/core/validators/attribute/choices.py +2 -2
  123. infrahub/core/validators/attribute/enum.py +2 -2
  124. infrahub/core/validators/attribute/kind.py +2 -2
  125. infrahub/core/validators/attribute/length.py +2 -2
  126. infrahub/core/validators/attribute/optional.py +2 -2
  127. infrahub/core/validators/attribute/regex.py +2 -2
  128. infrahub/core/validators/attribute/unique.py +2 -2
  129. infrahub/core/validators/checks_runner.py +25 -2
  130. infrahub/core/validators/determiner.py +1 -3
  131. infrahub/core/validators/interface.py +6 -2
  132. infrahub/core/validators/model.py +22 -3
  133. infrahub/core/validators/models/validate_migration.py +17 -4
  134. infrahub/core/validators/node/attribute.py +2 -2
  135. infrahub/core/validators/node/generate_profile.py +2 -2
  136. infrahub/core/validators/node/hierarchy.py +3 -5
  137. infrahub/core/validators/node/inherit_from.py +27 -5
  138. infrahub/core/validators/node/relationship.py +2 -2
  139. infrahub/core/validators/relationship/count.py +4 -4
  140. infrahub/core/validators/relationship/optional.py +2 -2
  141. infrahub/core/validators/relationship/peer.py +2 -2
  142. infrahub/core/validators/shared.py +2 -2
  143. infrahub/core/validators/tasks.py +8 -0
  144. infrahub/core/validators/uniqueness/checker.py +22 -21
  145. infrahub/core/validators/uniqueness/index.py +2 -2
  146. infrahub/core/validators/uniqueness/model.py +11 -11
  147. infrahub/database/__init__.py +26 -22
  148. infrahub/database/metrics.py +7 -1
  149. infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
  150. infrahub/dependencies/component/registry.py +2 -2
  151. infrahub/events/__init__.py +25 -2
  152. infrahub/events/artifact_action.py +13 -25
  153. infrahub/events/branch_action.py +26 -18
  154. infrahub/events/generator.py +71 -0
  155. infrahub/events/group_action.py +10 -24
  156. infrahub/events/models.py +10 -16
  157. infrahub/events/node_action.py +87 -32
  158. infrahub/events/repository_action.py +5 -18
  159. infrahub/events/schema_action.py +4 -9
  160. infrahub/events/utils.py +16 -0
  161. infrahub/events/validator_action.py +55 -0
  162. infrahub/exceptions.py +23 -24
  163. infrahub/generators/models.py +1 -3
  164. infrahub/git/base.py +7 -7
  165. infrahub/git/integrator.py +26 -25
  166. infrahub/git/models.py +22 -9
  167. infrahub/git/repository.py +3 -3
  168. infrahub/git/tasks.py +67 -49
  169. infrahub/git/utils.py +48 -0
  170. infrahub/git/worktree.py +1 -2
  171. infrahub/git_credential/askpass.py +1 -2
  172. infrahub/graphql/analyzer.py +12 -0
  173. infrahub/graphql/app.py +13 -15
  174. infrahub/graphql/context.py +6 -0
  175. infrahub/graphql/initialization.py +3 -0
  176. infrahub/graphql/loaders/node.py +2 -12
  177. infrahub/graphql/loaders/peers.py +77 -0
  178. infrahub/graphql/loaders/shared.py +13 -0
  179. infrahub/graphql/manager.py +13 -10
  180. infrahub/graphql/mutations/artifact_definition.py +5 -5
  181. infrahub/graphql/mutations/computed_attribute.py +4 -5
  182. infrahub/graphql/mutations/graphql_query.py +5 -5
  183. infrahub/graphql/mutations/ipam.py +50 -70
  184. infrahub/graphql/mutations/main.py +164 -141
  185. infrahub/graphql/mutations/menu.py +5 -5
  186. infrahub/graphql/mutations/models.py +2 -4
  187. infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
  188. infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
  189. infrahub/graphql/mutations/node_getter/by_id.py +1 -3
  190. infrahub/graphql/mutations/node_getter/interface.py +1 -2
  191. infrahub/graphql/mutations/proposed_change.py +7 -7
  192. infrahub/graphql/mutations/relationship.py +67 -35
  193. infrahub/graphql/mutations/repository.py +8 -8
  194. infrahub/graphql/mutations/resource_manager.py +3 -3
  195. infrahub/graphql/mutations/schema.py +4 -4
  196. infrahub/graphql/mutations/webhook.py +137 -0
  197. infrahub/graphql/parser.py +4 -4
  198. infrahub/graphql/queries/diff/tree.py +4 -4
  199. infrahub/graphql/queries/ipam.py +2 -2
  200. infrahub/graphql/queries/relationship.py +2 -2
  201. infrahub/graphql/queries/search.py +2 -2
  202. infrahub/graphql/resolvers/many_relationship.py +264 -0
  203. infrahub/graphql/resolvers/resolver.py +13 -110
  204. infrahub/graphql/subscription/graphql_query.py +2 -0
  205. infrahub/graphql/types/event.py +20 -11
  206. infrahub/graphql/types/node.py +2 -2
  207. infrahub/graphql/utils.py +2 -2
  208. infrahub/groups/ancestors.py +29 -0
  209. infrahub/groups/parsers.py +107 -0
  210. infrahub/menu/generator.py +7 -7
  211. infrahub/menu/menu.py +0 -10
  212. infrahub/menu/models.py +117 -16
  213. infrahub/menu/repository.py +111 -0
  214. infrahub/menu/utils.py +5 -8
  215. infrahub/message_bus/messages/__init__.py +1 -11
  216. infrahub/message_bus/messages/check_generator_run.py +2 -0
  217. infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
  218. infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
  219. infrahub/message_bus/operations/__init__.py +0 -2
  220. infrahub/message_bus/operations/check/generator.py +1 -0
  221. infrahub/message_bus/operations/event/__init__.py +2 -2
  222. infrahub/message_bus/operations/finalize/validator.py +51 -1
  223. infrahub/message_bus/operations/requests/generator_definition.py +19 -19
  224. infrahub/message_bus/operations/requests/proposed_change.py +3 -1
  225. infrahub/pools/number.py +2 -4
  226. infrahub/proposed_change/tasks.py +37 -28
  227. infrahub/pytest_plugin.py +13 -10
  228. infrahub/server.py +1 -2
  229. infrahub/services/adapters/event/__init__.py +1 -1
  230. infrahub/task_manager/event.py +23 -9
  231. infrahub/tasks/artifact.py +2 -4
  232. infrahub/telemetry/__init__.py +0 -0
  233. infrahub/telemetry/constants.py +9 -0
  234. infrahub/telemetry/database.py +86 -0
  235. infrahub/telemetry/models.py +65 -0
  236. infrahub/telemetry/task_manager.py +77 -0
  237. infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
  238. infrahub/telemetry/utils.py +11 -0
  239. infrahub/trace.py +4 -4
  240. infrahub/transformations/tasks.py +2 -2
  241. infrahub/trigger/catalogue.py +2 -5
  242. infrahub/trigger/constants.py +0 -8
  243. infrahub/trigger/models.py +14 -1
  244. infrahub/trigger/setup.py +90 -0
  245. infrahub/trigger/tasks.py +35 -90
  246. infrahub/utils.py +11 -1
  247. infrahub/validators/__init__.py +0 -0
  248. infrahub/validators/events.py +42 -0
  249. infrahub/validators/tasks.py +41 -0
  250. infrahub/webhook/gather.py +17 -0
  251. infrahub/webhook/models.py +22 -5
  252. infrahub/webhook/tasks.py +44 -19
  253. infrahub/webhook/triggers.py +22 -5
  254. infrahub/workers/infrahub_async.py +2 -2
  255. infrahub/workers/utils.py +2 -2
  256. infrahub/workflows/catalogue.py +28 -20
  257. infrahub/workflows/initialization.py +1 -3
  258. infrahub/workflows/models.py +1 -1
  259. infrahub/workflows/utils.py +10 -1
  260. infrahub_sdk/client.py +27 -8
  261. infrahub_sdk/config.py +3 -0
  262. infrahub_sdk/context.py +13 -0
  263. infrahub_sdk/exceptions.py +6 -0
  264. infrahub_sdk/generator.py +4 -1
  265. infrahub_sdk/graphql.py +45 -13
  266. infrahub_sdk/node.py +69 -20
  267. infrahub_sdk/protocols_base.py +32 -11
  268. infrahub_sdk/query_groups.py +6 -35
  269. infrahub_sdk/schema/__init__.py +55 -26
  270. infrahub_sdk/schema/main.py +8 -0
  271. infrahub_sdk/task/__init__.py +10 -0
  272. infrahub_sdk/task/manager.py +12 -6
  273. infrahub_sdk/testing/schemas/animal.py +9 -0
  274. infrahub_sdk/timestamp.py +12 -4
  275. {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +3 -2
  276. {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +289 -260
  277. {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
  278. infrahub_testcontainers/constants.py +2 -0
  279. infrahub_testcontainers/container.py +157 -12
  280. infrahub_testcontainers/docker-compose.test.yml +31 -6
  281. infrahub_testcontainers/helpers.py +18 -73
  282. infrahub_testcontainers/host.py +41 -0
  283. infrahub_testcontainers/measurements.py +93 -0
  284. infrahub_testcontainers/models.py +38 -0
  285. infrahub_testcontainers/performance_test.py +166 -0
  286. infrahub_testcontainers/plugin.py +136 -0
  287. infrahub_testcontainers/prometheus.yml +30 -0
  288. infrahub/message_bus/messages/event_branch_create.py +0 -11
  289. infrahub/message_bus/messages/event_branch_delete.py +0 -11
  290. infrahub/message_bus/messages/event_branch_rebased.py +0 -9
  291. infrahub/message_bus/messages/event_node_mutated.py +0 -15
  292. infrahub/message_bus/messages/event_schema_update.py +0 -9
  293. infrahub/message_bus/operations/event/node.py +0 -20
  294. infrahub/message_bus/operations/event/schema.py +0 -17
  295. infrahub/webhook/constants.py +0 -1
  296. {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
  297. {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import inspect
4
4
  from collections import defaultdict
5
5
  from dataclasses import dataclass
6
- from typing import TYPE_CHECKING, Generator, Optional, Union
6
+ from typing import TYPE_CHECKING, Generator
7
7
 
8
8
  from infrahub_sdk.uuidt import UUIDT
9
9
 
@@ -79,24 +79,24 @@ class RelationshipPeerData:
79
79
  peer_kind: str
80
80
  """Kind of the Peer Node."""
81
81
 
82
- properties: dict[str, Union[FlagPropertyData, NodePropertyData]]
82
+ properties: dict[str, FlagPropertyData | NodePropertyData]
83
83
  """UUID of the Relationship Node."""
84
84
 
85
- rel_node_id: Optional[UUID] = None
85
+ rel_node_id: UUID | None = None
86
86
  """UUID of the Relationship Node."""
87
87
 
88
- peer_db_id: Optional[str] = None
88
+ peer_db_id: str | None = None
89
89
  """Internal DB ID of the Peer Node."""
90
90
 
91
- rel_node_db_id: Optional[str] = None
91
+ rel_node_db_id: str | None = None
92
92
  """Internal DB ID of the Relationship Node."""
93
93
 
94
- rels: Optional[list[RelData]] = None
94
+ rels: list[RelData] | None = None
95
95
  """Both relationships pointing at this Relationship Node."""
96
96
 
97
- updated_at: Optional[str] = None
97
+ updated_at: str | None = None
98
98
 
99
- def rel_ids_per_branch(self) -> dict[str, list[Union[str, int]]]:
99
+ def rel_ids_per_branch(self) -> dict[str, list[str | int]]:
100
100
  response = defaultdict(list)
101
101
  for rel in self.rels:
102
102
  response[rel.branch].append(rel.db_id)
@@ -137,15 +137,15 @@ class FullRelationshipIdentifier:
137
137
  class RelationshipQuery(Query):
138
138
  def __init__(
139
139
  self,
140
- rel: Union[type[Relationship], Relationship] | None = None,
141
- rel_type: Optional[str] = None,
140
+ rel: type[Relationship] | Relationship | None = None,
141
+ rel_type: str | None = None,
142
142
  source: Node | None = None,
143
143
  source_id: UUID | None = None,
144
144
  destination: Node | None = None,
145
145
  destination_id: UUID | None = None,
146
146
  schema: RelationshipSchema | None = None,
147
147
  branch: Branch | None = None,
148
- at: Union[Timestamp, str] | None = None,
148
+ at: Timestamp | str | None = None,
149
149
  **kwargs,
150
150
  ):
151
151
  if not source and not source_id:
@@ -185,7 +185,7 @@ class RelationshipQuery(Query):
185
185
 
186
186
  super().__init__(**kwargs)
187
187
 
188
- def get_relationship_properties_dict(self, status: RelationshipStatus) -> dict[str, Optional[str]]:
188
+ def get_relationship_properties_dict(self, status: RelationshipStatus) -> dict[str, str | None]:
189
189
  rel_prop_dict = {
190
190
  "branch": self.branch.name,
191
191
  "branch_level": self.branch.hierarchy_level,
@@ -523,15 +523,15 @@ class RelationshipGetPeerQuery(Query):
523
523
 
524
524
  def __init__(
525
525
  self,
526
- filters: Optional[dict] = None,
527
- source: Optional[Node] = None,
528
- source_ids: Optional[list[str]] = None,
529
- source_kind: Optional[str] = None,
530
- rel: Optional[Union[type[Relationship], Relationship]] = None,
531
- rel_type: Optional[str] = None,
532
- schema: Optional[RelationshipSchema] = None,
533
- branch: Optional[Branch] = None,
534
- at: Optional[Union[Timestamp, str]] = None,
526
+ filters: dict | None = None,
527
+ source: Node | None = None,
528
+ source_ids: list[str] | None = None,
529
+ source_kind: str | None = None,
530
+ rel: type[Relationship] | Relationship | None = None,
531
+ rel_type: str | None = None,
532
+ schema: RelationshipSchema | None = None,
533
+ branch: Branch | None = None,
534
+ at: Timestamp | str | None = None,
535
535
  **kwargs,
536
536
  ):
537
537
  if not source and not source_ids:
@@ -831,9 +831,9 @@ class RelationshipGetByIdentifierQuery(Query):
831
831
 
832
832
  def __init__(
833
833
  self,
834
- identifiers: Optional[list[str]] = None,
835
- full_identifiers: Optional[list[FullRelationshipIdentifier]] = None,
836
- excluded_namespaces: Optional[list[str]] = None,
834
+ identifiers: list[str] | None = None,
835
+ full_identifiers: list[FullRelationshipIdentifier] | None = None,
836
+ excluded_namespaces: list[str] | None = None,
837
837
  **kwargs,
838
838
  ) -> None:
839
839
  if (not identifiers and not full_identifiers) or (identifiers and full_identifiers):
@@ -276,6 +276,8 @@ class NumberPoolSetReserved(Query):
276
276
  query = """
277
277
  MATCH (pool:%(number_pool)s { uuid: $pool_id })
278
278
  MERGE (value:AttributeValue { value: $reserved, is_default: false })
279
+ WITH value, pool
280
+ LIMIT 1
279
281
  CREATE (pool)-[rel:IS_RESERVED $rel_prop]->(value)
280
282
  """ % {"number_pool": InfrahubKind.NUMBERPOOL}
281
283
 
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Optional
3
+ from typing import TYPE_CHECKING, Any
4
4
 
5
5
  from infrahub.core.query import Query, QueryType
6
6
 
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
11
11
 
12
12
  class StandardNodeQuery(Query):
13
13
  def __init__(
14
- self, node: StandardNode = None, node_id: Optional[str] = None, node_db_id: Optional[int] = None, **kwargs: Any
14
+ self, node: StandardNode = None, node_id: str | None = None, node_db_id: int | None = None, **kwargs: Any
15
15
  ):
16
16
  self.node = node
17
17
  self.node_id = node_id
@@ -120,7 +120,7 @@ class StandardNodeGetListQuery(Query):
120
120
  type = QueryType.READ
121
121
 
122
122
  def __init__(
123
- self, node_class: StandardNode, ids: Optional[list[str]] = None, node_name: Optional[str] = None, **kwargs: Any
123
+ self, node_class: StandardNode, ids: list[str] | None = None, node_name: str | None = None, **kwargs: Any
124
124
  ) -> None:
125
125
  self.ids = ids
126
126
  self.node_name = node_name
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Optional, Union
3
+ from typing import TYPE_CHECKING, Any
4
4
 
5
5
  from infrahub.core.query import QueryNode
6
6
 
@@ -17,16 +17,16 @@ async def build_subquery_filter(
17
17
  filter_name: str,
18
18
  filter_value: Any,
19
19
  branch_filter: str,
20
- field: Optional[Union[AttributeSchema, RelationshipSchema]] = None,
20
+ field: AttributeSchema | RelationshipSchema | None = None,
21
21
  node_alias: str = "n",
22
- name: Optional[str] = None,
22
+ name: str | None = None,
23
23
  branch: Branch = None,
24
24
  subquery_idx: int = 1,
25
25
  partial_match: bool = False,
26
26
  optional_match: bool = False,
27
27
  result_prefix: str = "filter",
28
28
  support_profiles: bool = False,
29
- extra_tail_properties: Optional[dict[str, str]] = None,
29
+ extra_tail_properties: dict[str, str] | None = None,
30
30
  ) -> tuple[str, dict[str, Any], str]:
31
31
  support_profiles = (
32
32
  support_profiles and field and field.is_attribute and filter_name in ("value", "values", "isnull")
@@ -102,16 +102,16 @@ async def build_subquery_filter(
102
102
 
103
103
  async def build_subquery_order(
104
104
  db: InfrahubDatabase,
105
- field: Union[AttributeSchema, RelationshipSchema],
105
+ field: AttributeSchema | RelationshipSchema,
106
106
  order_by: str,
107
107
  branch_filter: str,
108
108
  node_alias: str = "n",
109
- name: Optional[str] = None,
109
+ name: str | None = None,
110
110
  branch: Branch = None,
111
111
  subquery_idx: int = 1,
112
- result_prefix: Optional[str] = None,
112
+ result_prefix: str | None = None,
113
113
  support_profiles: bool = False,
114
- extra_tail_properties: Optional[dict[str, str]] = None,
114
+ extra_tail_properties: dict[str, str] | None = None,
115
115
  ) -> tuple[str, dict[str, Any], str]:
116
116
  support_profiles = support_profiles and field and field.is_attribute and order_by in ("value", "values")
117
117
  params = {}
@@ -143,7 +143,7 @@ async def build_subquery_order(
143
143
  branch_level_str = "reduce(br_lvl = 0, r in relationships(path) | br_lvl + r.branch_level)"
144
144
  froms_str = db.render_list_comprehension(items="relationships(path)", item_name="from")
145
145
  to_return_parts = {f"last.{order_by if order_by != 'values' and '__' not in order_by else 'value'}": prefix}
146
- with_parts: dict[str, Optional[str]] = {
146
+ with_parts: dict[str, str | None] = {
147
147
  "last": None,
148
148
  }
149
149
  if extra_tail_properties:
infrahub/core/registry.py CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from collections import defaultdict
4
4
  from dataclasses import dataclass, field
5
- from typing import TYPE_CHECKING, Optional, Union
5
+ from typing import TYPE_CHECKING
6
6
 
7
7
  from infrahub import lock
8
8
  from infrahub.core.constants import GLOBAL_BRANCH_NAME
@@ -26,21 +26,21 @@ if TYPE_CHECKING:
26
26
 
27
27
  @dataclass
28
28
  class Registry:
29
- id: Optional[str] = None
29
+ id: str | None = None
30
30
  attribute: dict[str, type[BaseAttribute]] = field(default_factory=dict)
31
31
  branch: dict[str, Branch] = field(default_factory=dict)
32
32
  node: dict = field(default_factory=dict)
33
- _default_branch: Optional[str] = None
34
- _default_ipnamespace: Optional[str] = None
35
- _schema: Optional[SchemaManager] = None
33
+ _default_branch: str | None = None
34
+ _default_ipnamespace: str | None = None
35
+ _schema: SchemaManager | None = None
36
36
  default_graphql_type: dict[str, InfrahubObject | type[BaseAttribute]] = field(default_factory=dict)
37
37
  graphql_type: dict = field(default_factory=lambda: defaultdict(dict))
38
38
  data_type: dict[str, type[InfrahubDataType]] = field(default_factory=dict)
39
39
  input_type: dict[str, type[BaseAttributeCreate | BaseAttributeUpdate]] = field(default_factory=dict)
40
40
  attr_group: dict = field(default_factory=dict)
41
- _branch_object: Optional[type[Branch]] = None
42
- _manager: Optional[type[NodeManager]] = None
43
- _storage: Optional[InfrahubObjectStorage] = None
41
+ _branch_object: type[Branch] | None = None
42
+ _manager: type[NodeManager] | None = None
43
+ _storage: InfrahubObjectStorage | None = None
44
44
  permission_backends: list[PermissionBackend] = field(default_factory=list)
45
45
 
46
46
  @property
@@ -113,7 +113,7 @@ class Registry:
113
113
  return True
114
114
  return False
115
115
 
116
- def get_node_schema(self, name: str, branch: Optional[Union[Branch, str]] = None) -> NodeSchema:
116
+ def get_node_schema(self, name: str, branch: Branch | str | None = None) -> NodeSchema:
117
117
  return self.schema.get_node_schema(name=name, branch=branch)
118
118
 
119
119
  def get_data_type(self, name: str) -> type[InfrahubDataType]:
@@ -121,9 +121,7 @@ class Registry:
121
121
  raise DataTypeNotFoundError(name=name)
122
122
  return self.data_type[name]
123
123
 
124
- def get_full_schema(
125
- self, branch: Optional[Union[Branch, str]] = None, duplicate: bool = True
126
- ) -> dict[str, MainSchemaTypes]:
124
+ def get_full_schema(self, branch: Branch | str | None = None, duplicate: bool = True) -> dict[str, MainSchemaTypes]:
127
125
  """Return all the nodes in the schema for a given branch."""
128
126
  return self.schema.get_full(branch=branch, duplicate=duplicate)
129
127
 
@@ -137,7 +135,7 @@ class Registry:
137
135
  self.attribute = {}
138
136
  self.input_type = {}
139
137
 
140
- def get_branch_from_registry(self, branch: Optional[Union[Branch, str]] = None) -> Branch:
138
+ def get_branch_from_registry(self, branch: Branch | str | None = None) -> Branch:
141
139
  """Return a branch object from the registry based on its name.
142
140
 
143
141
  Args:
@@ -168,8 +166,8 @@ class Registry:
168
166
  async def get_branch(
169
167
  self,
170
168
  db: InfrahubDatabase,
171
- session: Optional[AsyncSession] = None,
172
- branch: Optional[Union[Branch, str]] = None,
169
+ session: AsyncSession | None = None,
170
+ branch: Branch | str | None = None,
173
171
  ) -> Branch:
174
172
  """Return a branch object based on its name.
175
173
 
@@ -1,5 +1,4 @@
1
1
  from dataclasses import dataclass
2
- from typing import Optional
3
2
 
4
3
  from infrahub.core import registry
5
4
  from infrahub.core.branch import Branch
@@ -17,12 +16,12 @@ from .interface import RelationshipManagerConstraintInterface
17
16
  class NodeToValidate:
18
17
  uuid: str
19
18
  cardinality: RelationshipCardinality
20
- min_count: Optional[int] = None
21
- max_count: Optional[int] = None
19
+ min_count: int | None = None
20
+ max_count: int | None = None
22
21
 
23
22
 
24
23
  class RelationshipCountConstraint(RelationshipManagerConstraintInterface):
25
- def __init__(self, db: InfrahubDatabase, branch: Optional[Branch] = None):
24
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
26
25
  self.db = db
27
26
  self.branch = branch
28
27
 
@@ -1,5 +1,4 @@
1
1
  from dataclasses import dataclass
2
- from typing import Optional
3
2
 
4
3
  from infrahub.core import registry
5
4
  from infrahub.core.branch import Branch
@@ -18,12 +17,12 @@ from .interface import RelationshipManagerConstraintInterface
18
17
  class NodeToValidate:
19
18
  uuid: str
20
19
  cardinality: RelationshipCardinality
21
- min_count: Optional[int] = None
22
- max_count: Optional[int] = None
20
+ min_count: int | None = None
21
+ max_count: int | None = None
23
22
 
24
23
 
25
24
  class RelationshipPeerKindConstraint(RelationshipManagerConstraintInterface):
26
- def __init__(self, db: InfrahubDatabase, branch: Optional[Branch] = None):
25
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
27
26
  self.db = db
28
27
  self.branch = branch
29
28
 
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Optional
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from infrahub.core import registry
6
6
  from infrahub.core.schema import NodeSchema
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
18
18
 
19
19
 
20
20
  class RelationshipProfilesKindConstraint(RelationshipManagerConstraintInterface):
21
- def __init__(self, db: InfrahubDatabase, branch: Optional[Branch] = None):
21
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
22
22
  self.db = db
23
23
  self.branch = branch
24
24
  self.schema_branch = registry.schema.get_schema_branch(branch.name if branch else registry.default_branch)
@@ -11,10 +11,8 @@ from typing import (
11
11
  Iterator,
12
12
  Literal,
13
13
  Mapping,
14
- Optional,
15
14
  Sequence,
16
15
  TypeVar,
17
- Union,
18
16
  overload,
19
17
  )
20
18
 
@@ -65,14 +63,14 @@ class RelationshipCreateData(BaseModel):
65
63
  uuid: str
66
64
  name: str
67
65
  destination_id: str
68
- branch: Optional[str] = None
66
+ branch: str | None = None
69
67
  branch_level: int
70
- branch_support: Optional[str] = None
68
+ branch_support: str | None = None
71
69
  direction: str
72
70
  status: str
73
71
  is_protected: bool
74
72
  is_visible: bool
75
- hierarchical: Optional[str] = None
73
+ hierarchical: str | None = None
76
74
  source_prop: list[NodePropertyData] = Field(default_factory=list)
77
75
  owner_prop: list[NodePropertyData] = Field(default_factory=list)
78
76
 
@@ -92,9 +90,9 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
92
90
  self,
93
91
  schema: RelationshipSchema,
94
92
  branch: Branch,
95
- at: Optional[Timestamp] = None,
96
- node: Optional[Node] = None,
97
- node_id: Optional[str] = None,
93
+ at: Timestamp | None = None,
94
+ node: Node | None = None,
95
+ node_id: str | None = None,
98
96
  **kwargs: Any,
99
97
  ) -> None:
100
98
  if not node and not node_id:
@@ -107,18 +105,18 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
107
105
  self.at = Timestamp(at)
108
106
 
109
107
  self._node = node
110
- self._node_id: Optional[str] = node_id
108
+ self._node_id: str | None = node_id
111
109
 
112
- self.id: Optional[UUID] = None
113
- self.db_id: Optional[str] = None
114
- self.updated_at: Optional[Timestamp] = None
110
+ self.id: UUID | None = None
111
+ self.db_id: str | None = None
112
+ self.updated_at: Timestamp | None = None
115
113
 
116
- self._peer: Optional[Union[Node, str]] = None
117
- self.peer_id: Optional[str] = None
118
- self.peer_hfid: Optional[list[str]] = None
119
- self.data: Optional[Union[dict, RelationshipPeerData, str]] = None
114
+ self._peer: Node | str | None = None
115
+ self.peer_id: str | None = None
116
+ self.peer_hfid: list[str] | None = None
117
+ self.data: dict | RelationshipPeerData | str | None = None
120
118
 
121
- self.from_pool: Optional[dict[str, Any]] = None
119
+ self.from_pool: dict[str, Any] | None = None
122
120
 
123
121
  self._init_node_property_mixin(kwargs=kwargs)
124
122
  self._init_flag_property_mixin(kwargs=kwargs)
@@ -166,7 +164,7 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
166
164
  return registry.get_global_branch()
167
165
  return self.branch
168
166
 
169
- async def _process_data(self, data: Union[dict, RelationshipPeerData, str]) -> None:
167
+ async def _process_data(self, data: dict | RelationshipPeerData | str) -> None:
170
168
  self.data = data
171
169
 
172
170
  if isinstance(data, RelationshipPeerData):
@@ -203,7 +201,7 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
203
201
  async def new(
204
202
  self,
205
203
  db: InfrahubDatabase, # noqa: ARG002
206
- data: Union[dict, RelationshipPeerData, Any] = None,
204
+ data: dict | RelationshipPeerData | Any = None,
207
205
  **kwargs: Any, # noqa: ARG002
208
206
  ) -> Relationship:
209
207
  await self._process_data(data=data)
@@ -213,10 +211,10 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
213
211
  async def load(
214
212
  self,
215
213
  db: InfrahubDatabase, # noqa: ARG002
216
- id: Optional[UUID] = None,
217
- db_id: Optional[str] = None,
218
- updated_at: Optional[Union[Timestamp, str]] = None,
219
- data: Union[dict, RelationshipPeerData, Any] = None,
214
+ id: UUID | None = None,
215
+ db_id: str | None = None,
216
+ updated_at: Timestamp | str | None = None,
217
+ data: dict | RelationshipPeerData | Any = None,
220
218
  ) -> Self:
221
219
  hash_before = hash(self)
222
220
 
@@ -252,7 +250,7 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
252
250
  self._node_id = self._node.id
253
251
  return node
254
252
 
255
- async def set_peer(self, value: Union[str, Node]) -> None:
253
+ async def set_peer(self, value: str | Node) -> None:
256
254
  if isinstance(value, str):
257
255
  self.peer_id = value
258
256
  else:
@@ -337,7 +335,7 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
337
335
 
338
336
  return different_properties
339
337
 
340
- async def _create(self, db: InfrahubDatabase, at: Optional[Timestamp] = None) -> None:
338
+ async def _create(self, db: InfrahubDatabase, at: Timestamp | None = None) -> None:
341
339
  """Add a relationship with another object by creating a new relationship node."""
342
340
 
343
341
  create_at = Timestamp(at)
@@ -364,7 +362,7 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
364
362
  db: InfrahubDatabase,
365
363
  properties_to_update: list[str],
366
364
  data: RelationshipPeerData,
367
- at: Optional[Timestamp] = None,
365
+ at: Timestamp | None = None,
368
366
  ) -> None:
369
367
  """Update the properties of an existing relationship."""
370
368
 
@@ -392,7 +390,7 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
392
390
  )
393
391
  await query.execute(db=db)
394
392
 
395
- async def delete(self, db: InfrahubDatabase, at: Optional[Timestamp] = None) -> None:
393
+ async def delete(self, db: InfrahubDatabase, at: Timestamp | None = None) -> None:
396
394
  delete_at = Timestamp(at)
397
395
 
398
396
  node = await self.get_node(db=db)
@@ -476,7 +474,7 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
476
474
  await self.set_peer(value=assigned_peer)
477
475
  self.set_source(value=pool.id)
478
476
 
479
- async def save(self, db: InfrahubDatabase, at: Optional[Timestamp] = None) -> Self:
477
+ async def save(self, db: InfrahubDatabase, at: Timestamp | None = None) -> Self:
480
478
  """Create or Update the Relationship in the database."""
481
479
 
482
480
  save_at = Timestamp(at)
@@ -487,9 +485,7 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
487
485
 
488
486
  return self
489
487
 
490
- async def to_graphql(
491
- self, fields: Optional[dict], db: InfrahubDatabase, related_node_ids: Optional[set] = None
492
- ) -> dict:
488
+ async def to_graphql(self, fields: dict | None, db: InfrahubDatabase, related_node_ids: set | None = None) -> dict:
493
489
  """Generate GraphQL Payload for the associated Peer."""
494
490
 
495
491
  if not fields:
@@ -726,7 +722,7 @@ class RelationshipManager:
726
722
  min_count=0 if self.schema.optional else self.schema.min_count,
727
723
  max_count=self.schema.max_count,
728
724
  )
729
- self._relationship_id_details: Optional[RelationshipUpdateDetails] = None
725
+ self._relationship_id_details: RelationshipUpdateDetails | None = None
730
726
  self.has_fetched_relationships: bool = False
731
727
  self.lock = asyncio.Lock()
732
728
 
@@ -738,7 +734,7 @@ class RelationshipManager:
738
734
  branch: Branch,
739
735
  at: Timestamp,
740
736
  node: Node,
741
- data: Optional[Union[dict, list, str]] = None,
737
+ data: dict | list | str | None = None,
742
738
  ) -> RelationshipManager:
743
739
  rm = cls(schema=schema, branch=branch, at=at, node=node)
744
740
 
@@ -904,7 +900,7 @@ class RelationshipManager:
904
900
  async def fetch_relationship_ids(
905
901
  self,
906
902
  db: InfrahubDatabase,
907
- at: Optional[Timestamp] = None,
903
+ at: Timestamp | None = None,
908
904
  branch_agnostic: bool = False,
909
905
  force_refresh: bool = True,
910
906
  ) -> RelationshipUpdateDetails:
@@ -946,7 +942,7 @@ class RelationshipManager:
946
942
  async def _fetch_relationships(
947
943
  self,
948
944
  db: InfrahubDatabase,
949
- at: Optional[Timestamp] = None,
945
+ at: Timestamp | None = None,
950
946
  branch_agnostic: bool = False,
951
947
  force_refresh: bool = True,
952
948
  ) -> None:
@@ -1008,12 +1004,10 @@ class RelationshipManager:
1008
1004
 
1009
1005
  return self._relationships.as_list()
1010
1006
 
1011
- async def update(
1012
- self, data: Union[list[Union[str, Node]], dict[str, Any], str, Node, None], db: InfrahubDatabase
1013
- ) -> bool:
1007
+ async def update(self, data: list[str | Node] | dict[str, Any] | str | Node | None, db: InfrahubDatabase) -> bool:
1014
1008
  """Replace and Update the list of relationships with this one."""
1015
1009
  if not isinstance(data, list):
1016
- list_data: Sequence[Union[str, Node, dict[str, Any], None]] = [data]
1010
+ list_data: Sequence[str | Node | dict[str, Any] | None] = [data]
1017
1011
  else:
1018
1012
  list_data = data
1019
1013
 
@@ -1071,7 +1065,7 @@ class RelationshipManager:
1071
1065
 
1072
1066
  return changed
1073
1067
 
1074
- async def add(self, data: Union[dict[str, Any], Node], db: InfrahubDatabase) -> bool:
1068
+ async def add(self, data: dict[str, Any] | Node, db: InfrahubDatabase) -> bool:
1075
1069
  """Add a new relationship to the list of existing ones, avoid duplication."""
1076
1070
  if not isinstance(data, self.rel_class | dict) and not hasattr(data, "_schema"):
1077
1071
  raise ValidationError({self.name: f"Invalid data provided to form a relationship {data}"})
@@ -1102,7 +1096,7 @@ class RelationshipManager:
1102
1096
 
1103
1097
  async def remove_locally(
1104
1098
  self,
1105
- peer_id: Union[str, UUID],
1099
+ peer_id: str | UUID,
1106
1100
  db: InfrahubDatabase,
1107
1101
  ) -> bool:
1108
1102
  """Remove a peer id from the local relationships list"""
@@ -1120,7 +1114,7 @@ class RelationshipManager:
1120
1114
  self,
1121
1115
  db: InfrahubDatabase,
1122
1116
  peer_data: RelationshipPeerData,
1123
- at: Optional[Timestamp] = None,
1117
+ at: Timestamp | None = None,
1124
1118
  ) -> None:
1125
1119
  remove_at = Timestamp(at)
1126
1120
  branch = self.get_branch_based_on_support_type()
@@ -1148,7 +1142,7 @@ class RelationshipManager:
1148
1142
  await query.execute(db=db)
1149
1143
 
1150
1144
  async def save(
1151
- self, db: InfrahubDatabase, at: Optional[Timestamp] = None
1145
+ self, db: InfrahubDatabase, at: Timestamp | None = None
1152
1146
  ) -> RelationshipCardinalityManyChangelog | RelationshipCardinalityOneChangelog:
1153
1147
  """Create or Update the Relationship in the database."""
1154
1148
 
@@ -1194,7 +1188,7 @@ class RelationshipManager:
1194
1188
  return relationship_mapper.changelog
1195
1189
 
1196
1190
  async def delete(
1197
- self, db: InfrahubDatabase, at: Optional[Timestamp] = None
1191
+ self, db: InfrahubDatabase, at: Timestamp | None = None
1198
1192
  ) -> RelationshipCardinalityManyChangelog | RelationshipCardinalityOneChangelog:
1199
1193
  """Delete all the relationships."""
1200
1194
 
@@ -1212,8 +1206,8 @@ class RelationshipManager:
1212
1206
  return relationship_mapper.changelog
1213
1207
 
1214
1208
  async def to_graphql(
1215
- self, db: InfrahubDatabase, fields: Optional[dict] = None, related_node_ids: Optional[set] = None
1216
- ) -> Union[dict, None]:
1209
+ self, db: InfrahubDatabase, fields: dict | None = None, related_node_ids: set | None = None
1210
+ ) -> dict | None:
1217
1211
  # NOTE Need to investigate when and why we are passing the peer directly here, how do we account for many relationship
1218
1212
  if self.schema.cardinality == "many":
1219
1213
  raise TypeError("to_graphql is not available for relationship with multiple cardinality")
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import enum
4
4
  from enum import Enum
5
- from typing import TYPE_CHECKING, Any, Optional, Union
5
+ from typing import TYPE_CHECKING, Any
6
6
 
7
7
  from pydantic import field_validator, model_validator
8
8
 
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
23
23
 
24
24
  class AttributeSchema(GeneratedAttributeSchema):
25
25
  _sort_by: list[str] = ["name"]
26
- _enum_class: Optional[type[enum.Enum]] = None
26
+ _enum_class: type[enum.Enum] | None = None
27
27
 
28
28
  @property
29
29
  def is_attribute(self) -> bool:
@@ -38,7 +38,7 @@ class AttributeSchema(GeneratedAttributeSchema):
38
38
  return bool(self.deprecation)
39
39
 
40
40
  def to_dict(self) -> dict:
41
- data = self.model_dump(exclude_unset=True, exclude_none=True, exclude_defaults=True)
41
+ data = self.model_dump(exclude_unset=True, exclude_none=True)
42
42
  for field_name, value in data.items():
43
43
  if isinstance(value, Enum):
44
44
  data[field_name] = value.value
@@ -56,7 +56,7 @@ class AttributeSchema(GeneratedAttributeSchema):
56
56
  def validate_dropdown_choices(cls, values: dict[str, Any]) -> dict[str, Any]:
57
57
  """Validate that choices are defined for a dropdown but not for other kinds."""
58
58
  if values.get("kind") != "Dropdown" and values.get("choices"):
59
- raise ValueError(f"Can only specify 'choices' for kind=Dropdown: {values['kind'] }")
59
+ raise ValueError(f"Can only specify 'choices' for kind=Dropdown: {values['kind']}")
60
60
 
61
61
  if values.get("kind") == "Dropdown" and not values.get("choices"):
62
62
  raise ValueError("The property 'choices' is required for kind=Dropdown")
@@ -82,7 +82,7 @@ class AttributeSchema(GeneratedAttributeSchema):
82
82
  self._enum_class = generate_python_enum(name=f"{self.name.title()}Enum", options=self.enum)
83
83
  return self._enum_class
84
84
 
85
- def convert_value_to_enum(self, value: Any) -> Optional[enum.Enum]:
85
+ def convert_value_to_enum(self, value: Any) -> enum.Enum | None:
86
86
  if isinstance(value, enum.Enum) or value is None:
87
87
  return value
88
88
  enum_class = self.get_enum_class()
@@ -121,11 +121,11 @@ class AttributeSchema(GeneratedAttributeSchema):
121
121
  self,
122
122
  name: str,
123
123
  filter_name: str,
124
- branch: Optional[Branch] = None,
125
- filter_value: Optional[Union[str, int, bool, list]] = None,
124
+ branch: Branch | None = None,
125
+ filter_value: str | int | bool | list | None = None,
126
126
  include_match: bool = True,
127
- param_prefix: Optional[str] = None,
128
- db: Optional[InfrahubDatabase] = None,
127
+ param_prefix: str | None = None,
128
+ db: InfrahubDatabase | None = None,
129
129
  partial_match: bool = False,
130
130
  support_profiles: bool = False,
131
131
  ) -> tuple[list[QueryElement], dict[str, Any], list[str]]: