OptixLog Docs
Python SDKRecipes

Ingest a Simulation Run

Full example — generate bindings, build a SimulationNode, ingest it with a prompt, and inspect the IngestResult.

This recipe walks through the complete flow from generating typed bindings to ingesting a simulation node and reading the result.

Prerequisites

You need an optixlog.toml that references your project(s) and a saved login. If you are working offline, see Offline Testing with Fixtures first.

Step 1: Generate bindings

Generate the typed module

optixlog generate

This writes optixlog_gen.py (or updates it if the schema has changed). The file contains OptixClient, Projects, and all node classes for your schema.

Verify the output

python -c "from optixlog_gen import OptixClient, Projects, SimulationNode; print('OK')"

Step 2: Build a SimulationNode

Construct the node with all required fields. Optional fields fall back to their defaults when omitted:

ingest_simulation.py
from optixlog_gen import SimulationNode

node = SimulationNode(
    config={
        "mesh_resolution": "fine",
        "boundary_condition": "pml",
        "grid_size_nm": 10,
    },
    solver="fdtd",
    wavelength_nm=1550.0,
    other_param="sweep-baseline",
)

SimulationNode is a frozen dataclass — it cannot be mutated after construction. See Node Classes for the full field-type mapping.

Step 3: Ingest with a prompt

Pass the node and a natural-language prompt. OptixLog uses the prompt to wire the node into the workflow graph automatically:

ingest_simulation.py
from optixlog_gen import OptixClient, Projects, SimulationNode

client = OptixClient()

result = client.project(Projects.GRATING_COUPLER_LAB).ingest(
    data=SimulationNode(
        config={"mesh_resolution": "fine", "boundary_condition": "pml"},
        solver="fdtd",
        wavelength_nm=1550.0,
    ),
    prompt=(
        "Ran an FDTD simulation of the grating coupler design "
        "at 1550 nm with fine mesh and PML boundaries."
    ),
)

client.close()

Step 4: Inspect the IngestResult

ingest returns an IngestResult dataclass:

print("Node ID:", result.node_id)
print("Project:", result.project_id)
print("Created (vs updated):", result.created)
print("Origin nodes:", [r.id for r in result.origin_nodes])
print("Forward nodes:", [r.id for r in result.forward_nodes])

Prop

Type

Complete script

ingest_simulation.py
from optixlog_gen import OptixClient, Projects, SimulationNode

def main() -> None:
    client = OptixClient()
    try:
        result = client.project(Projects.GRATING_COUPLER_LAB).ingest(
            data=SimulationNode(
                config={"mesh_resolution": "fine", "boundary_condition": "pml"},
                solver="fdtd",
                wavelength_nm=1550.0,
            ),
            prompt=(
                "Ran an FDTD simulation of the grating coupler at 1550 nm "
                "with fine mesh and PML boundaries."
            ),
        )
    finally:
        client.close()

    print(f"Ingested node {result.node_id} (created={result.created})")
    for ref in result.origin_nodes:
        print(f"  origin: {ref.id} ({ref.type})")
    for ref in result.forward_nodes:
        print(f"  forward: {ref.id} ({ref.type})")


if __name__ == "__main__":
    main()

Next steps

On this page