Skip to content

Pipeline APIs

fxquinox ships a small set of pipeline primitives on top of the publish chain: path resolution from a project's anatomy, a host-agnostic universal loader with scene inventory, a render farm queue, and multi-site sync. They are all reachable from the SDK and the HTTP API, and they are deliberately thin - the host (Houdini, Nuke, a farm blade) supplies only the host-specific bit; everything else is shared core.

Project anatomy, path resolution

A project's anatomy is a set of named templates (work, publish, …) and roots (named filesystem prefixes, e.g. work vs publish storage) stored on the Project. Templates are token strings like {root}/{project}/{entity}/{task}/v{version}/{product}.{ext} that resolve against an entity plus extra fields.

resolve_path turns a template into a concrete path for a specific entity:

path = fxq.resolve_path(
    template_key="publish",
    entity_type="Task",
    entity_id=task.id,
    root_name="work",       # which root to resolve against
    extra={"product": "lightingMain", "ext": "exr"},
)

Resolving on the server (not in each DCC) keeps every host and the farm in agreement about where files live, and means a studio can retarget storage by editing the anatomy in one place.

Universal loader, scene inventory

The universal loader lets any host place a published version without the core knowing which host it is. Each integration registers a loader for the product types it understands:

@loader.register_loader("houdini_file", product_types=["geometry", "render", "pointcache"])
def load_file_node(session, version_id, files, **_):
    ...   # host builds the node; the core resolves the files

To drive a loader UI, ask the server what is loadable into a context:

# everything publishable into a context (latest only)
items = fxq.browse_loadable(project_id=pid, product_type="render", latest_only=True)

Scene inventory keeps an open scene honest. Given the version ids currently loaded, it reports which are outdated so the host can offer an update:

inv = fxq.scene_inventory([v1_id, v2_id])   # each item: current / latest / outdated

This is the same contract the Houdini and Nuke adapters use.

Render farm

Submit and track farm jobs. The farm itself reports progress back through the update call:

job = fxq.submit_farm_job(task_id=task.id, version_id=ver_id, frames="1-100")
fxq.farm_jobs(status="running")            # list / filter tracked jobs
fxq.update_farm_job(job["id"], status="completed", progress=100)

Jobs are tracked records, so they flow through events and show up in activity like any other entity.

Multi-site sync (SiteSync)

For multi-location studios, SiteSync queues transfers of a representation between named sites and processes them as a batch:

fxq.request_sync(representation_id=rep_id, target_site_id=site_id)
fxq.sync_jobs(status="queued")             # list transfer jobs
fxq.process_sync_queue()                   # process the queue once → completed count

The full method surface is in the SDK reference.