Skip to content

Conversation

@fatih-acar
Copy link
Contributor

@fatih-acar fatih-acar commented Nov 10, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added infrahubctl graphql commands to export GraphQL schemas and generate Pydantic models from queries.
    • Implemented range expansion in object files for bulk object creation.
    • Added object-type conversion capability to SDK.
    • Extended Branch entity with status and graph_version fields.
    • Added execution control flags for generators.
  • Bug Fixes

    • Improved schema loading error handling and display.
    • Fixed console markup rendering issues.
  • Documentation

    • Added guides for GraphQL CLI and Pydantic type generation from GraphQL queries.
    • Documented range expansion functionality in object files.
  • Chores

    • Updated GitHub Actions tooling and added pre-commit hooks.
    • Improved Python 3.11+ compatibility.

gmazoyer and others added 30 commits July 17, 2025 10:44
- Add find_repository_config_file() function to search for both .yml and .yaml extensions
- Update all modules to use dynamic config file discovery
- Prefer .yml over .yaml when both exist for backward compatibility
- Update pytest plugin to support both extensions
- Improve error messages to mention both possible file extensions
develop -> infrahub-develop
Support infrahub.yml or infrahub.yaml configuration files
Merge 'develop' into 'infrahub-develop'
Merge stable into develop
Signed-off-by: Fatih Acar <fatih@opsmill.com>
Merge stable into develop
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/labeler](https://github.com/actions/labeler) from 5.0.0 to 6.0.1.
- [Release notes](https://github.com/actions/labeler/releases)
- [Commits](actions/labeler@v5.0.0...v6.0.1)

---
updated-dependencies:
- dependency-name: actions/labeler
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 5.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
…p/actions/setup-node-5

Bump actions/setup-node from 4 to 5
…p/actions/setup-python-6

Bump actions/setup-python from 5 to 6
…p/actions/labeler-6.0.1

Bump actions/labeler from 5.0.0 to 6.0.1
Merge develop into infrahub-develop
* Replace toml package with tomllib and tomli optionally

* fix for mypy errors

* update config, add pre-commit config

* Make tomli package optional

* Add towncrier housekeeping message

* update python to uppercase p
dgarros and others added 21 commits October 13, 2025 14:48
Merge develop into infrahub-develop
Add flags to `CoreGeneratorDefinition` to control when each generator should be executed
* IHS-128: Replace `Sync` in protocol sync classes schema name

Fixes #380

This PR replaces the `Sync` word in the protocol schema name so that the correct kind can be gotten from the cache.

* add towncrier

* refactor get_schema_name, add test

* update test
Merge develop into infrahub-develop
* Replace strategy in object file with parameters section

* Implement code rabbit suggestions

* implement logic directly in process_data

* Patricks suggestion

* Fix default parameter initialization for InfrahubObjectFileData

* Refactor InfrahubObjectFileData to allow optional parameters initialization

---------

Co-authored-by: Alex Gittings <agitting96@gmail.com>
Merge 'stable' into 'develop' with resolved conflicts.
Merge stable into develop
Merge develop into infrahub-develop
Merge develop into infrahub-develop
Merge develop into infrahub-develop
@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Warning

Rate limit exceeded

@fatih-acar has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 15 minutes and 40 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between f43c73a and bb1acc1.

⛔ Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • pyproject.toml (6 hunks)

Walkthrough

This pull request introduces GraphQL schema tooling capabilities, including code generation plugins and query rendering utilities. It adds range expansion for object file fields, new Branch properties (status and graph_version), and a convert_object_type method for the client. The change replaces the toml dependency with tomllib/tomli (Python 3.11+ compatible), improves repository configuration file discovery with fallback extension matching, and implements deprecation handling for raise_for_error parameters. Protocol definitions are extended with new fields and entity types. Schema warnings support is added, and CLI commands are enhanced with dynamic config resolution and a new graphql command group for schema export and Pydantic type generation.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.21% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Merge infrahub-develop into stable' accurately describes the main objective of this changeset—a branch merge operation integrating the develop branch into the stable branch.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added group/ci Issue related to the CI pipeline type/documentation Improvements or additions to documentation labels Nov 10, 2025
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 10, 2025

Deploying infrahub-sdk-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: bb1acc1
Status: ✅  Deploy successful!
Preview URL: https://20c14418.infrahub-sdk-python.pages.dev
Branch Preview URL: https://infrahub-develop.infrahub-sdk-python.pages.dev

View logs

@codecov
Copy link

codecov bot commented Nov 10, 2025

Codecov Report

❌ Patch coverage is 68.62124% with 198 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
infrahub_sdk/ctl/graphql.py 35.78% 61 Missing ⚠️
infrahub_sdk/graphql/plugin.py 50.98% 24 Missing and 1 partial ⚠️
infrahub_sdk/schema/__init__.py 52.77% 15 Missing and 2 partials ⚠️
infrahub_sdk/graphql/utils.py 20.00% 16 Missing ⚠️
infrahub_sdk/ctl/repository.py 25.00% 12 Missing and 3 partials ⚠️
infrahub_sdk/ctl/schema.py 46.15% 11 Missing and 3 partials ⚠️
infrahub_sdk/pytest_plugin/utils.py 30.00% 10 Missing and 4 partials ⚠️
infrahub_sdk/client.py 79.06% 5 Missing and 4 partials ⚠️
infrahub_sdk/spec/range_expansion.py 88.57% 5 Missing and 3 partials ⚠️
infrahub_sdk/spec/object.py 76.92% 6 Missing ⚠️
... and 7 more
@@            Coverage Diff             @@
##           stable     #613      +/-   ##
==========================================
- Coverage   75.94%   75.46%   -0.49%     
==========================================
  Files         101      113      +12     
  Lines        8977     9512     +535     
  Branches     1772     1893     +121     
==========================================
+ Hits         6818     7178     +360     
- Misses       1677     1834     +157     
- Partials      482      500      +18     
Flag Coverage Δ
integration-tests 34.90% <33.75%> (+0.21%) ⬆️
python-3.10 48.76% <51.18%> (+0.06%) ⬆️
python-3.11 48.76% <51.18%> (+0.06%) ⬆️
python-3.12 48.72% <51.18%> (+0.07%) ⬆️
python-3.13 48.72% <51.18%> (+0.04%) ⬆️
python-3.9 47.46% <49.76%> (+0.10%) ⬆️
python-filler-3.12 24.29% <15.05%> (-0.61%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
infrahub_sdk/branch.py 56.37% <100.00%> (+2.47%) ⬆️
infrahub_sdk/ctl/branch.py 77.46% <100.00%> (+0.32%) ⬆️
infrahub_sdk/ctl/generator.py 50.90% <100.00%> (-0.88%) ⬇️
infrahub_sdk/generator.py 79.06% <100.00%> (+1.56%) ⬆️
infrahub_sdk/graphql/__init__.py 100.00% <100.00%> (ø)
infrahub_sdk/graphql/constants.py 100.00% <100.00%> (ø)
infrahub_sdk/graphql/query.py 100.00% <100.00%> (ø)
infrahub_sdk/graphql/renderers.py 98.68% <100.00%> (ø)
infrahub_sdk/protocols.py 100.00% <100.00%> (ø)
infrahub_sdk/pytest_plugin/plugin.py 85.10% <100.00%> (+0.66%) ⬆️
... and 21 more

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
infrahub_sdk/spec/object.py (1)

200-212: Pass parameters to create_node.

The process method processes data using the parameters but doesn't pass them to create_node. This breaks parameter propagation through the creation flow.

Apply this diff:

 async def process(self, client: InfrahubClient, branch: str | None = None) -> None:
     schema = await client.schema.get(kind=self.kind, branch=branch)
     processed_data = await self._get_processed_data(data=self.data)

     for idx, item in enumerate(processed_data):
         await self.create_node(
             client=client,
             schema=schema,
             data=item,
             position=[idx + 1],
             branch=branch,
             default_schema_kind=self.kind,
+            parameters=self.parameters,
         )
🧹 Nitpick comments (13)
infrahub_sdk/timestamp.py (1)

83-95: TypedDict improves type safety; consider simplifying the key assignment logic.

The introduction of SubstractParams TypedDict enhances type safety. However, the explicit if-elif chain (lines 87-92) is verbose and could be simplified since the keys are already constrained by REGEX_MAPPING.

Consider this simpler approach:

         params: SubstractParams = {}
         for key, regex in REGEX_MAPPING.items():
             match = re.search(regex, value)
             if match:
-                if key == "seconds":
-                    params["seconds"] = float(match.group(1))
-                elif key == "minutes":
-                    params["minutes"] = float(match.group(1))
-                elif key == "hours":
-                    params["hours"] = float(match.group(1))
+                params[key] = float(match.group(1))  # type: ignore[literal-required]
 
         if params:
             return ZonedDateTime.now("UTC").subtract(**params)

Note: The type: ignore[literal-required] comment suppresses the type checker warning about dynamic key assignment, which is safe here since REGEX_MAPPING keys match the TypedDict keys.

infrahub_sdk/graphql/constants.py (2)

1-1: Consider using a dict for O(1) type lookups.

The tuple-of-tuples structure requires iteration for type lookups. A dict would provide more efficient O(1) lookups when mapping Python types to GraphQL types.

Apply this diff to use a dict structure:

-VARIABLE_TYPE_MAPPING = ((str, "String!"), (int, "Int!"), (float, "Float!"), (bool, "Boolean!"))
+VARIABLE_TYPE_MAPPING = {
+    str: "String!",
+    int: "Int!",
+    float: "Float!",
+    bool: "Boolean!",
+}

1-1: Limited type coverage.

The mapping currently covers only 4 basic scalar types. Consider whether additional common types are needed (e.g., list, dict, None/Optional, datetime, UUID) or if they're intentionally handled elsewhere in the codebase.

.pre-commit-config.yaml (1)

3-4: Update pre-commit-hooks to v6.0.0.

The version v4.3.0 is over 2 years old; v6.0.0 is the latest release, which requires pre-commit >= 3.2.0 (introduced in v5.x). Your configuration does not use deprecated stage names, so the upgrade should be straightforward. Update the rev: field to v6.0.0 and verify your pre-commit version meets the requirement.

infrahub_sdk/ctl/repository.py (1)

27-51: Consider eliminating code duplication.

This function is duplicated in infrahub_sdk/pytest_plugin/utils.py (lines 10-34) with identical logic. Consider extracting it to a shared utility module to maintain DRY principles.

For example, you could move this to a shared location like infrahub_sdk/utils.py and import from both modules.

docs/docs/python-sdk/guides/python-typing.mdx (2)

134-135: Add example GraphQL query for step 1.

The first step mentions creating GraphQL queries but doesn't include an example. Adding a sample .gql file would make this workflow more concrete and actionable for users.

Consider adding an example like:

 1. **Create your GraphQL queries** in `.gql` files:
+
+   ```graphql title="queries/get_devices.gql"
+   query GetDevices {
+     InfraDevice {
+       edges {
+         node {
+           id
+           name { value }
+         }
+       }
+     }
+   }
+   ```

142-142: Fix grammar for clarity.

Apply this diff:

-   The command will generate the Python file per query based on the name of the query.
+   The command will generate a Python file per query based on the name of the query.
infrahub_sdk/spec/processors/factory.py (2)

8-8: Consider encapsulating the processor registry.

The module-level mutable registry PROCESSOR_PER_KIND can cause test isolation issues and makes registration order implicit. Consider encapsulating it within the factory class or using a class-level registry with explicit registration methods.

Apply this diff to encapsulate the registry:

-PROCESSOR_PER_KIND: dict[str, DataProcessor] = {}
-
-
 class DataProcessorFactory:
     """Factory to create appropriate data processor based on strategy"""
+    _registry: dict[str, DataProcessor] = {}
+
+    @classmethod
+    def register(cls, kind: str, processor: DataProcessor) -> None:
+        """Register a processor for a specific kind."""
+        cls._registry[kind] = processor
 
     @classmethod
     def get_processors(cls, kind: str, parameters: InfrahubObjectParameters) -> Sequence[DataProcessor]:
         processors: list[DataProcessor] = []
         if parameters.expand_range:
             processors.append(RangeExpandDataProcessor())
-        if kind in PROCESSOR_PER_KIND:
-            processors.append(PROCESSOR_PER_KIND[kind])
+        if kind in cls._registry:
+            processors.append(cls._registry[kind])
 
         return processors

24-34: LGTM! Consider adding error handling for processor failures.

The sequential processing logic is correct. However, you may want to add error handling or logging if individual processors fail, depending on whether failures should be fatal or recoverable.

infrahub_sdk/schema/__init__.py (2)

504-521: Consider using a more specific exception type.

The method correctly fetches the GraphQL schema, but raises a generic ValueError on failure. Consider using or creating a more specific exception type (e.g., SchemaFetchError or ServerResponseError) for better error handling by consumers.

Example:

     async def get_graphql_schema(self, branch: str | None = None) -> str:
         """Get the GraphQL schema as a string.
 
         Args:
             branch: The branch to get the schema for. Defaults to default_branch.
 
         Returns:
             The GraphQL schema as a string.
         """
         branch = branch or self.client.default_branch
         url = f"{self.client.address}/schema.graphql?branch={branch}"
 
         response = await self.client._get(url=url)
 
         if response.status_code != 200:
-            raise ValueError(f"Failed to fetch GraphQL schema: HTTP {response.status_code} - {response.text}")
+            response.raise_for_status()
 
         return response.text

Note: Using response.raise_for_status() will raise appropriate httpx exceptions that provide better context.


746-763: Consider using a more specific exception type.

Same recommendation as the async version: consider using response.raise_for_status() instead of a generic ValueError for better error semantics.

Apply this diff:

     def get_graphql_schema(self, branch: str | None = None) -> str:
         """Get the GraphQL schema as a string.
 
         Args:
             branch: The branch to get the schema for. Defaults to default_branch.
 
         Returns:
             The GraphQL schema as a string.
         """
         branch = branch or self.client.default_branch
         url = f"{self.client.address}/schema.graphql?branch={branch}"
 
         response = self.client._get(url=url)
 
         if response.status_code != 200:
-            raise ValueError(f"Failed to fetch GraphQL schema: HTTP {response.status_code} - {response.text}")
+            response.raise_for_status()
 
         return response.text
infrahub_sdk/spec/object.py (1)

636-652: Broad exception catching for context enrichment.

The try/except blocks catch all exceptions to enrich them with location context before re-raising as ValidationError. While broad, this pattern is acceptable for converting parsing errors into domain-specific exceptions with added context.

Consider catching more specific Pydantic validation exceptions if only those are expected:

from pydantic import ValidationError as PydanticValidationError

try:
    self._spec = InfrahubObjectFileData(**self.data.spec)
except PydanticValidationError as exc:
    raise ValidationError(identifier=str(self.location), message=str(exc))
infrahub_sdk/client.py (1)

1659-1689: New convert_object_type method is correctly implemented.

The method properly converts field mappings to JSON-serializable dicts and constructs the node from the GraphQL response. Note that passing raise_for_error=True will trigger the deprecation warning, but this appears intentional for this specific mutation.

Consider removing raise_for_error=True to avoid the deprecation warning, as the default behavior (None) provides the same HTTP error raising:

-        response = await self.execute_graphql(
-            query=CONVERT_OBJECT_MUTATION,
-            variables={
-                "node_id": node_id,
-                "fields_mapping": mapping_dict,
-                "target_kind": target_kind,
-            },
-            branch_name=branch_name,
-            raise_for_error=True,
-        )
+        response = await self.execute_graphql(
+            query=CONVERT_OBJECT_MUTATION,
+            variables={
+                "node_id": node_id,
+                "fields_mapping": mapping_dict,
+                "target_kind": target_kind,
+            },
+            branch_name=branch_name,
+        )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c63009 and f43c73a.

⛔ Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (69)
  • .github/workflows/ci.yml (5 hunks)
  • .github/workflows/repository-dispatch.yml (1 hunks)
  • .pre-commit-config.yaml (1 hunks)
  • .vale/styles/Infrahub/branded-terms-case-swap.yml (0 hunks)
  • changelog/+branch-graph-version-status.added.md (1 hunks)
  • changelog/+convert-object-type.added.md (1 hunks)
  • changelog/+f6791a3d.added.md (1 hunks)
  • changelog/+gql-command.added.md (1 hunks)
  • changelog/380.fixed.md (1 hunks)
  • changelog/464.housekeeping.md (1 hunks)
  • changelog/493.changed.md (1 hunks)
  • changelog/528.housekeeping.md (1 hunks)
  • changelog/560.added.md (1 hunks)
  • changelog/565.fixed.md (1 hunks)
  • docs/docs/infrahubctl/infrahubctl-graphql.mdx (1 hunks)
  • docs/docs/python-sdk/guides/python-typing.mdx (1 hunks)
  • docs/docs/python-sdk/topics/object_file.mdx (2 hunks)
  • docs/docusaurus.config.ts (1 hunks)
  • infrahub_sdk/branch.py (3 hunks)
  • infrahub_sdk/client.py (55 hunks)
  • infrahub_sdk/convert_object_type.py (1 hunks)
  • infrahub_sdk/ctl/branch.py (3 hunks)
  • infrahub_sdk/ctl/check.py (2 hunks)
  • infrahub_sdk/ctl/cli_commands.py (5 hunks)
  • infrahub_sdk/ctl/config.py (2 hunks)
  • infrahub_sdk/ctl/generator.py (4 hunks)
  • infrahub_sdk/ctl/graphql.py (1 hunks)
  • infrahub_sdk/ctl/repository.py (1 hunks)
  • infrahub_sdk/ctl/schema.py (4 hunks)
  • infrahub_sdk/generator.py (3 hunks)
  • infrahub_sdk/graphql/__init__.py (1 hunks)
  • infrahub_sdk/graphql/constants.py (1 hunks)
  • infrahub_sdk/graphql/plugin.py (1 hunks)
  • infrahub_sdk/graphql/query.py (1 hunks)
  • infrahub_sdk/graphql/renderers.py (3 hunks)
  • infrahub_sdk/graphql/utils.py (1 hunks)
  • infrahub_sdk/protocols.py (20 hunks)
  • infrahub_sdk/pytest_plugin/plugin.py (3 hunks)
  • infrahub_sdk/pytest_plugin/utils.py (2 hunks)
  • infrahub_sdk/schema/__init__.py (7 hunks)
  • infrahub_sdk/schema/main.py (1 hunks)
  • infrahub_sdk/schema/repository.py (1 hunks)
  • infrahub_sdk/spec/models.py (1 hunks)
  • infrahub_sdk/spec/object.py (21 hunks)
  • infrahub_sdk/spec/processors/data_processor.py (1 hunks)
  • infrahub_sdk/spec/processors/factory.py (1 hunks)
  • infrahub_sdk/spec/processors/range_expand_processor.py (1 hunks)
  • infrahub_sdk/spec/range_expansion.py (1 hunks)
  • infrahub_sdk/timestamp.py (2 hunks)
  • pyproject.toml (6 hunks)
  • tests/constants.py (1 hunks)
  • tests/fixtures/unit/test_graphql_plugin/python01.py (1 hunks)
  • tests/fixtures/unit/test_graphql_plugin/python01_after_annotation.py (1 hunks)
  • tests/fixtures/unit/test_graphql_plugin/python02.py (1 hunks)
  • tests/fixtures/unit/test_graphql_plugin/python02_after_annotation.py (1 hunks)
  • tests/integration/test_convert_object_type.py (1 hunks)
  • tests/unit/ctl/conftest.py (2 hunks)
  • tests/unit/ctl/test_schema_app.py (1 hunks)
  • tests/unit/sdk/checks/test_checks.py (1 hunks)
  • tests/unit/sdk/conftest.py (4 hunks)
  • tests/unit/sdk/graphql/conftest.py (1 hunks)
  • tests/unit/sdk/graphql/test_plugin.py (1 hunks)
  • tests/unit/sdk/graphql/test_query.py (1 hunks)
  • tests/unit/sdk/graphql/test_renderer.py (1 hunks)
  • tests/unit/sdk/spec/test_object.py (2 hunks)
  • tests/unit/sdk/test_client.py (2 hunks)
  • tests/unit/sdk/test_range_expansion.py (1 hunks)
  • tests/unit/sdk/test_repository.py (1 hunks)
  • tests/unit/sdk/test_schema.py (2 hunks)
💤 Files with no reviewable changes (1)
  • .vale/styles/Infrahub/branded-terms-case-swap.yml
🧰 Additional context used
📓 Path-based instructions (7)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

When implementing Infrahub checks, subclass InfrahubCheck and override validate(data); do not implement or rely on a check() method

Files:

  • infrahub_sdk/ctl/branch.py
  • infrahub_sdk/ctl/config.py
  • infrahub_sdk/schema/main.py
  • tests/unit/sdk/checks/test_checks.py
  • infrahub_sdk/generator.py
  • infrahub_sdk/graphql/utils.py
  • infrahub_sdk/pytest_plugin/plugin.py
  • tests/unit/ctl/conftest.py
  • infrahub_sdk/spec/processors/data_processor.py
  • tests/constants.py
  • infrahub_sdk/pytest_plugin/utils.py
  • infrahub_sdk/spec/processors/factory.py
  • infrahub_sdk/spec/range_expansion.py
  • infrahub_sdk/ctl/repository.py
  • infrahub_sdk/spec/processors/range_expand_processor.py
  • tests/unit/sdk/conftest.py
  • infrahub_sdk/spec/models.py
  • tests/unit/sdk/spec/test_object.py
  • tests/fixtures/unit/test_graphql_plugin/python01.py
  • infrahub_sdk/schema/repository.py
  • tests/fixtures/unit/test_graphql_plugin/python01_after_annotation.py
  • infrahub_sdk/client.py
  • infrahub_sdk/spec/object.py
  • infrahub_sdk/branch.py
  • infrahub_sdk/convert_object_type.py
  • infrahub_sdk/timestamp.py
  • tests/integration/test_convert_object_type.py
  • infrahub_sdk/ctl/cli_commands.py
  • infrahub_sdk/graphql/constants.py
  • infrahub_sdk/ctl/generator.py
  • tests/unit/sdk/test_range_expansion.py
  • infrahub_sdk/ctl/check.py
  • tests/unit/sdk/graphql/test_renderer.py
  • tests/unit/sdk/graphql/test_plugin.py
  • tests/unit/sdk/graphql/test_query.py
  • infrahub_sdk/graphql/__init__.py
  • tests/unit/sdk/test_repository.py
  • tests/fixtures/unit/test_graphql_plugin/python02.py
  • infrahub_sdk/ctl/graphql.py
  • tests/unit/sdk/test_client.py
  • infrahub_sdk/ctl/schema.py
  • tests/unit/ctl/test_schema_app.py
  • tests/unit/sdk/test_schema.py
  • infrahub_sdk/graphql/renderers.py
  • infrahub_sdk/graphql/plugin.py
  • tests/fixtures/unit/test_graphql_plugin/python02_after_annotation.py
  • infrahub_sdk/graphql/query.py
  • infrahub_sdk/schema/__init__.py
  • tests/unit/sdk/graphql/conftest.py
  • infrahub_sdk/protocols.py
infrahub_sdk/ctl/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

infrahub_sdk/ctl/**/*.py: Build CLI commands with Typer
Organize and keep all CLI commands within infrahub_sdk/ctl/

Files:

  • infrahub_sdk/ctl/branch.py
  • infrahub_sdk/ctl/config.py
  • infrahub_sdk/ctl/repository.py
  • infrahub_sdk/ctl/cli_commands.py
  • infrahub_sdk/ctl/generator.py
  • infrahub_sdk/ctl/check.py
  • infrahub_sdk/ctl/graphql.py
  • infrahub_sdk/ctl/schema.py
tests/unit/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Place and write unit tests under tests/unit/ (isolated component tests)

Files:

  • tests/unit/sdk/checks/test_checks.py
  • tests/unit/ctl/conftest.py
  • tests/unit/sdk/conftest.py
  • tests/unit/sdk/spec/test_object.py
  • tests/unit/sdk/test_range_expansion.py
  • tests/unit/sdk/graphql/test_renderer.py
  • tests/unit/sdk/graphql/test_plugin.py
  • tests/unit/sdk/graphql/test_query.py
  • tests/unit/sdk/test_repository.py
  • tests/unit/sdk/test_client.py
  • tests/unit/ctl/test_schema_app.py
  • tests/unit/sdk/test_schema.py
  • tests/unit/sdk/graphql/conftest.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use the custom pytest plugin (infrahub_sdk.pytest_plugin) fixtures for clients, configuration, and Infrahub-specific testing

Files:

  • tests/unit/sdk/checks/test_checks.py
  • tests/unit/ctl/conftest.py
  • tests/constants.py
  • tests/unit/sdk/conftest.py
  • tests/unit/sdk/spec/test_object.py
  • tests/fixtures/unit/test_graphql_plugin/python01.py
  • tests/fixtures/unit/test_graphql_plugin/python01_after_annotation.py
  • tests/integration/test_convert_object_type.py
  • tests/unit/sdk/test_range_expansion.py
  • tests/unit/sdk/graphql/test_renderer.py
  • tests/unit/sdk/graphql/test_plugin.py
  • tests/unit/sdk/graphql/test_query.py
  • tests/unit/sdk/test_repository.py
  • tests/fixtures/unit/test_graphql_plugin/python02.py
  • tests/unit/sdk/test_client.py
  • tests/unit/ctl/test_schema_app.py
  • tests/unit/sdk/test_schema.py
  • tests/fixtures/unit/test_graphql_plugin/python02_after_annotation.py
  • tests/unit/sdk/graphql/conftest.py
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

docs/**/*.{md,mdx}: Follow the Diataxis framework and classify docs as Tutorials, How-to guides, Explanation, or Reference
Structure How-to guides with required frontmatter and sections: introduction, prerequisites, step-by-step steps, validation, related resources
Structure Topics (Explanation) docs with introduction, concepts & definitions, background & context, architecture & design, connections, further reading
Use a professional, concise, informative tone with consistent structure across documents
Use proper language tags on all code blocks
Include both async and sync examples where applicable using the Tabs component
Add validation steps to guides to confirm success and expected outputs
Use callouts for warnings, tips, and important notes
Define new terms on first use and use domain-relevant terminology consistent with Infrahub’s model/UI
Conform to markdown style rules in .markdownlint.yaml and Vale styles in .vale/styles/

Files:

  • docs/docs/python-sdk/topics/object_file.mdx
  • docs/docs/python-sdk/guides/python-typing.mdx
  • docs/docs/infrahubctl/infrahubctl-graphql.mdx
infrahub_sdk/client.py

📄 CodeRabbit inference engine (CLAUDE.md)

infrahub_sdk/client.py: Use HTTPX for transport with proxy support (single proxy or HTTP/HTTPS mounts)
Support authentication via API tokens or JWT with automatic refresh

Files:

  • infrahub_sdk/client.py
tests/integration/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Place and write integration tests under tests/integration/ (tests against real Infrahub instances)

Files:

  • tests/integration/test_convert_object_type.py
🧠 Learnings (10)
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to infrahub_sdk/config.py : Use a Pydantic-based Config class with environment variable support for configuration

Applied to files:

  • infrahub_sdk/ctl/config.py
  • tests/unit/sdk/test_schema.py
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to infrahub_sdk/config.py : Environment variables for configuration must use the INFRAHUB_ prefix

Applied to files:

  • infrahub_sdk/ctl/config.py
  • infrahub_sdk/pytest_plugin/plugin.py
  • pyproject.toml
  • tests/unit/sdk/test_schema.py
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to **/*.py : When implementing Infrahub checks, subclass InfrahubCheck and override validate(data); do not implement or rely on a check() method

Applied to files:

  • tests/unit/sdk/checks/test_checks.py
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to tests/**/*.py : Use the custom pytest plugin (infrahub_sdk.pytest_plugin) fixtures for clients, configuration, and Infrahub-specific testing

Applied to files:

  • infrahub_sdk/pytest_plugin/plugin.py
  • tests/unit/sdk/conftest.py
  • tests/unit/sdk/spec/test_object.py
  • tests/unit/sdk/graphql/test_plugin.py
  • tests/fixtures/unit/test_graphql_plugin/python02.py
  • tests/unit/sdk/test_client.py
  • infrahub_sdk/graphql/plugin.py
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to infrahub_sdk/ctl/**/*.py : Organize and keep all CLI commands within infrahub_sdk/ctl/

Applied to files:

  • changelog/+gql-command.added.md
  • infrahub_sdk/ctl/cli_commands.py
  • infrahub_sdk/ctl/check.py
  • infrahub_sdk/ctl/graphql.py
  • tests/unit/sdk/test_schema.py
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to infrahub_sdk/ctl/**/*.py : Build CLI commands with Typer

Applied to files:

  • changelog/+gql-command.added.md
  • infrahub_sdk/ctl/cli_commands.py
  • infrahub_sdk/ctl/generator.py
  • infrahub_sdk/ctl/graphql.py
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to infrahub_sdk/client.py : Use HTTPX for transport with proxy support (single proxy or HTTP/HTTPS mounts)

Applied to files:

  • tests/unit/sdk/conftest.py
  • tests/unit/sdk/spec/test_object.py
  • infrahub_sdk/client.py
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Maintain a dual client pattern: InfrahubClient (async) and InfrahubClientSync (sync) must provide identical interfaces

Applied to files:

  • infrahub_sdk/client.py
  • tests/unit/sdk/test_schema.py
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to docs/**/*.{md,mdx} : Conform to markdown style rules in .markdownlint.yaml and Vale styles in .vale/styles/

Applied to files:

  • docs/docusaurus.config.ts
📚 Learning: 2025-08-24T13:35:12.998Z
Learnt from: CR
Repo: opsmill/infrahub-sdk-python PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T13:35:12.998Z
Learning: Applies to docs/**/*.{md,mdx} : Use proper language tags on all code blocks

Applied to files:

  • docs/docusaurus.config.ts
🧬 Code graph analysis (35)
infrahub_sdk/schema/main.py (1)
infrahub_sdk/protocols_base.py (1)
  • display_label (30-30)
tests/unit/sdk/checks/test_checks.py (1)
infrahub_sdk/checks.py (2)
  • log_error (114-115)
  • InfrahubCheck (33-175)
infrahub_sdk/generator.py (1)
infrahub_sdk/client.py (1)
  • start_tracking (198-217)
infrahub_sdk/pytest_plugin/plugin.py (2)
infrahub_sdk/pytest_plugin/utils.py (2)
  • find_repository_config_file (11-35)
  • load_repository_config (38-59)
infrahub_sdk/ctl/repository.py (1)
  • find_repository_config_file (27-51)
infrahub_sdk/spec/processors/data_processor.py (2)
infrahub_sdk/spec/processors/factory.py (1)
  • process_data (25-34)
infrahub_sdk/spec/processors/range_expand_processor.py (1)
  • process_data (19-56)
infrahub_sdk/pytest_plugin/utils.py (1)
infrahub_sdk/schema/repository.py (1)
  • InfrahubRepositoryConfig (182-267)
infrahub_sdk/spec/processors/factory.py (3)
infrahub_sdk/spec/models.py (1)
  • InfrahubObjectParameters (6-7)
infrahub_sdk/spec/processors/data_processor.py (2)
  • DataProcessor (5-10)
  • process_data (9-10)
infrahub_sdk/spec/processors/range_expand_processor.py (2)
  • RangeExpandDataProcessor (15-56)
  • process_data (19-56)
infrahub_sdk/ctl/repository.py (2)
infrahub_sdk/pytest_plugin/utils.py (1)
  • find_repository_config_file (11-35)
infrahub_sdk/schema/repository.py (1)
  • InfrahubRepositoryConfig (182-267)
infrahub_sdk/spec/processors/range_expand_processor.py (4)
infrahub_sdk/exceptions.py (1)
  • ValidationError (117-129)
infrahub_sdk/spec/range_expansion.py (1)
  • range_expansion (88-118)
infrahub_sdk/spec/processors/data_processor.py (2)
  • DataProcessor (5-10)
  • process_data (9-10)
infrahub_sdk/spec/processors/factory.py (1)
  • process_data (25-34)
tests/unit/sdk/conftest.py (1)
infrahub_sdk/schema/__init__.py (1)
  • set_cache (134-149)
tests/unit/sdk/spec/test_object.py (4)
tests/unit/sdk/conftest.py (3)
  • client (32-33)
  • schema_query_01_data (1851-1853)
  • client_with_schema_01 (1886-1888)
infrahub_sdk/schema/__init__.py (1)
  • set_cache (134-149)
infrahub_sdk/spec/object.py (6)
  • ObjectFile (633-661)
  • validate_format (179-198)
  • validate_format (654-658)
  • spec (637-643)
  • RelationshipDataFormat (36-44)
  • get_relationship_info (104-166)
infrahub_sdk/exceptions.py (1)
  • ValidationError (117-129)
tests/fixtures/unit/test_graphql_plugin/python01.py (2)
tests/fixtures/unit/test_graphql_plugin/python02.py (2)
  • CreateDevice (6-7)
  • CreateDeviceInfraDeviceUpsert (10-12)
tests/fixtures/unit/test_graphql_plugin/python02_after_annotation.py (2)
  • CreateDevice (9-10)
  • CreateDeviceInfraDeviceUpsert (13-15)
tests/fixtures/unit/test_graphql_plugin/python01_after_annotation.py (1)
tests/fixtures/unit/test_graphql_plugin/python01.py (6)
  • CreateDevice (8-9)
  • CreateDeviceInfraDeviceUpsert (12-14)
  • CreateDeviceInfraDeviceUpsertObject (17-21)
  • CreateDeviceInfraDeviceUpsertObjectName (24-25)
  • CreateDeviceInfraDeviceUpsertObjectDescription (28-29)
  • CreateDeviceInfraDeviceUpsertObjectStatus (32-33)
infrahub_sdk/client.py (2)
infrahub_sdk/convert_object_type.py (1)
  • ConversionFieldInput (43-61)
infrahub_sdk/node/node.py (2)
  • from_graphql (486-500)
  • from_graphql (1117-1131)
infrahub_sdk/spec/object.py (6)
infrahub_sdk/spec/models.py (1)
  • InfrahubObjectParameters (6-7)
infrahub_sdk/spec/processors/factory.py (2)
  • DataProcessorFactory (11-34)
  • process_data (25-34)
infrahub_sdk/yaml.py (5)
  • data (147-150)
  • kind (157-158)
  • validate_content (60-61)
  • validate_content (160-163)
  • InfrahubFileKind (20-22)
infrahub_sdk/spec/processors/range_expand_processor.py (1)
  • process_data (19-56)
infrahub_sdk/exceptions.py (2)
  • ObjectValidationError (132-139)
  • ValidationError (117-129)
infrahub_sdk/spec/menu.py (2)
  • spec (25-28)
  • validate_content (30-34)
infrahub_sdk/branch.py (1)
infrahub_sdk/protocols_base.py (1)
  • Enum (111-112)
infrahub_sdk/timestamp.py (1)
infrahub_sdk/exceptions.py (1)
  • TimestampFormatError (172-175)
tests/integration/test_convert_object_type.py (3)
infrahub_sdk/client.py (16)
  • convert_object_type (1659-1689)
  • convert_object_type (3006-3036)
  • get (390-406)
  • get (409-425)
  • get (428-444)
  • get (447-463)
  • get (466-482)
  • get (485-501)
  • get (503-561)
  • get (2199-2215)
  • get (2218-2234)
  • get (2237-2253)
  • get (2256-2272)
  • get (2275-2291)
  • get (2294-2310)
  • get (2312-2370)
infrahub_sdk/convert_object_type.py (2)
  • ConversionFieldInput (43-61)
  • ConversionFieldValue (21-40)
infrahub_sdk/testing/docker.py (1)
  • TestInfrahubDockerClient (36-47)
infrahub_sdk/ctl/cli_commands.py (1)
infrahub_sdk/ctl/repository.py (2)
  • find_repository_config_file (27-51)
  • get_repository_config (54-84)
infrahub_sdk/ctl/generator.py (1)
infrahub_sdk/ctl/repository.py (2)
  • find_repository_config_file (27-51)
  • get_repository_config (54-84)
tests/unit/sdk/test_range_expansion.py (1)
infrahub_sdk/spec/range_expansion.py (1)
  • range_expansion (88-118)
infrahub_sdk/ctl/check.py (1)
infrahub_sdk/ctl/repository.py (2)
  • find_repository_config_file (27-51)
  • get_repository_config (54-84)
tests/unit/sdk/graphql/test_renderer.py (2)
infrahub_sdk/graphql/renderers.py (2)
  • render_input_block (152-212)
  • render_query_block (83-149)
tests/unit/sdk/graphql/conftest.py (4)
  • query_data_no_filter (17-26)
  • query_data_alias (30-39)
  • query_data_fragment (43-54)
  • input_data_01 (103-113)
tests/unit/sdk/graphql/test_plugin.py (1)
infrahub_sdk/graphql/plugin.py (4)
  • FutureAnnotationPlugin (12-29)
  • generate_result_types_module (24-29)
  • generate_result_types_module (57-63)
  • generate_result_types_module (80-85)
tests/unit/sdk/graphql/test_query.py (1)
infrahub_sdk/graphql/query.py (2)
  • Mutation (46-77)
  • Query (31-43)
infrahub_sdk/graphql/__init__.py (2)
infrahub_sdk/graphql/query.py (2)
  • Mutation (46-77)
  • Query (31-43)
infrahub_sdk/graphql/renderers.py (3)
  • render_input_block (152-212)
  • render_query_block (83-149)
  • render_variables_to_string (69-80)
tests/fixtures/unit/test_graphql_plugin/python02.py (1)
tests/fixtures/unit/test_graphql_plugin/python01.py (2)
  • CreateDevice (8-9)
  • CreateDeviceInfraDeviceUpsert (12-14)
infrahub_sdk/ctl/graphql.py (5)
infrahub_sdk/schema/__init__.py (2)
  • get_graphql_schema (504-521)
  • get_graphql_schema (746-763)
infrahub_sdk/async_typer.py (2)
  • AsyncTyper (11-31)
  • command (29-31)
infrahub_sdk/ctl/client.py (1)
  • initialize_client (10-25)
infrahub_sdk/ctl/utils.py (1)
  • catch_exception (78-106)
infrahub_sdk/graphql/utils.py (2)
  • insert_fragments_inline (13-31)
  • remove_fragment_import (34-40)
infrahub_sdk/ctl/schema.py (1)
infrahub_sdk/schema/__init__.py (2)
  • SchemaWarning (108-111)
  • display (103-105)
tests/unit/sdk/test_schema.py (3)
infrahub_sdk/protocols.py (4)
  • BuiltinIPAddress (39-43)
  • BuiltinIPAddressSync (596-600)
  • BuiltinTag (249-251)
  • BuiltinTagSync (806-808)
infrahub_sdk/schema/__init__.py (1)
  • _get_schema_name (210-221)
infrahub_sdk/ctl/schema.py (1)
  • display_schema_load_errors (52-99)
tests/fixtures/unit/test_graphql_plugin/python02_after_annotation.py (2)
tests/fixtures/unit/test_graphql_plugin/python01.py (2)
  • CreateDevice (8-9)
  • CreateDeviceInfraDeviceUpsert (12-14)
tests/fixtures/unit/test_graphql_plugin/python02.py (2)
  • CreateDevice (6-7)
  • CreateDeviceInfraDeviceUpsert (10-12)
infrahub_sdk/graphql/query.py (1)
infrahub_sdk/graphql/renderers.py (3)
  • render_input_block (152-212)
  • render_query_block (83-149)
  • render_variables_to_string (69-80)
infrahub_sdk/schema/__init__.py (2)
infrahub_sdk/protocols_base.py (2)
  • save (210-216)
  • save (235-241)
infrahub_sdk/client.py (16)
  • get (390-406)
  • get (409-425)
  • get (428-444)
  • get (447-463)
  • get (466-482)
  • get (485-501)
  • get (503-561)
  • get (2199-2215)
  • get (2218-2234)
  • get (2237-2253)
  • get (2256-2272)
  • get (2275-2291)
  • get (2294-2310)
  • get (2312-2370)
  • _get (1023-1041)
  • _get (2833-2851)
tests/unit/sdk/graphql/conftest.py (1)
infrahub_sdk/protocols_base.py (1)
  • Enum (111-112)
infrahub_sdk/protocols.py (2)
infrahub_sdk/node/relationship.py (2)
  • RelationshipManager (99-219)
  • RelationshipManagerSync (222-341)
infrahub_sdk/protocols_base.py (11)
  • CoreNode (209-230)
  • IntegerOptional (123-124)
  • StringOptional (67-68)
  • BooleanOptional (147-148)
  • Dropdown (103-104)
  • RelatedNode (44-44)
  • Enum (111-112)
  • Boolean (143-144)
  • IPHost (127-128)
  • CoreNodeSync (234-255)
  • RelatedNodeSync (48-48)
🪛 LanguageTool
docs/docs/infrahubctl/infrahubctl-graphql.mdx

[grammar] ~3-~3: Use a hyphen to join words.
Context: ...# infrahubctl graphql Various GraphQL related commands. Usage: ```consol...

(QB_NEW_EN_HYPHEN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: unit-tests (3.13)
  • GitHub Check: unit-tests (3.12)
  • GitHub Check: unit-tests (3.11)
  • GitHub Check: unit-tests (3.10)
  • GitHub Check: unit-tests (3.9)
  • GitHub Check: documentation
  • GitHub Check: Cloudflare Pages

Comment on lines +1 to +56
# `infrahubctl graphql`

Various GraphQL related commands.

**Usage**:

```console
$ infrahubctl graphql [OPTIONS] COMMAND [ARGS]...
```

**Options**:

* `--install-completion`: Install completion for the current shell.
* `--show-completion`: Show completion for the current shell, to copy it or customize the installation.
* `--help`: Show this message and exit.

**Commands**:

* `export-schema`: Export the GraphQL schema to a file.
* `generate-return-types`: Create Pydantic Models for GraphQL query...

## `infrahubctl graphql export-schema`

Export the GraphQL schema to a file.

**Usage**:

```console
$ infrahubctl graphql export-schema [OPTIONS]
```

**Options**:

* `--destination PATH`: Path to the GraphQL schema file. [default: schema.graphql]
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.

## `infrahubctl graphql generate-return-types`

Create Pydantic Models for GraphQL query return types

**Usage**:

```console
$ infrahubctl graphql generate-return-types [OPTIONS] [QUERY]
```

**Arguments**:

* `[QUERY]`: Location of the GraphQL query file(s). Defaults to current directory if not specified.

**Options**:

* `--schema PATH`: Path to the GraphQL schema file. [default: schema.graphql]
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add required Diataxis frontmatter.

Docs under docs/ must declare their Diataxis classification via frontmatter; without it this page can’t be indexed correctly and violates the documentation guidelines. Please add the appropriate metadata at the top (e.g., classify this as a “Reference” page) before the heading.

As per coding guidelines.

Apply this diff:

+# ---
+# title: infrahubctl GraphQL CLI reference
+# description: Reference for the infrahubctl graphql command group and its subcommands.
+# type: Reference
+# ---
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# `infrahubctl graphql`
Various GraphQL related commands.
**Usage**:
```console
$ infrahubctl graphql [OPTIONS] COMMAND [ARGS]...
```
**Options**:
* `--install-completion`: Install completion for the current shell.
* `--show-completion`: Show completion for the current shell, to copy it or customize the installation.
* `--help`: Show this message and exit.
**Commands**:
* `export-schema`: Export the GraphQL schema to a file.
* `generate-return-types`: Create Pydantic Models for GraphQL query...
## `infrahubctl graphql export-schema`
Export the GraphQL schema to a file.
**Usage**:
```console
$ infrahubctl graphql export-schema [OPTIONS]
```
**Options**:
* `--destination PATH`: Path to the GraphQL schema file. [default: schema.graphql]
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.
## `infrahubctl graphql generate-return-types`
Create Pydantic Models for GraphQL query return types
**Usage**:
```console
$ infrahubctl graphql generate-return-types [OPTIONS] [QUERY]
```
**Arguments**:
* `[QUERY]`: Location of the GraphQL query file(s). Defaults to current directory if not specified.
**Options**:
* `--schema PATH`: Path to the GraphQL schema file. [default: schema.graphql]
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.
---
title: infrahubctl GraphQL CLI reference
description: Reference for the infrahubctl graphql command group and its subcommands.
type: Reference
---
# `infrahubctl graphql`
Various GraphQL related commands.
**Usage**:
🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: Use a hyphen to join words.
Context: ...# infrahubctl graphql Various GraphQL related commands. Usage: ```consol...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
In docs/docs/infrahubctl/infrahubctl-graphql.mdx around lines 1 to 56, the file
is missing required Diataxis frontmatter so the page can’t be indexed; add a
YAML frontmatter block at the very top of the file containing at minimum a
diataxis classification (e.g., diataxis: Reference) and a title (e.g., title:
"infrahubctl graphql"); ensure the frontmatter block is placed before the first
heading and includes any standard site keys you use (layout, slug, sidebar) so
the page conforms to the docs guidelines.

Comment on lines +127 to +133
def raise_for_error_deprecation_warning(value: bool | None) -> None:
if value is not None:
warnings.warn(
"Using `raise_for_error` is deprecated, use `try/except` to handle errors.",
DeprecationWarning,
stacklevel=1,
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Increase stacklevel for better deprecation warnings.

The stacklevel=1 points to the raise_for_error_deprecation_warning call itself, not the user's code. Increase it so users see which of their calls triggered the warning.

Apply this diff:

 def raise_for_error_deprecation_warning(value: bool | None) -> None:
     if value is not None:
         warnings.warn(
             "Using `raise_for_error` is deprecated, use `try/except` to handle errors.",
             DeprecationWarning,
-            stacklevel=1,
+            stacklevel=3,
         )

This will point to the actual execute_graphql or query_gql_query call in the user's code.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def raise_for_error_deprecation_warning(value: bool | None) -> None:
if value is not None:
warnings.warn(
"Using `raise_for_error` is deprecated, use `try/except` to handle errors.",
DeprecationWarning,
stacklevel=1,
)
def raise_for_error_deprecation_warning(value: bool | None) -> None:
if value is not None:
warnings.warn(
"Using `raise_for_error` is deprecated, use `try/except` to handle errors.",
DeprecationWarning,
stacklevel=3,
)
🤖 Prompt for AI Agents
In infrahub_sdk/client.py around lines 127 to 133, the deprecation warning uses
stacklevel=1 which points to the helper itself instead of the caller; change the
warnings.warn call to use a larger stacklevel (e.g. stacklevel=3) so the warning
points at the user's execute_graphql or query_gql_query call that triggered it,
leaving the message and warning class unchanged.

Comment on lines +210 to +213
for warning in warnings:
console.print(
f"[yellow] {warning.type.value}: {warning.message} [{', '.join([kind.display for kind in warning.kinds])}]"
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix SchemaWarningKind display usage

SchemaWarningKind.display is a method; joining the bound method objects prints <bound method ...> instead of the warning targets. Call the method so warnings render correctly.

Apply this diff to fix the display:

-        console.print(
-            f"[yellow] {warning.type.value}: {warning.message} [{', '.join([kind.display for kind in warning.kinds])}]"
-        )
+        console.print(
+            f"[yellow] {warning.type.value}: {warning.message} [{', '.join(kind.display() for kind in warning.kinds)}]"
+        )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for warning in warnings:
console.print(
f"[yellow] {warning.type.value}: {warning.message} [{', '.join([kind.display for kind in warning.kinds])}]"
)
for warning in warnings:
console.print(
f"[yellow] {warning.type.value}: {warning.message} [{', '.join(kind.display() for kind in warning.kinds)}]"
)
🤖 Prompt for AI Agents
In infrahub_sdk/ctl/schema.py around lines 210 to 213, the code joins
SchemaWarningKind.display bound method objects instead of their returned
strings; change the join to call the method for each kind (e.g., ',
'.join([kind.display() for kind in warning.kinds])) so the actual display
strings are rendered (ensure you call display() with any required arguments if
applicable).

Comment on lines +34 to +40
def remove_fragment_import(module: ast.Module) -> ast.Module:
"""Remove the fragment import from the module."""
for item in module.body:
if isinstance(item, ast.ImportFrom) and item.module == "fragments":
module.body.remove(item)
return module
return module
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix list modification during iteration.

Modifying a list while iterating over it can cause elements to be skipped. While this specific case happens to work because of the early return, the pattern is fragile and could break if the logic changes.

Apply this diff to use a safer approach:

 def remove_fragment_import(module: ast.Module) -> ast.Module:
     """Remove the fragment import from the module."""
-    for item in module.body:
-        if isinstance(item, ast.ImportFrom) and item.module == "fragments":
-            module.body.remove(item)
-            return module
+    module.body = [
+        item for item in module.body
+        if not (isinstance(item, ast.ImportFrom) and item.module == "fragments")
+    ]
     return module
🤖 Prompt for AI Agents
infrahub_sdk/graphql/utils.py around lines 34 to 40: the function
remove_fragment_import mutates module.body while iterating which is fragile;
instead build a new body that excludes any ast.ImportFrom with module ==
"fragments" (e.g. assign module.body = [item for item in module.body if not
(isinstance(item, ast.ImportFrom) and item.module == "fragments")]) and then
return module.

Comment on lines +34 to +38
if start_char.isdigit() and end_char.isdigit():
start_num = int(start_char)
end_num = int(end_char)
step = 1 if start_num <= end_num else -1
expanded_values.extend(str(i) for i in range(start_num, end_num + step, step))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Preserve zero padding for numeric ranges.

Casting to int and then str() strips leading zeros, so patterns like "[01-03]" incorrectly expand to "1"/"2"/"3". That breaks common interface naming schemes where the padding is significant.

Apply this diff:

-            if start_char.isdigit() and end_char.isdigit():
-                start_num = int(start_char)
-                end_num = int(end_char)
-                step = 1 if start_num <= end_num else -1
-                expanded_values.extend(str(i) for i in range(start_num, end_num + step, step))
+            if start_char.isdigit() and end_char.isdigit():
+                width = max(len(start_char), len(end_char))
+                start_num = int(start_char)
+                end_num = int(end_char)
+                step = 1 if start_num <= end_num else -1
+                expanded_values.extend(
+                    f"{i:0{width}d}" for i in range(start_num, end_num + step, step)
+                )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if start_char.isdigit() and end_char.isdigit():
start_num = int(start_char)
end_num = int(end_char)
step = 1 if start_num <= end_num else -1
expanded_values.extend(str(i) for i in range(start_num, end_num + step, step))
if start_char.isdigit() and end_char.isdigit():
width = max(len(start_char), len(end_char))
start_num = int(start_char)
end_num = int(end_char)
step = 1 if start_num <= end_num else -1
expanded_values.extend(
f"{i:0{width}d}" for i in range(start_num, end_num + step, step)
)
🤖 Prompt for AI Agents
In infrahub_sdk/spec/range_expansion.py around lines 34 to 38, the numeric
expansion currently casts start and end to int and then back to str which strips
leading zeros; change the logic to preserve zero padding by computing the
original width (e.g., max length of the start and end numeric strings), iterate
the integer range as before, and format each generated number using zfill or
equivalent to that width (so "[01-03]" expands to "01","02","03"); keep the step
sign logic identical and ensure the range end is inclusive.

Comment on lines +16 to +20
class SubstractParams(TypedDict):
seconds: NotRequired[float]
minutes: NotRequired[float]
hours: NotRequired[float]

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the typo in the class name.

The class name SubstractParams contains a spelling error. It should be SubtractParams to match the subtract method (lines 95, 184) and standard English spelling.

Apply this diff to fix the typo:

-class SubstractParams(TypedDict):
+class SubtractParams(TypedDict):
     seconds: NotRequired[float]
     minutes: NotRequired[float]
     hours: NotRequired[float]

And update the type annotation on line 83:

-        params: SubstractParams = {}
+        params: SubtractParams = {}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In infrahub_sdk/timestamp.py around lines 16 to 20, the TypedDict class is
misspelled as SubstractParams; rename the class to SubtractParams to match the
subtract method and correct spelling, and then update the type annotation at
line 83 to reference SubtractParams instead of SubstractParams so all usages and
annotations align.

Signed-off-by: Fatih Acar <fatih@opsmill.com>
@ogenstad ogenstad merged commit 8004be4 into stable Nov 10, 2025
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

group/ci Issue related to the CI pipeline type/documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.