Skip to content

Pipeline Configuration

K-Pipe has two pipeline types, each with its own config file in the bundle:

Type Config file Purpose
Publish kpipe-publish.toml Five-phase workflow that exports and versions scene data
Load kpipe-load.toml Ordered sequence of one or more steps that imports a published product into the scene

Both files share the same [pipeline.<key>] structure for top-level metadata, but their step declarations differ.


Publish pipelines

Pipeline definition

Each pipeline is a TOML table identified by a unique key:

[pipeline.blender_render_review_still]
name        = "Review Still"
dcc         = "blender"
tasks       = ["lighting", "animation"]
product_type = "review_png"
description = "Renders a still image of the active camera"
Field Required Description
name yes Display name shown in the DCC UI
dcc yes Which DCC runs this pipeline (blender, nuke, publisher, …)
product_type yes Product type this pipeline publishes. A template: {task}, {entity} and {entity_type} are filled in, so "{task}_review" gives one product per task (anim_review, comp_review). Integrate actions can publish further products with their own product_type field (same templates)
tasks no List of task names that show this pipeline. Empty list = show for all tasks
description no Short description shown below the pipeline name in the UI
icon no Blender icon identifier (e.g. "GESTURE_ROTATE") shown in front of the pipeline name in the Blender pipeline dropdown. Unknown names log a warning and show no icon
layers no Default true: the publish UI shows a layer selector that suggests previously published layer names (via Entity.get_product_layers()) and accepts new ones; the chosen name is set on ctx.layer before the pipeline runs (empty = main layer). Set to false for product types without layers
layer no Fixed layer name set on ctx.layer when the pipeline is built (PublishPipeline.from_config), overriding any UI value; combine with layers = false (e.g. layer = "staged")

Phases and steps

The five phases run in order: collect → validate → config → extract → integrate. Once the pipeline finishes — whether it completed all five phases or an action raised partway through — every action that already ran gets its optional cleanup() called, in reverse order (last action run, first cleaned up).

Each phase is declared as an array of tables. Every entry must have an action key naming the action class to run:

[[pipeline.blender_render_review_still.collect]]
action = "CollectBlenderSingleFrame"

[[pipeline.blender_render_review_still.collect]]
action = "CollectBlenderCamera"

[[pipeline.blender_render_review_still.config]]
action = "ConfigBlenderRenderOutput"
preset = "png_8"

[[pipeline.blender_render_review_still.extract]]
action = "ExtractBlenderRender"

[[pipeline.blender_render_review_still.integrate]]
action = "IntegrateMedia"
keep_files = true

[[pipeline.blender_render_review_still.integrate]]
action = "IntegrateKitsuMedia"
enabled = false

All fields other than action are passed directly to the action's dataclass constructor — see the Action Reference for each action's available fields.

Shared step fields

Field Default Description
action — Required. Class name of the action to instantiate
slot "main" Named slot used by this action for input and/or output
description action's default Label shown in the publish UI's action list. Falls back to the class name split into words
enabled true false skips the step. To let artists toggle a step, add a bool setting that targets "ClassName.enabled"

The publish UIs show no per-step checkboxes. Instead, each action in the list carries a status icon that updates while publishing (pending → running → succeeded / failed), and steps that are disabled — by enabled = false or by a setting — are greyed out.

Settings

Settings add UI controls to the publish panel. They are declared under [pipeline.<key>.settings] and their values are accessible inside actions via ctx.settings.

Inline syntax (simple types)

[pipeline.blender_render_review_still.settings]
note         = { text = "Note", type = "text", default_value = "" }
use_selection = { text = "Use selected strips", type = "bool", default_value = false }
kitsu_main   = { text = "Set main preview", type = "bool", default_value = false, target = "IntegrateKitsuMedia.set_as_main" }

Table syntax (required for enum)

[pipeline.blender_render_review_still.settings.status]
type          = "enum"
text          = "Kitsu Status"
default_value = ""
values        = [["", "Unchanged"], ["wff", "Waiting for feedback"], ["wfa", "Waiting for approval"]]
target        = "IntegrateKitsuMedia.task_status"

Setting fields

Field Description
type One of string, text, bool, int, float, enum, format, media_preset, scene
text Label shown in the UI
default_value Initial value
values (enum only) List of items. Each item is either a plain string (identifier = display name) or a [identifier, display_name] pair. An empty-string identifier renders as inactive ("Unchanged") in the dropdown
target Push this setting's value into an action field before the pipeline runs (see below)
parent Name of another setting to group this one under (see Setting hierarchy)
clear Default false. If true, the setting returns to its default_value after a successful publish — useful for per-publish values like a note. Values are kept when a publish fails, so it can be retried

Setting types

Type UI control Notes
string Single-line text input
text Multi-line text box Blender: drawn with UILayout.textbox() (Blender 5.2+), label above the box
bool Checkbox
int Integer field
float Float field
enum Dropdown Requires values list
format Dropdown The project's formats, shown by name ("Doris 2K"), value is the key. formats = [...] limits the keys; allow_empty = true adds a first "" entry labelled empty_label (default "Source")
media_preset Dropdown All media presets; media_type = "video" (or image, multilayer_image, audio) limits them
scene Dropdown Populated with scene names from the DCC at runtime

Targeting action fields

The target field on a setting pushes its value directly into a matching action's field before the pipeline runs. This lets you expose action parameters as UI controls without writing custom code.

Format: "ClassName.field_name" (every step of that class) or "<id>.field_name" (the step with that id)

target = "IntegrateKitsuMedia.task_status"

When a pipeline uses the same action class more than once, give the steps an id (a field every action has) and target them by it:

codec = { text = "Codec", type = "enum", default_value = "prores_4444", target = "master.preset" }
proxy = { text = "Proxy", type = "bool", default_value = true, target = ["proxy_frames.enabled", "proxy.enabled"] }

  [[pipeline.publisher_plate_prores.extract]]
  action = "ExtractFfmpegSequenceToVideo"
  id = "master"

To push into multiple actions at once, use an array:

target = ["IntegrateKitsuMedia.enabled", "OpenFolder.enabled"]

The setting value is only applied if an action with the matching class name or id exists in the pipeline — no error is raised if it doesn't.

Actions that write media expose a preset field plus flat override fields (quality, container, compression, …), so an enum setting targeting e.g. "ExtractFfmpegSequenceToVideo.preset" lets artists pick the output format. See Using presets in pipelines.

Targeting an action's enabled field is how a step is switched on or off at publish time:

open_folder = { text = "Open folder", type = "bool", default_value = false, target = "OpenFolder.enabled" }

Setting hierarchy

A setting with parent = "<setting name>" is drawn indented under that parent, grouped with the parent's other children. When the parent is a bool that's switched off, the whole group — the parent included — is greyed out; the parent's checkbox stays usable so it can be switched back on. Children can be parents themselves. Order in the file doesn't matter, and an unknown parent (or a cycle) logs a warning and puts the setting at the top level.

publish_to_kitsu = { text = "Publish to Kitsu", type = "bool", default_value = true, target = "IntegrateKitsuMedia.enabled" }
kitsu_set_main   = { text = "Set main preview", type = "bool", default_value = false, target = "IntegrateKitsuMedia.set_as_main", parent = "publish_to_kitsu" }

Full example

[pipeline.blender_render_review_still]
name         = "Review Still"
dcc          = "blender"
tasks        = []
product_type = "review_png"
description  = "Renders a still image of the current active camera"

  [pipeline.blender_render_review_still.settings]
  note         = { text = "Note", type = "text", default_value = "" }
  kitsu_upload = { text = "Publish to Kitsu", type = "bool", default_value = false, target = "IntegrateKitsuMedia.enabled" }
  kitsu_main   = { text = "Set main preview", type = "bool", default_value = false, target = "IntegrateKitsuMedia.set_as_main", parent = "kitsu_upload" }

  [pipeline.blender_render_review_still.settings.status]
  type          = "enum"
  text          = "Kitsu Status"
  default_value = ""
  values        = [["", "Unchanged"], ["wff", "Waiting for feedback"], ["wfa", "Waiting for approval"]]
  target        = "IntegrateKitsuMedia.task_status"
  parent        = "kitsu_upload"

  [[pipeline.blender_render_review_still.collect]]
  action = "CollectBlenderSingleFrame"

  [[pipeline.blender_render_review_still.collect]]
  action = "CollectBlenderCamera"

  [[pipeline.blender_render_review_still.config]]
  action = "ConfigBlenderRenderOutput"

  [[pipeline.blender_render_review_still.extract]]
  action = "ExtractBlenderRender"

  [[pipeline.blender_render_review_still.integrate]]
  action      = "IntegrateMedia"
  remap_frames = true
  keep_files  = true

  [[pipeline.blender_render_review_still.integrate]]
  action      = "IntegrateKitsuMedia"
  set_as_main = true
  enabled     = false

  [[pipeline.blender_render_review_still.integrate]]
  action = "CleanMedia"

Load pipelines

Load pipelines use one or more [[pipeline.<key>.load]] steps instead of the five publish phases. Steps run in the order they are declared — useful for chaining a pre-process action before the main load.

[pipeline.image_blender]
name          = "Image"
dcc           = "blender"
product_types = ["texture", "image", "review_png"]
tasks         = []
description   = "Load images as Blender image datablock"

  [[pipeline.image_blender.load]]
  action = "LoadBlenderMedia"
  source = "FILE"

Additional top-level fields for load pipelines

Field Description
product_types Product types this pipeline can load: names or wildcard patterns such as "*_review" (fnmatch: *, ?, [...]). The UI lists every published product type of the entity that matches, in pattern order
spaces Blender only: where the Load panel offers the pipeline, any of viewport (default), sequencer, shader_editor

The load step accepts the same action key and any action-specific fields. See LoadBlenderMedia and LoadBlenderTextureSet for available load actions.


Action loading order

Actions are discovered at runtime from three locations. Later entries override earlier ones, so project-level actions can replace built-ins by reusing the same class name:

  1. kpipe/actions/ (in packages/core) — built-in actions, available as soon as import kpipe is called
  2. kpipe_<dcc>/…/actions/ (in packages/<dcc>) — DCC-specific actions, loaded when the DCC extension registers
  3. {KPIPE_ROOT}/actions/ — project-level custom actions, loaded on first pipeline build