Repository navigation
feature: provide a synchronous ObjectFile.process() so object files can be loaded from sync code #1310
Description
Component
Python SDK
Describe the Feature Request
ObjectFile.process() exists only as a coroutine, so object files cannot be loaded from synchronous code.
infrahub_sdk/spec/object.py:
class InfrahubObjectFileData(BaseModel):
async def process(self, client: InfrahubClient, branch: str | None = None) -> None: # :236
class ObjectFile(InfrahubFile):
async def process(self, client: InfrahubClient, branch: str | None = None) -> None: # :706Both take InfrahubClient (async) specifically, and the supporting methods are async throughout — validate_format, validate_object, validate_related_nodes, create_node, create_related_nodes, get_peer_schema, plus the module-level get_relationship_info.
Everywhere else the SDK offers a synchronous mirror (InfrahubClientSync, InfrahubNodeSync, InfrahubBranchManagerSync, the sync ObjectStore methods, and so on). Object-file loading is the gap.
Describe the Use Case
The opsmill.infrahub Ansible collection cannot offer object-file loading at all. The collection is synchronous by architectural decision — its ADR-0003 and constitution both forbid the async client, because Ansible's execution model is synchronous and per-task — so there is no way to reach process() without violating that.
The practical effect for users: object files that load fine with infrahubctl object load cannot be loaded from a playbook. Bulk object definition from Ansible degrades to a loop: over a single-node module — one round trip per object, and no access to range expansion, which is the main reason to use an object file for something like 48 interfaces on a switch. Teams that keep object files in a repo for infrahubctl end up expressing the same data twice in two formats.
The alternative — reimplementing the loader against sync API inside the collection — would duplicate validation, relationship resolution and range expansion that the SDK already owns, and would drift from infrahubctl behaviour. That is not a road worth going down for a format the SDK defines.
Worth noting that range expansion itself is already synchronous and reusable (infrahub_sdk/spec/range_expansion.py is pure functions). The blocker is only the loader that consumes it.
The same constraint applies to infrahub_sdk/spec/menu.py, if a sync path there is also wanted.
Additional Information
Adjacent existing issues in this area: #367 (refactor validate_content for ObjectFile), #589 (dynamic typing for object spec files), #24 (remove redundant code in sync vs async client), #1276 (generated sync protocols inherit async base classes).
Blocking collection issue: opsmill/infrahub-ansible#403, filed as state/blocked pending this.
Activity