Skip to content

Releases: opsmill/infrahub-sdk-python

v1.23.1

Choose a tag to compare

@fatih-acar fatih-acar released this 28 Aug 13:53

1.23.1 - 2026-08-28

Fixed

  • Fixed client.branch.validate() and infrahubctl branch validate, which raised a GraphQLError against every supported Infrahub server because the mutation requested a messages field that was removed from BranchValidate in Infrahub 1.1.0. (#1263)
  • The queries generated by all(), filters(), get() and relationship fetch() no longer request count on cardinality-many relationships. The SDK never read that value, and Infrahub resolved it with one extra database query per returned node and per relationship, on top of preventing the peer reads of those nodes from being batched into a single query.

v1.23.0

Choose a tag to compare

@wvandeun wvandeun released this 19 Aug 17:27
99a380a

1.23.0 - 2026-08-19

Removed

  • Removed client.branch.diff_data() from both the async and sync clients. The method relied on a GET /api/diff/data REST endpoint that does not exist in Infrahub, so every call returned a 404. Use client.get_diff_tree() to retrieve the full diff of a branch against its base branch, or client.get_diff_summary() for the list of changed nodes; both use the DiffTree GraphQL query. (#325)

Added

  • Added the Infrahub deployment ID to the infrahubctl info command output and a get_server_information() method (returning the server version and deployment ID) on the async and sync clients. (#1017)
  • Added transparent retry of HTTP 429 (rate-limited) responses on both InfrahubClient and InfrahubClientSync. Retries use jittered exponential backoff and honour a server-provided Retry-After header (delta-seconds or HTTP-date). The behaviour is tunable through four new Config fields (rate_limit_retry_enabled, rate_limit_max_retries, rate_limit_backoff_base, rate_limit_backoff_max), and a new RateLimitError exception is raised when retries are exhausted. (#1124)
  • Added support for tagging SDK requests with a priority via a new X-Priority header. A Priority enum (high, medium, low) is available from infrahub_sdk.constants; set Config.priority (env var INFRAHUB_PRIORITY) for a client-wide default emitted on every request, or pass priority= to individual operations to override it per request. When unset, no header is sent. Works identically on InfrahubClient and InfrahubClientSync. (#1151)
  • Add infrahubctl schema format command, an opinionated offline formatter that normalises the key ordering of schema files. Optional flags can also strip redundant default values (--strip-defaults), sort attributes/relationships by order_weight (--sort-by-order-weight), and backfill a missing order_weight (--backfill-order-weight).
  • Added retry() and cancel() methods to the task manager. The Task model now exposes available_actions along with can_retry / can_cancel helpers.
  • Added an opt-in include_diagnostics flag to the task manager's all(), filter(), and get() methods. When enabled, tasks expose an error field, and webhook-send tasks are returned as WebhookDeliveryTask instances carrying http_request / http_response delivery details.
  • Added support for the new IPAddress attribute kind. Values are exposed as bare ipaddress.IPv4Address/IPv6Address objects (no prefix) and serialized to a bare-address string when writing, alongside the existing IPHost and IPNetwork kinds.
  • The JSON schema generated for .infrahub.yml now warns when a definition has not said what it depends on, so YAML language servers flag it while the file is being edited. A Python transform or generator definition with no watch block is flagged, and so is a watch value that is not a mapping, including the bare watch: that parses as null and records nothing. Both warnings are advisory only: the models still accept every one of those forms. An empty watch: {} or files: [] stays clean, since either one records that the author checked and nothing beyond what Infrahub detects needs watching. The generated schema also picks up the watch block on generator definitions, which it was previously rejecting as an unknown property.
  • The request priority (X-Priority header) can now be carried on the client's RequestContext via a new priority field, alongside the existing client-wide Config.priority default and per-call priority= override. Resolution precedence is per-call priority= > request_context.priority > Config.priority > no header. The priority is emitted as a header only and is never included in the mutation body. Works identically on InfrahubClient and InfrahubClientSync.
  • Import pyarrow lazily in the line-delimited JSON importer so that infrahubctl commands other than object load no longer require the ctl extra (and its heavy pyarrow dependency) to be installed.

Changed

  • Paginated queries generated by all(), filters(), get() and resource pool allocation lookups now pass offset and limit as GraphQL variables instead of inlining them in the query text. The query document stays identical across pages, allowing the Infrahub server to reuse its cached query analysis, and the query is now rendered once per call instead of once per page. generate_query_data also accepts variable placeholder strings (for example "$offset") for its offset and limit arguments.

  • Raised the default Config.rate_limit_max_retries from 5 to 10, so a request shed with HTTP 429 keeps retrying (honouring Retry-After) for longer before raising RateLimitError. This lets background work ride out a longer burst of server-side backpressure. Callers that prefer to give up sooner can lower the value.

  • The hand-maintained schema models in infrahub_sdk.schema are now backed by the generated write/read contract (infrahub_sdk.schema.generated). Public names, import paths, and behavior methods are unchanged, but a few defaults and constraints now match the server contract:

    • AttributeKind.STRING has been removed. It was deprecated and kind="String" was already rejected server-side; use AttributeKind.TEXT instead.
    • Write and read models drop unknown fields silently (extra="ignore"). A submitted field that is not part of the write contract — read-level, internal, or a typo — is dropped rather than rejected, and a read model tolerates additional fields returned by a newer server.
    • Write-model defaults now match the server contract: relationship min_count/max_count default to 0 (was None), node branch defaults to "aware", generate_profile defaults to True, and generate_template defaults to False. This changes the round-trip output of programmatically-built schemas.

    Constructing AttributeSchema(name=..., kind=AttributeKind.TEXT, ...), NodeSchema, GenericSchema, RelationshipSchema, SchemaRoot, and the read-side *API models continues to work unchanged.

v1.22.3

Choose a tag to compare

@wvandeun wvandeun released this 19 Aug 13:13
db6e0c7

1.22.3 - 2026-08-19

Fixed

  • Register the infrahub_integration pytest marker under its real name. It was registered as infrahub_integraton, so integration tests raised a PytestUnknownMarkWarning on every run and failed to collect under --strict-markers. (#1231)
  • Fixed the load and check command descriptions in the infrahubctl schema help output and generated docs, which were cut off mid-sentence.

v1.23.0b0

v1.23.0b0 Pre-release
Pre-release

Choose a tag to compare

@wvandeun wvandeun released this 29 Jul 10:42
681b458

1.23.0b0 - 2026-07-29

Added

  • Added the Infrahub deployment ID to the infrahubctl info command output and a get_server_information() method (returning the server version and deployment ID) on the async and sync clients. (#1017)
  • Added a --dependencies flag to infrahubctl marketplace get. When downloading a schema or a collection, it now also resolves and downloads the schemas they depend on, via the marketplace API. Dependencies are grouped by the collection they belong to: prerequisite collections (and, for a single schema, dependencies that are members of a collection) are placed in their own <collection>/ directory, while dependencies that belong to no collection land in the output root. Referenced kinds the marketplace cannot resolve are reported as unresolved dependencies. A schema that already exists in the output directory is reconciled to a single file rather than duplicated across directories — kept by default, or overwritten with the new -y/--yes flag. (#1117)
  • Added transparent retry of HTTP 429 (rate-limited) responses on both InfrahubClient and InfrahubClientSync. Retries use jittered exponential backoff and honour a server-provided Retry-After header (delta-seconds or HTTP-date). The behaviour is tunable through four new Config fields (rate_limit_retry_enabled, rate_limit_max_retries, rate_limit_backoff_base, rate_limit_backoff_max), and a new RateLimitError exception is raised when retries are exhausted. (#1124)
  • Added support for tagging SDK requests with a priority via a new X-Priority header. A Priority enum (high, medium, low) is available from infrahub_sdk.constants; set Config.priority (env var INFRAHUB_PRIORITY) for a client-wide default emitted on every request, or pass priority= to individual operations to override it per request. When unset, no header is sent. Works identically on InfrahubClient and InfrahubClientSync. (#1151)
  • Added infrahubctl marketplace list, search, and show commands for browsing schemas and collections on the Infrahub Marketplace.
  • Added retry() and cancel() methods to the task manager. The Task model now exposes available_actions along with can_retry / can_cancel helpers.
  • Added an opt-in include_diagnostics flag to the task manager's all(), filter(), and get() methods. When enabled, tasks expose an error field, and webhook-send tasks are returned as WebhookDeliveryTask instances carrying http_request / http_response delivery details.
  • Added support for the new IPAddress attribute kind. Values are exposed as bare ipaddress.IPv4Address/IPv6Address objects (no prefix) and serialized to a bare-address string when writing, alongside the existing IPHost and IPNetwork kinds.
  • The request priority (X-Priority header) can now be carried on the client's RequestContext via a new priority field, alongside the existing client-wide Config.priority default and per-call priority= override. Resolution precedence is per-call priority= > request_context.priority > Config.priority > no header. The priority is emitted as a header only and is never included in the mutation body. Works identically on InfrahubClient and InfrahubClientSync.

Changed

  • Paginated queries generated by all(), filters(), get() and resource pool allocation lookups now pass offset and limit as GraphQL variables instead of inlining them in the query text. The query document stays identical across pages, allowing the Infrahub server to reuse its cached query analysis, and the query is now rendered once per call instead of once per page. generate_query_data also accepts variable placeholder strings (for example "$offset") for its offset and limit arguments.

  • Raised the default Config.rate_limit_max_retries from 5 to 10, so a request shed with HTTP 429 keeps retrying (honouring Retry-After) for longer before raising RateLimitError. This lets background work ride out a longer burst of server-side backpressure. Callers that prefer to give up sooner can lower the value.

  • The hand-maintained schema models in infrahub_sdk.schema are now backed by the generated write/read contract (infrahub_sdk.schema.generated). Public names, import paths, and behavior methods are unchanged, but a few defaults and constraints now match the server contract:

    • AttributeKind.STRING has been removed. It was deprecated and kind="String" was already rejected server-side; use AttributeKind.TEXT instead.
    • Write and read models drop unknown fields silently (extra="ignore"). A submitted field that is not part of the write contract — read-level, internal, or a typo — is dropped rather than rejected, and a read model tolerates additional fields returned by a newer server.
    • Write-model defaults now match the server contract: relationship min_count/max_count default to 0 (was None), node branch defaults to "aware", generate_profile defaults to True, and generate_template defaults to False. This changes the round-trip output of programmatically-built schemas.

    Constructing AttributeSchema(name=..., kind=AttributeKind.TEXT, ...), NodeSchema, GenericSchema, RelationshipSchema, SchemaRoot, and the read-side *API models continues to work unchanged.

Fixed

  • Fixed several cases where InfrahubClientSync had drifted from InfrahubClient: sync branch.merge now applies the same 120-second minimum timeout floor as the async client, and sync create(allow_upsert=True) now excludes the hfid from the mutation payload to avoid server-side upsert overhead. Also corrected an incorrect "feature not supported" message on async artifact fetch and a resource-pool error message typo.
  • Import pyarrow lazily in the line-delimited JSON importer so that infrahubctl commands other than object load no longer require the ctl extra (and its heavy pyarrow dependency) to be installed.

Housekeeping

  • Replaced markdownlint-cli2 with rumdl for markdown linting. This removes the Node.js/npm dependency for the markdown check, speeds up linting, and consolidates the configuration into pyproject.toml under [tool.rumdl]. (#1138)

v1.22.2

Choose a tag to compare

@ogenstad ogenstad released this 27 Jul 15:00
13f26b0

1.22.2 - 2026-07-27

Added

  • Added a --dependencies flag to infrahubctl marketplace get. When downloading a schema or a collection, it now also resolves and downloads the schemas they depend on, via the marketplace API. Dependencies are grouped by the collection they belong to: prerequisite collections (and, for a single schema, dependencies that are members of a collection) are placed in their own <collection>/ directory, while dependencies that belong to no collection land in the output root. Referenced kinds the marketplace cannot resolve are reported as unresolved dependencies. A schema that already exists in the output directory is reconciled to a single file rather than duplicated across directories — kept by default, or overwritten with the new -y/--yes flag. (#1117)
  • Added infrahubctl marketplace list, search, and show commands for browsing schemas and collections on the Infrahub Marketplace.

Fixed

  • Branch names containing URL-significant characters (such as # or /) are now percent-encoded in the GraphQL URL, so requests against those branches resolve correctly instead of returning a 404. (#1209)
  • Fixed several cases where InfrahubClientSync had drifted from InfrahubClient: sync branch.merge now applies the same 120-second minimum timeout floor as the async client, and sync create(allow_upsert=True) now excludes the hfid from the mutation payload to avoid server-side upsert overhead. Also corrected an incorrect "feature not supported" message on async artifact fetch and a resource-pool error message typo.

Housekeeping

  • Replaced markdownlint-cli2 with rumdl for markdown linting. This removes the Node.js/npm dependency for the markdown check, speeds up linting, and consolidates the configuration into pyproject.toml under [tool.rumdl]. (#1138)

v1.22.1

Choose a tag to compare

@ogenstad ogenstad released this 03 Jul 11:50
c478a75

1.22.1 - 2026-07-03

Added

  • Added a shortest_paths_only parameter to InfrahubClient.traverse_paths() and its sync equivalent (default None, deferring to the server). Set it to False to return all loopless paths up to max_paths instead of only the shortest one(s); previously path traversal always returned the shortest path(s) because the flag could not be set. PathTraversalResult now also parses truncated_at_depth, which is set when the search stopped at max_depth before exhausting the graph and None when it completed within budget. (#1119)

Fixed

  • Clarified the ValidationError raised when calling save(allow_upsert=True) on a node whose human-friendly identifier includes a CoreNumberPool-sourced attribute. The message now explains that the pool assigns a new value on every creation, so the HFID is never stable and the upsert would silently create a duplicate on each run, and points to the idempotent alternatives (look the node up by a stable field and reuse it, or set an explicit id). The resource manager guide was updated to match.

v1.22.0

Choose a tag to compare

@ogenstad ogenstad released this 23 Jun 16:29
4d1bad5

1.22.0 - 2026-06-23

Added

  • Added query_name parameter to all(), filters(), count() and get() methods in InfrahubClient and InfrahubClientSync to be used as meaningful GraphQL operation name for observability (#923)
  • Add infrahubctl graphql query-report to analyze a GraphQL query and report whether it targets unique nodes, which controls whether Infrahub limits artifact regeneration to changed nodes or regenerates all artifacts on any relevant node change. Supports --online to fetch the query from the server by name.
  • Added OrderByEntry and an Order.by field so query results can be ordered by attributes, related-node attributes, or node metadata, e.g. Order(by=[OrderByEntry(field="name__value", direction=OrderDirection.DESC)]). The Order.node_metadata field is deprecated; use by with the node_metadata__created_at / node_metadata__updated_at fields instead.
  • Added graph traversal support for Infrahub 1.10: InfrahubClient.traverse_paths() (shortest path(s) between two nodes), InfrahubClient.reachable_nodes() (nodes of given kinds reachable from a source), and InfrahubClient.path_exists() (boolean convenience for checks) — all with sync equivalents. Source and destination accept either a node id or an InfrahubNode; kind filters accept kind strings or protocol classes; each PathNode in the result exposes .fetch() to resolve the full node (store-backed). Calling these against a pre-1.10 server raises a clear VersionNotSupportedError.

Fixed

  • Calling .save(allow_upsert=True) on a node whose human-friendly identifier contains a CoreNumberPool-sourced attribute now raises a clear ValidationError instead of crashing with an opaque backend error. (#339)

  • RelatedNode, RelatedNodeSync, RelationshipManager and RelationshipManagerSync are now generic over their peer type, and infrahubctl protocols parameterises generated relationships accordingly (e.g. device: RelatedNode[NetworkDevice], interfaces: RelationshipManager[NetworkInterface]).

    Traversing a relationship via .peer, .peers or indexing now preserves the peer's type instead of collapsing to the dynamic InfrahubNode, so chains such as device.rack.peer.name.value type-check under mypy/ty without casts. Existing un-parameterised RelatedNode / RelationshipManager usage is unaffected — the peer type defaults to InfrahubNode / InfrahubNodeSync, preserving current behaviour. (#1063) (#1063)

  • Cardinality-one relationships in generated protocols are now typed with a RelationshipAttribute[...] descriptor. It still reads back as a typed RelatedNode[Peer] (so .peer keeps the peer type), but it accepts assignment of an id string, an HFID, a peer node, or None — mirroring the runtime InfrahubNode.__setattr__, which wraps the assigned value in a RelatedNode.

    Previously relationships were typed read-only as RelatedNode, so the documented way of setting a relationship (node.rel = "<id>" or node.rel = peer_node) failed under mypy/ty with an assignment error. The descriptor only appears in generated protocols and is never instantiated at runtime.

    Because the new typing lives in the generated protocols, existing projects must regenerate them with infrahubctl protocols to pick up the change — it does not take effect for already-generated protocol files. (#1064) (#1064)

  • Calling .save(allow_upsert=True) on a node hydrated by from_graphql no longer silently clears optional one-cardinality relationships that the GraphQL response didn't fetch. Explicitly assigning node.rel = None still clears the relationship. (#1080)

  • Send the GraphQL operation name as operationName in the request payload so tracing and observability tools can identify each query.

v1.21.1

Choose a tag to compare

@minitriga minitriga released this 05 Jun 15:49
3c6b5c0

Changed

  • infrahubctl marketplace get --collection now downloads each member schema individually into a <output_dir>/<collection name>/<schema name>.yml layout (for example schemas/base-schemas/dcim.yml), instead of dumping version-suffixed files flat into the output directory. Filenames no longer carry the version, matching single-schema downloads, so re-downloading a collection overwrites cleanly rather than accumulating stale versions. If two members share a schema name across namespaces, those members are written to <output_dir>/<collection name>/<namespace>/<schema name>.yml instead of overwriting each other. (#1057)

Fixed

  • Fix infrahubctl printing a spurious Error: 1 and Python traceback after the human-readable error message when a command exits with typer.Exit. The CLI now exits cleanly with only the intended error output. (#1047)****

v1.21.0

Choose a tag to compare

@ogenstad ogenstad released this 29 May 15:39
c985782

1.21.0 - 2026-05-29

Added

  • Add infrahubctl marketplace get for fetching schemas and collections from the Infrahub Marketplace. Auto-detects schemas vs collections by namespace/name, supports --version for pinning, --collection to force the collection path, --stdout to stream content for piping (status messages on stderr), and --marketplace-url / INFRAHUB_MARKETPLACE_URL to point at staging or local instances. (#952)

Changed

  • Change default value of sync_with_git parameter in branch.create() from True to False to match UI behavior. (#224)

Fixed

  • Improve error message when a single node is passed to a cardinality-many relationship. (#174)

v1.20.1

Choose a tag to compare

@ogenstad ogenstad released this 20 May 13:44
98bb218

1.20.1 - 2026-05-20

Added

  • Added SHA-1 idempotency primitives for CoreFileObject nodes:

    • InfrahubNode.matches_local_checksum(source) / sync variant — compare a local bytes | Path | BinaryIO source against the node's server-stored checksum without invoking a transfer.
    • InfrahubNode.upload_if_changed(source, name=None) / sync variant — stage + save only when the local source differs from the server, returning an UploadResult(was_uploaded, checksum) dataclass.
    • download_file(..., skip_if_unchanged=True) — short-circuit the download when dest already exists on disk with a matching SHA-1. Returns 0 bytes written when skipped.

    A shared sha1_of_source helper (streaming, 64 KiB chunks) centralises the hashing convention in infrahub_sdk.file_handler.

Fixed

  • Skip mandatory field validation during object loading when object_profile is specified. (#908)
  • Render schema rejections originating in an extensions: block as a readable one-line message in infrahubctl schema load, instead of crashing with ValueError: invalid literal for int(). (#1007)
  • Add MERGING branch status so that a merging branch can still be correctly retrieved. (#1037)