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.
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:
- Prompt shape —
data + prompt: the server resolves where to place the node in the graph based on the natural-language prompt. - 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.
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, ...) withto_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.