Architecture
The three SDK surfaces — SDKClient, Management, and Pipeline — and how the generated OptixClient wraps them.
The OptixLog Python SDK has a deliberate layered structure. Understanding the layers prevents confusion about which import to use and why.
The three surfaces
SDKClient — core identity and session
SDKClient is the network session. It holds your base_url, api_key, timeout, retry settings, and custom headers. It knows how to make authenticated HTTP requests. It does not expose any domain methods.
from optixlog import SDKClient
client = SDKClient(
base_url="https://optixlog.leidos.com",
api_key="sk-opt-xxxx",
)client.project("project-id") returns a ProjectRef — a lightweight object containing only the project's id. ProjectRef intentionally exposes nothing else: no teams, no workflow_nodes, no ingest. It is a token, not a resource.
Management — read the domain
Management wraps an SDKClient and exposes the full read surface: project config, organization, teams, memberships, workflow nodes, node labels, project members, and audit events.
from optixlog.management import Management
management = Management(client)
project = management.project("proj_grating_7f3a")
config = project.config.get()
teams_page = project.teams.list(limit=50)Management never writes data; it is a read-only view.
Pipeline — write nodes into the graph
Pipeline wraps an SDKClient and exposes the ingest surface. Its ingest method creates (or updates) a workflow node in the project's graph and wires its edges.
from optixlog.pipeline import Pipeline
pipeline = Pipeline(client)
project = pipeline.project("proj_grating_7f3a")
# Ingest is documented in detail in the Pipeline API reference.Generated OptixClient — typed wrapper
OptixClient (from optixlog_gen) wraps both SDKClient and Pipeline. Its project() method is overloaded once per project in your schema, so calling client.project(Projects.GRATING_COUPLER_LAB) returns an object whose ingest() method only accepts node types from that project's schema.
from optixlog_gen import OptixClient, Projects, SimulationNode
client = OptixClient() # reads from credentials file or envOptixClient does not replace SDKClient — it wraps it. You can access the underlying SDKClient through client.sdk.
Import map
from optixlog import SDKClient # core session
from optixlog import JSONValue, ProjectRef, Page, EntityRef
from optixlog import OptixLogError, AuthenticationError, NotFoundError
from optixlog import MultipleResultsError, ValidationError
from optixlog.management import Management # read surface
from optixlog.pipeline import Pipeline # write surface
from optixlog.pipeline import Pipeline, PipelineProject, IngestResult, IngestibleNode
from optixlog_gen import OptixClient, Projects # generated (not in the package)Concrete node classes are generated, not imported
Node dataclasses like SimulationNode come from optixlog_gen (produced by optixlog generate), not from the optixlog package itself. You cannot import them from optixlog.
Surface boundaries
| Surface | Import | Can read? | Can write? | Type-checked per project? |
|---|---|---|---|---|
SDKClient | from optixlog import SDKClient | No | No | No |
Management | from optixlog.management import Management | Yes | No | No |
Pipeline | from optixlog.pipeline import Pipeline | No | Yes | No |
OptixClient | from optixlog_gen import OptixClient | No | Yes | Yes |
The server surface
The SDK communicates with a versioned API under the v0 prefix. The relevant endpoints are:
v0.whoami— identity check (used byoptixlog login).v0.projects.*— project and organization reads (used by Management).v0.codegen.schema— schema fetch (used byoptixlog generate).v0.ingest— node ingest (used by Pipeline).
You do not need to call these endpoints directly. The SDK handles them.