infrahub-server 1.7.0b0__py3-none-any.whl → 1.7.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 (112) hide show
  1. infrahub/api/exceptions.py +2 -2
  2. infrahub/cli/db.py +48 -22
  3. infrahub/core/account.py +12 -9
  4. infrahub/core/diff/branch_differ.py +1 -1
  5. infrahub/core/diff/conflict_transferer.py +1 -1
  6. infrahub/core/diff/data_check_synchronizer.py +1 -1
  7. infrahub/core/diff/enricher/cardinality_one.py +1 -1
  8. infrahub/core/diff/enricher/hierarchy.py +1 -1
  9. infrahub/core/diff/enricher/labels.py +1 -1
  10. infrahub/core/diff/merger/merger.py +1 -1
  11. infrahub/core/diff/repository/repository.py +3 -1
  12. infrahub/core/graph/constraints.py +1 -1
  13. infrahub/core/ipam/reconciler.py +8 -6
  14. infrahub/core/ipam/utilization.py +8 -15
  15. infrahub/core/manager.py +1 -26
  16. infrahub/core/merge.py +1 -1
  17. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -12
  18. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +4 -4
  19. infrahub/core/migrations/graph/m041_deleted_dup_edges.py +1 -1
  20. infrahub/core/migrations/graph/m049_remove_is_visible_relationship.py +16 -1
  21. infrahub/core/migrations/query/__init__.py +2 -2
  22. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  23. infrahub/core/migrations/schema/attribute_name_update.py +1 -1
  24. infrahub/core/migrations/schema/attribute_supports_profile.py +2 -2
  25. infrahub/core/migrations/schema/node_attribute_add.py +1 -1
  26. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  27. infrahub/core/migrations/schema/node_kind_update.py +1 -1
  28. infrahub/core/node/__init__.py +1 -1
  29. infrahub/core/node/base.py +9 -5
  30. infrahub/core/node/delete_validator.py +1 -1
  31. infrahub/core/order.py +30 -0
  32. infrahub/core/protocols.py +1 -0
  33. infrahub/core/protocols_base.py +4 -0
  34. infrahub/core/query/__init__.py +8 -5
  35. infrahub/core/query/attribute.py +3 -3
  36. infrahub/core/query/branch.py +1 -1
  37. infrahub/core/query/delete.py +1 -1
  38. infrahub/core/query/diff.py +3 -3
  39. infrahub/core/query/ipam.py +104 -43
  40. infrahub/core/query/node.py +454 -101
  41. infrahub/core/query/relationship.py +83 -26
  42. infrahub/core/query/resource_manager.py +107 -18
  43. infrahub/core/relationship/constraints/count.py +1 -1
  44. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  45. infrahub/core/relationship/constraints/peer_parent.py +1 -1
  46. infrahub/core/relationship/constraints/peer_relatives.py +1 -1
  47. infrahub/core/relationship/constraints/profiles_kind.py +1 -1
  48. infrahub/core/relationship/constraints/profiles_removal.py +1 -1
  49. infrahub/core/schema/attribute_schema.py +0 -13
  50. infrahub/core/schema/basenode_schema.py +3 -0
  51. infrahub/core/schema/definitions/core/__init__.py +8 -2
  52. infrahub/core/schema/definitions/core/account.py +10 -10
  53. infrahub/core/schema/definitions/core/artifact.py +14 -8
  54. infrahub/core/schema/definitions/core/check.py +10 -4
  55. infrahub/core/schema/definitions/core/generator.py +26 -6
  56. infrahub/core/schema/definitions/core/graphql_query.py +1 -1
  57. infrahub/core/schema/definitions/core/group.py +9 -2
  58. infrahub/core/schema/definitions/core/ipam.py +80 -10
  59. infrahub/core/schema/definitions/core/menu.py +41 -7
  60. infrahub/core/schema/definitions/core/permission.py +16 -2
  61. infrahub/core/schema/definitions/core/profile.py +16 -2
  62. infrahub/core/schema/definitions/core/propose_change.py +24 -4
  63. infrahub/core/schema/definitions/core/propose_change_comment.py +23 -11
  64. infrahub/core/schema/definitions/core/propose_change_validator.py +50 -21
  65. infrahub/core/schema/definitions/core/repository.py +10 -0
  66. infrahub/core/schema/definitions/core/resource_pool.py +8 -1
  67. infrahub/core/schema/definitions/core/template.py +19 -2
  68. infrahub/core/schema/definitions/core/transform.py +11 -5
  69. infrahub/core/schema/definitions/core/webhook.py +27 -9
  70. infrahub/core/schema/schema_branch.py +68 -2
  71. infrahub/core/utils.py +3 -3
  72. infrahub/core/validators/aggregated_checker.py +1 -1
  73. infrahub/core/validators/attribute/choices.py +1 -1
  74. infrahub/core/validators/attribute/enum.py +1 -1
  75. infrahub/core/validators/attribute/kind.py +1 -1
  76. infrahub/core/validators/attribute/length.py +1 -1
  77. infrahub/core/validators/attribute/min_max.py +1 -1
  78. infrahub/core/validators/attribute/number_pool.py +1 -1
  79. infrahub/core/validators/attribute/optional.py +1 -1
  80. infrahub/core/validators/attribute/regex.py +1 -1
  81. infrahub/core/validators/node/attribute.py +1 -1
  82. infrahub/core/validators/node/relationship.py +1 -1
  83. infrahub/core/validators/relationship/peer.py +1 -1
  84. infrahub/database/__init__.py +1 -1
  85. infrahub/git/utils.py +1 -1
  86. infrahub/graphql/app.py +2 -2
  87. infrahub/graphql/field_extractor.py +1 -1
  88. infrahub/graphql/manager.py +9 -1
  89. infrahub/graphql/mutations/account.py +1 -1
  90. infrahub/graphql/order.py +14 -0
  91. infrahub/graphql/queries/diff/tree.py +5 -5
  92. infrahub/graphql/queries/resource_manager.py +25 -24
  93. infrahub/graphql/resolvers/ipam.py +3 -3
  94. infrahub/graphql/resolvers/resolver.py +44 -3
  95. infrahub/graphql/types/standard_node.py +8 -4
  96. infrahub/menu/repository.py +1 -1
  97. infrahub/patch/queries/base.py +1 -1
  98. infrahub/pools/number.py +1 -8
  99. infrahub/profiles/node_applier.py +1 -1
  100. infrahub/profiles/queries/get_profile_data.py +1 -1
  101. infrahub/proposed_change/action_checker.py +1 -1
  102. infrahub/services/__init__.py +1 -1
  103. infrahub/services/adapters/cache/nats.py +1 -1
  104. infrahub/webhook/gather.py +1 -1
  105. infrahub/webhook/tasks.py +22 -6
  106. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/METADATA +1 -1
  107. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/RECORD +111 -110
  108. infrahub_testcontainers/models.py +3 -3
  109. infrahub/graphql/models.py +0 -36
  110. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/WHEEL +0 -0
  111. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/entry_points.txt +0 -0
  112. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -40,12 +40,14 @@ core_repository = NodeSchema(
40
40
  Attr(
41
41
  name="default_branch",
42
42
  kind="Text",
43
+ description="Default branch name in the Git repository",
43
44
  default_value="main",
44
45
  order_weight=6000,
45
46
  ),
46
47
  Attr(
47
48
  name="commit",
48
49
  kind="Text",
50
+ description="Current commit hash being tracked",
49
51
  optional=True,
50
52
  branch=BranchSupportType.LOCAL,
51
53
  order_weight=7000,
@@ -75,6 +77,7 @@ core_read_only_repository = NodeSchema(
75
77
  Attr(
76
78
  name="ref",
77
79
  kind="Text",
80
+ description="Git reference (branch or tag) to track",
78
81
  default_value="main",
79
82
  branch=BranchSupportType.AWARE,
80
83
  order_weight=6000,
@@ -82,6 +85,7 @@ core_read_only_repository = NodeSchema(
82
85
  Attr(
83
86
  name="commit",
84
87
  kind="Text",
88
+ description="Current commit hash being tracked",
85
89
  optional=True,
86
90
  branch=BranchSupportType.AWARE,
87
91
  order_weight=7000,
@@ -107,6 +111,7 @@ core_generic_repository = GenericSchema(
107
111
  name="name",
108
112
  regex=r"^[^/]*$",
109
113
  kind="Text",
114
+ description="Unique name identifier for the repository",
110
115
  unique=True,
111
116
  branch=BranchSupportType.AGNOSTIC,
112
117
  order_weight=1000,
@@ -115,6 +120,7 @@ core_generic_repository = GenericSchema(
115
120
  Attr(
116
121
  name="description",
117
122
  kind="Text",
123
+ description="Description of the repository",
118
124
  optional=True,
119
125
  branch=BranchSupportType.AGNOSTIC,
120
126
  order_weight=2000,
@@ -123,6 +129,7 @@ core_generic_repository = GenericSchema(
123
129
  Attr(
124
130
  name="location",
125
131
  kind="Text",
132
+ description="URL or path to the Git repository",
126
133
  unique=True,
127
134
  branch=BranchSupportType.AGNOSTIC,
128
135
  order_weight=3000,
@@ -131,6 +138,7 @@ core_generic_repository = GenericSchema(
131
138
  Attr(
132
139
  name="internal_status",
133
140
  kind="Dropdown",
141
+ description="Internal status of the repository on this branch",
134
142
  choices=[
135
143
  DropdownChoice(
136
144
  name=RepositoryInternalStatus.STAGING.value,
@@ -160,6 +168,7 @@ core_generic_repository = GenericSchema(
160
168
  Attr(
161
169
  name="operational_status",
162
170
  kind="Dropdown",
171
+ description="Connectivity status of the repository",
163
172
  choices=[
164
173
  DropdownChoice(
165
174
  name=RepositoryOperationalStatus.UNKNOWN.value,
@@ -200,6 +209,7 @@ core_generic_repository = GenericSchema(
200
209
  Attr(
201
210
  name="sync_status",
202
211
  kind="Dropdown",
212
+ description="Current synchronization status of the repository",
203
213
  choices=[
204
214
  DropdownChoice(
205
215
  name=RepositorySyncStatus.UNKNOWN.value,
@@ -73,12 +73,19 @@ core_ip_prefix_pool = NodeSchema(
73
73
  Attr(
74
74
  name="default_member_type",
75
75
  kind="Text",
76
+ description="Default member type for allocated prefixes",
76
77
  enum=["prefix", "address"],
77
78
  default_value="prefix",
78
79
  optional=True,
79
80
  order_weight=3000,
80
81
  ),
81
- Attr(name="default_prefix_type", kind="Text", optional=True, order_weight=4000),
82
+ Attr(
83
+ name="default_prefix_type",
84
+ kind="Text",
85
+ description="Default prefix type schema to use when allocating",
86
+ optional=True,
87
+ order_weight=4000,
88
+ ),
82
89
  ],
83
90
  relationships=[
84
91
  Rel(
@@ -11,7 +11,16 @@ core_object_template = GenericSchema(
11
11
  display_labels=["template_name__value"],
12
12
  default_filter="template_name__value",
13
13
  uniqueness_constraints=[["template_name__value"]],
14
- attributes=[Attr(name="template_name", kind="Text", optional=False, unique=True, order_weight=1000)],
14
+ attributes=[
15
+ Attr(
16
+ name="template_name",
17
+ kind="Text",
18
+ description="Unique name identifier for the template",
19
+ optional=False,
20
+ unique=True,
21
+ order_weight=1000,
22
+ )
23
+ ],
15
24
  )
16
25
 
17
26
  core_object_component_template = GenericSchema(
@@ -23,5 +32,13 @@ core_object_component_template = GenericSchema(
23
32
  label="Object Component Templates",
24
33
  display_labels=["template_name__value"],
25
34
  default_filter="template_name__value",
26
- attributes=[Attr(name="template_name", kind="Text", optional=False, order_weight=1000)],
35
+ attributes=[
36
+ Attr(
37
+ name="template_name",
38
+ kind="Text",
39
+ description="Name identifier for the component template",
40
+ optional=False,
41
+ order_weight=1000,
42
+ )
43
+ ],
27
44
  )
@@ -29,7 +29,7 @@ core_transform = GenericSchema(
29
29
  Attr(name="name", kind="Text", unique=True),
30
30
  Attr(name="label", kind="Text", optional=True),
31
31
  Attr(name="description", kind="Text", optional=True),
32
- Attr(name="timeout", kind="Number", default_value=60),
32
+ Attr(name="timeout", kind="Number", description="Maximum execution time in seconds", default_value=60),
33
33
  ],
34
34
  relationships=[
35
35
  Rel(
@@ -72,7 +72,7 @@ core_transform_jinja2 = NodeSchema(
72
72
  branch=BranchSupportType.AWARE,
73
73
  documentation="/topics/transformation",
74
74
  attributes=[
75
- Attr(name="template_path", kind="Text"),
75
+ Attr(name="template_path", kind="Text", description="Path to the Jinja2 template file in the repository"),
76
76
  ],
77
77
  )
78
78
 
@@ -90,8 +90,14 @@ core_transform_python = NodeSchema(
90
90
  branch=BranchSupportType.AWARE,
91
91
  documentation="/topics/transformation",
92
92
  attributes=[
93
- Attr(name="file_path", kind="Text"),
94
- Attr(name="class_name", kind="Text"),
95
- Attr(name="convert_query_response", kind="Boolean", optional=True, default_value=False),
93
+ Attr(name="file_path", kind="Text", description="Path to the Python file in the repository"),
94
+ Attr(name="class_name", kind="Text", description="Name of the Python class implementing the transformation"),
95
+ Attr(
96
+ name="convert_query_response",
97
+ kind="Boolean",
98
+ description="Whether to convert the GraphQL response to SDK objects",
99
+ optional=True,
100
+ default_value=False,
101
+ ),
96
102
  ],
97
103
  )
@@ -37,9 +37,18 @@ core_webhook = GenericSchema(
37
37
  order_weight=1500,
38
38
  description="The event type that triggers the webhook",
39
39
  ),
40
+ Attr(
41
+ name="active",
42
+ kind="Boolean",
43
+ description="Indicates if this webhook is enabled",
44
+ optional=False,
45
+ default_value=True,
46
+ order_weight=1750,
47
+ ),
40
48
  Attr(
41
49
  name="branch_scope",
42
50
  kind="Dropdown",
51
+ description="Which branches should trigger this webhook",
43
52
  choices=[
44
53
  DropdownChoice(
45
54
  name="all_branches",
@@ -72,16 +81,12 @@ core_webhook = GenericSchema(
72
81
  description="Only send node mutation events for nodes of this kind",
73
82
  order_weight=2250,
74
83
  ),
75
- Attr(
76
- name="description",
77
- kind="Text",
78
- optional=True,
79
- order_weight=2500,
80
- ),
81
- Attr(name="url", kind="URL", order_weight=3000),
84
+ Attr(name="description", kind="Text", optional=True, order_weight=2500),
85
+ Attr(name="url", kind="URL", description="Target URL to send webhook requests to", order_weight=3000),
82
86
  Attr(
83
87
  name="validate_certificates",
84
88
  kind="Boolean",
89
+ description="Whether to validate SSL/TLS certificates",
85
90
  default_value=True,
86
91
  optional=True,
87
92
  order_weight=5000,
@@ -103,7 +108,13 @@ core_standard_webhook = NodeSchema(
103
108
  generate_profile=False,
104
109
  inherit_from=[InfrahubKind.WEBHOOK, InfrahubKind.TASKTARGET],
105
110
  attributes=[
106
- Attr(name="shared_key", kind="Password", unique=False, order_weight=4000),
111
+ Attr(
112
+ name="shared_key",
113
+ kind="Password",
114
+ description="Shared secret key for webhook authentication",
115
+ unique=False,
116
+ order_weight=4000,
117
+ ),
107
118
  ],
108
119
  )
109
120
 
@@ -121,7 +132,14 @@ core_custom_webhook = NodeSchema(
121
132
  generate_profile=False,
122
133
  inherit_from=[InfrahubKind.WEBHOOK, InfrahubKind.TASKTARGET],
123
134
  attributes=[
124
- Attr(name="shared_key", kind="Password", unique=False, optional=True, order_weight=4000),
135
+ Attr(
136
+ name="shared_key",
137
+ kind="Password",
138
+ description="Shared secret key for webhook authentication",
139
+ unique=False,
140
+ optional=True,
141
+ order_weight=4000,
142
+ ),
125
143
  ],
126
144
  relationships=[
127
145
  Rel(
@@ -54,7 +54,7 @@ from infrahub.core.schema import (
54
54
  SchemaRoot,
55
55
  TemplateSchema,
56
56
  )
57
- from infrahub.core.schema.attribute_parameters import NumberPoolParameters
57
+ from infrahub.core.schema.attribute_parameters import NumberPoolParameters, TextAttributeParameters
58
58
  from infrahub.core.schema.attribute_schema import get_attribute_schema_class_for_kind
59
59
  from infrahub.core.schema.definitions.core import core_profile_schema_definition
60
60
  from infrahub.core.validators import CONSTRAINT_VALIDATOR_MAP
@@ -93,7 +93,7 @@ class SchemaBranch:
93
93
  computed_attributes: ComputedAttributes | None = None,
94
94
  display_labels: DisplayLabels | None = None,
95
95
  hfids: HFIDs | None = None,
96
- ):
96
+ ) -> None:
97
97
  self._cache: dict[str, NodeSchema | GenericSchema] = cache
98
98
  self.name: str | None = name
99
99
  self.nodes: dict[str, str] = {}
@@ -501,11 +501,76 @@ class SchemaBranch:
501
501
 
502
502
  return fields or None
503
503
 
504
+ def _text_attr_needs_reconciliation(self, attr: AttributeSchema) -> bool:
505
+ """Check if a Text attribute needs reconciliation between deprecated fields and parameters."""
506
+ if not isinstance(attr.parameters, TextAttributeParameters):
507
+ return False
508
+ return (
509
+ attr.regex != attr.parameters.regex
510
+ or attr.min_length != attr.parameters.min_length
511
+ or attr.max_length != attr.parameters.max_length
512
+ )
513
+
514
+ def _reconcile_text_attr(self, attr: AttributeSchema) -> None:
515
+ """Reconcile a single Text attribute's deprecated fields with parameters.
516
+
517
+ Parameters take precedence over deprecated top-level fields when both are set.
518
+ """
519
+ if not isinstance(attr.parameters, TextAttributeParameters):
520
+ return
521
+
522
+ # Sync regex: parameters takes precedence
523
+ if attr.parameters.regex is not None:
524
+ attr.regex = attr.parameters.regex
525
+ elif attr.regex is not None:
526
+ attr.parameters.regex = attr.regex
527
+
528
+ # Sync min_length: parameters takes precedence
529
+ if attr.parameters.min_length is not None:
530
+ attr.min_length = attr.parameters.min_length
531
+ elif attr.min_length is not None:
532
+ attr.parameters.min_length = attr.min_length
533
+
534
+ # Sync max_length: parameters takes precedence
535
+ if attr.parameters.max_length is not None:
536
+ attr.max_length = attr.parameters.max_length
537
+ elif attr.max_length is not None:
538
+ attr.parameters.max_length = attr.max_length
539
+
540
+ def _reconcile_text_attribute_parameters(self, schema: SchemaRoot | None = None) -> None:
541
+ """Reconcile regex, min_length, max_length between deprecated fields and parameters for Text attributes.
542
+
543
+ Args:
544
+ schema: If provided, reconcile incoming schema data before merging.
545
+ If None, reconcile already-loaded schemas (e.g., from database).
546
+ """
547
+ if schema:
548
+ # Incoming schema: modify in place
549
+ for item in schema.nodes + schema.generics:
550
+ for attr in item.attributes:
551
+ self._reconcile_text_attr(attr)
552
+ return
553
+
554
+ # Loaded schemas: need to duplicate before modifying
555
+ for name in self.all_names:
556
+ node = self.get(name=name, duplicate=False)
557
+
558
+ if not any(self._text_attr_needs_reconciliation(attr) for attr in node.attributes):
559
+ continue
560
+
561
+ node = node.duplicate()
562
+ for attr in node.attributes:
563
+ self._reconcile_text_attr(attr)
564
+ self.set(name=name, schema=node)
565
+
504
566
  def load_schema(self, schema: SchemaRoot) -> None:
505
567
  """Load a SchemaRoot object and store all NodeSchema or GenericSchema.
506
568
 
507
569
  In the current implementation, if a schema object present in the SchemaRoot already exist, it will be overwritten.
508
570
  """
571
+ # Reconcile deprecated text attribute parameters before merging
572
+ self._reconcile_text_attribute_parameters(schema)
573
+
509
574
  for item in schema.nodes + schema.generics:
510
575
  try:
511
576
  if item.id:
@@ -545,6 +610,7 @@ class SchemaBranch:
545
610
  self.generate_identifiers()
546
611
  self.process_default_values()
547
612
  self.process_deprecations()
613
+ self._reconcile_text_attribute_parameters()
548
614
  self.process_cardinality_counts()
549
615
  self.process_inheritance()
550
616
  self.process_hierarchy()
infrahub/core/utils.py CHANGED
@@ -215,7 +215,7 @@ def props(x: Any) -> dict[str, Any]:
215
215
 
216
216
 
217
217
  class SubclassWithMeta_Meta(type):
218
- _meta = None
218
+ _meta: Any = None
219
219
 
220
220
  def __str__(cls) -> str:
221
221
  if cls._meta:
@@ -229,7 +229,7 @@ class SubclassWithMeta_Meta(type):
229
229
  class SubclassWithMeta(metaclass=SubclassWithMeta_Meta):
230
230
  """This class improves __init_subclass__ to receive automatically the options from meta"""
231
231
 
232
- def __init_subclass__(cls, **meta_options: dict[str, Any]) -> None:
232
+ def __init_subclass__(cls, **meta_options: Any) -> None:
233
233
  """This method just terminates the super() chain"""
234
234
  _Meta = getattr(cls, "Meta", None)
235
235
  _meta_props = {}
@@ -254,5 +254,5 @@ class SubclassWithMeta(metaclass=SubclassWithMeta_Meta):
254
254
  super_class.__init_subclass_with_meta__(**options)
255
255
 
256
256
  @classmethod
257
- def __init_subclass_with_meta__(cls, **meta_options: dict[str, Any]) -> None:
257
+ def __init_subclass_with_meta__(cls, **meta_options: Any) -> None:
258
258
  """This method just terminates the super() chain"""
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
20
20
  class AggregatedConstraintChecker:
21
21
  def __init__(
22
22
  self, constraints: list[ConstraintCheckerInterface], db: InfrahubDatabase, branch: Branch | None = None
23
- ):
23
+ ) -> None:
24
24
  self.constraints = constraints
25
25
  self.db = db
26
26
  self.branch = branch
@@ -84,7 +84,7 @@ class AttributeChoicesUpdateValidatorQuery(AttributeSchemaValidatorQuery):
84
84
  class AttributeChoicesChecker(ConstraintCheckerInterface):
85
85
  query_classes = [AttributeChoicesUpdateValidatorQuery]
86
86
 
87
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
87
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
88
88
  self.db = db
89
89
  self.branch = branch
90
90
 
@@ -72,7 +72,7 @@ class AttributeEnumUpdateValidatorQuery(AttributeSchemaValidatorQuery):
72
72
  class AttributeEnumChecker(ConstraintCheckerInterface):
73
73
  query_classes = [AttributeEnumUpdateValidatorQuery]
74
74
 
75
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
75
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
76
76
  self.db = db
77
77
  self.branch = branch
78
78
 
@@ -89,7 +89,7 @@ class AttributeKindUpdateValidatorQuery(AttributeSchemaValidatorQuery):
89
89
  class AttributeKindChecker(ConstraintCheckerInterface):
90
90
  query_classes = [AttributeKindUpdateValidatorQuery]
91
91
 
92
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
92
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
93
93
  self.db = db
94
94
  self.branch = branch
95
95
 
@@ -69,7 +69,7 @@ class AttributeLengthUpdateValidatorQuery(AttributeSchemaValidatorQuery):
69
69
  class AttributeLengthChecker(ConstraintCheckerInterface):
70
70
  query_classes = [AttributeLengthUpdateValidatorQuery]
71
71
 
72
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
72
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
73
73
  self.db = db
74
74
  self.branch = branch
75
75
 
@@ -79,7 +79,7 @@ class AttributeNumberUpdateValidatorQuery(AttributeSchemaValidatorQuery):
79
79
  class AttributeNumberChecker(ConstraintCheckerInterface):
80
80
  query_classes = [AttributeNumberUpdateValidatorQuery]
81
81
 
82
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
82
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
83
83
  self.db = db
84
84
  self.branch = branch
85
85
 
@@ -74,7 +74,7 @@ class AttributeNumberPoolUpdateValidatorQuery(AttributeSchemaValidatorQuery):
74
74
  class AttributeNumberPoolChecker(ConstraintCheckerInterface):
75
75
  query_classes = [AttributeNumberPoolUpdateValidatorQuery]
76
76
 
77
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
77
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
78
78
  self.db = db
79
79
  self.branch = branch
80
80
 
@@ -64,7 +64,7 @@ class AttributeOptionalUpdateValidatorQuery(AttributeSchemaValidatorQuery):
64
64
  class AttributeOptionalChecker(ConstraintCheckerInterface):
65
65
  query_classes = [AttributeOptionalUpdateValidatorQuery]
66
66
 
67
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
67
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
68
68
  self.db = db
69
69
  self.branch = branch
70
70
 
@@ -69,7 +69,7 @@ class AttributeRegexUpdateValidatorQuery(AttributeSchemaValidatorQuery):
69
69
  class AttributeRegexChecker(ConstraintCheckerInterface):
70
70
  query_classes = [AttributeRegexUpdateValidatorQuery]
71
71
 
72
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
72
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
73
73
  self.db = db
74
74
  self.branch = branch
75
75
 
@@ -19,7 +19,7 @@ if TYPE_CHECKING:
19
19
  class NodeAttributeAddChecker(ConstraintCheckerInterface):
20
20
  query_classes = [NodeNotPresentValidatorQuery]
21
21
 
22
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
22
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
23
23
  self.db = db
24
24
  self.branch = branch
25
25
 
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
16
16
  class NodeRelationshipAddChecker(ConstraintCheckerInterface):
17
17
  query_classes = [NodeNotPresentValidatorQuery]
18
18
 
19
- def __init__(self, db: InfrahubDatabase, branch: Branch | None = None):
19
+ def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
20
20
  self.db = db
21
21
  self.branch = branch
22
22
 
@@ -136,7 +136,7 @@ class RelationshipPeerParentValidatorQuery(RelationshipSchemaValidatorQuery):
136
136
  parent_relationship: RelationshipSchema,
137
137
  peer_parent_relationship: RelationshipSchema,
138
138
  **kwargs: Any,
139
- ):
139
+ ) -> None:
140
140
  super().__init__(**kwargs)
141
141
 
142
142
  self.relationship = relationship
@@ -152,7 +152,7 @@ class InfrahubDatabase:
152
152
  session_mode: InfrahubDatabaseSessionMode = InfrahubDatabaseSessionMode.WRITE,
153
153
  transaction: AsyncTransaction | None = None,
154
154
  queries_names_to_config: dict[str, QueryConfig] | None = None,
155
- ):
155
+ ) -> None:
156
156
  self._mode: InfrahubDatabaseMode = mode
157
157
  self._driver: AsyncDriver = driver
158
158
  self._session: AsyncSession | None = session
infrahub/git/utils.py CHANGED
@@ -16,9 +16,9 @@ from infrahub_sdk.types import Order
16
16
  from infrahub.core import registry
17
17
  from infrahub.core.constants import InfrahubKind
18
18
  from infrahub.core.manager import NodeManager
19
+ from infrahub.core.order import OrderModel
19
20
  from infrahub.database import InfrahubDatabase
20
21
  from infrahub.generators.models import ProposedChangeGeneratorDefinition
21
- from infrahub.graphql.models import OrderModel
22
22
 
23
23
  from .. import config
24
24
  from .models import RepositoryBranchInfo, RepositoryData
infrahub/graphql/app.py CHANGED
@@ -172,9 +172,9 @@ class InfrahubGraphQLApp:
172
172
 
173
173
  response = handler(request)
174
174
  if isawaitable(response):
175
- return await cast("Awaitable[Response]", response)
175
+ return await response
176
176
 
177
- return cast("Response", response)
177
+ return response
178
178
 
179
179
  async def _handle_http_request(
180
180
  self, request: Request, db: InfrahubDatabase, branch: Branch, account_session: AccountSession
@@ -12,7 +12,7 @@ from graphql import (
12
12
  class GraphQLFieldExtractor:
13
13
  """Class to extract fields from a GraphQL selection set."""
14
14
 
15
- def __init__(self, info: GraphQLResolveInfo):
15
+ def __init__(self, info: GraphQLResolveInfo) -> None:
16
16
  self.info = info
17
17
  self.fragments = info.fragments
18
18
 
@@ -1005,8 +1005,16 @@ class GraphQLSchemaManager:
1005
1005
  if not top_level:
1006
1006
  filters["isnull"] = graphene.Boolean()
1007
1007
 
1008
+ if schema.display_label:
1009
+ display_label_schema = schema.get_attribute("display_label")
1010
+ filters.update(
1011
+ get_attribute_type(kind=display_label_schema.kind).get_graphql_filters(
1012
+ name="display_label", include_properties=False, include_isnull=True
1013
+ )
1014
+ )
1015
+
1008
1016
  if schema.human_friendly_id and top_level:
1009
- # HFID filter limited to top level because we can't filter on HFID for relationships (yet)
1017
+ # NOTE: this can loosen to allow filtering at a non-top level once IFC-2110 is implemented
1010
1018
  filters["hfid"] = graphene.List(graphene.String)
1011
1019
 
1012
1020
  for attr in schema.attributes:
@@ -9,13 +9,13 @@ from infrahub.auth import AuthType
9
9
  from infrahub.core.constants import InfrahubKind
10
10
  from infrahub.core.manager import NodeManager
11
11
  from infrahub.core.node import Node
12
+ from infrahub.core.order import OrderModel
12
13
  from infrahub.core.protocols import CoreAccount, CoreNode, InternalAccountToken
13
14
  from infrahub.core.timestamp import Timestamp
14
15
  from infrahub.database import InfrahubDatabase, retry_db_transaction
15
16
  from infrahub.exceptions import NodeNotFoundError, PermissionDeniedError
16
17
  from infrahub.graphql.field_extractor import extract_graphql_fields
17
18
 
18
- from ..models import OrderModel
19
19
  from ..types import InfrahubObjectType
20
20
 
21
21
  if TYPE_CHECKING:
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from infrahub.core.order import OrderModel
6
+
7
+
8
+ def deserialize_order_input(input_data: dict[str, Any] | None) -> OrderModel | None:
9
+ # Corresponds to infrahub.graphql.manager.OrderInput
10
+ if not input_data:
11
+ return None
12
+
13
+ order_model = OrderModel(**input_data)
14
+ return order_model
@@ -60,10 +60,10 @@ class ConflictDetails(ObjectType):
60
60
 
61
61
 
62
62
  class DiffSummaryCounts(ObjectType):
63
- num_added = Int(required=False)
64
- num_updated = Int(required=False)
65
- num_removed = Int(required=False)
66
- num_conflicts = Int(required=False)
63
+ num_added = Int(required=True)
64
+ num_updated = Int(required=True)
65
+ num_removed = Int(required=True)
66
+ num_conflicts = Int(required=True)
67
67
 
68
68
 
69
69
  class DiffProperty(ObjectType):
@@ -146,7 +146,7 @@ class DiffTreeSummary(DiffSummaryCounts):
146
146
  diff_branch = String(required=True)
147
147
  from_time = DateTime(required=True)
148
148
  to_time = DateTime(required=True)
149
- num_unchanged = Int(required=False)
149
+ num_unchanged = Int(required=True)
150
150
  num_untracked_base_changes = Int(required=False)
151
151
  num_untracked_diff_changes = Int(required=False)
152
152