OptixLog Docs
Python SDKPipeline API

Pipeline API

Construct Pipeline to ingest workflow nodes into a project graph, and understand how generated bindings delegate to it.

The Pipeline API is the write surface of the OptixLog Python SDK. Its single entry point — PipelineProject.ingest — creates or updates a workflow node in the project graph and wires its edges.

Constructing Pipeline

Pass an SDKClient to Pipeline. Then call .project() or .project_from() to get a PipelineProject scoped to a specific project.

pipeline_setup.py
from optixlog import SDKClient
from optixlog.pipeline import Pipeline

client = SDKClient(
    base_url="https://optixlog.leidos.com",
    api_key="sk-opt-your-key-here",
)

pipe = Pipeline(client)

# By project id string
project = pipe.project("proj_grating_7f3a")

# Or from a ProjectRef
ref = client.project("proj_grating_7f3a")
project = pipe.project_from(ref)

print(project.id)  # "proj_grating_7f3a"

The ingest method

PipelineProject.ingest has two call shapes. You must choose exactly one:

  1. Prompt shape — data + prompt: the server resolves where to place the node in the graph based on the natural-language prompt.
  2. Explicit graph shape — data + origin_nodes + forward_nodes: you supply the node ids for the preceding and following nodes directly.

You cannot mix prompt and explicit graph ids in the same call.

ingest_both_shapes.py
from optixlog_gen import SimulationNode

# Shape 1: prompt-guided placement
result = project.ingest(
    data=SimulationNode(config={"mesh": "fine"}, solver="fdtd"),
    prompt="FDTD simulation of a grating coupler at 1550 nm.",
)

# Shape 2: explicit graph placement
result = project.ingest(
    data=SimulationNode(config={"mesh": "fine"}, solver="fdtd"),
    origin_nodes=["node-abc123"],
    forward_nodes=["node-def456"],
)

See Ingesting Nodes for full examples and guidance on when to use each shape.

Generated bindings delegate here

The OptixClient and per-project wrapper classes produced by optixlog generate delegate directly to Pipeline.ingest. They add:

  • Typed node classes (SimulationNode, MeasurementNode, ...) with to_payload().
  • Per-project project() overloads, so passing the wrong node type is a static error.

If you don't use generated bindings, you can implement IngestibleNode protocol yourself — any class with a to_payload() -> dict method qualifies.

See Generated Bindings for setup.

On this page