Using the Typed Client
How to construct OptixClient, call project() with typed overloads, use the .sdk escape hatch, and close the connection.
OptixClient is the entry point generated into optixlog_gen.py. It auto-fills credentials from your saved login and gives you per-project ingest overloads that are checked at type-check time.
Constructing OptixClient
OptixClient takes optional base_url and api_key keyword arguments. When you omit them — which is the normal case after running optixlog login — it calls resolve_credential() to fill them from:
OPTIXLOG_API_KEY/OPTIXLOG_BASE_URLenvironment variables.~/.optixlog/credentials.toml(written byoptixlog login).
from optixlog_gen import OptixClient
# Normal: use saved login credentials.
client = OptixClient()
# Override for a specific environment or service account.
client = OptixClient(
base_url="https://optixlog.leidos.com",
api_key="sk-opt-xxxx",
)Any additional keyword arguments (e.g. timeout_seconds, max_retries, user_agent) are forwarded to the underlying SDKClient.
client = OptixClient(timeout_seconds=60.0, max_retries=3)Credential hygiene
Never hard-code api_key in source files you commit. Use OPTIXLOG_API_KEY or the saved profile written by optixlog login.
Calling project()
project() is overloaded once for each project in your schema. You identify the project via the Projects constants:
from optixlog_gen import OptixClient, Projects
client = OptixClient()
# Each call returns a project-specific typed wrapper.
grating = client.project(Projects.GRATING_COUPLER_LAB) # _Project_proj_grating_7f3a
modulator = client.project(Projects.MODULATOR_PROGRAM) # _Project_proj_modulator_22b1The Projects constants are Literal-typed:
class Projects:
GRATING_COUPLER_LAB: Literal["proj_grating_7f3a"] = "proj_grating_7f3a"
MODULATOR_PROGRAM: Literal["proj_modulator_22b1"] = "proj_modulator_22b1"This Literal annotation is what lets pyright and mypy resolve the correct overload — and therefore the correct node-type union — from a single constant reference.
Ingesting with the typed wrapper
Once you have a project wrapper, call ingest with either a prompt (AI-assisted edge wiring) or explicit origin_nodes / forward_nodes (manual edge wiring):
from optixlog_gen import OptixClient, Projects, SimulationNode
client = OptixClient()
grating = client.project(Projects.GRATING_COUPLER_LAB)
result = grating.ingest(
data=SimulationNode(config={"mesh": "fine"}, solver="fdtd"),
prompt="Simulated a grating coupler with 220 nm Si thickness.",
)
print(result.node_id, result.created)result = grating.ingest(
data=SimulationNode(config={"mesh": "coarse"}, solver="eme"),
origin_nodes=["node_abc123"],
forward_nodes=[],
)See IngestResult for a full description of the returned object.
The .sdk escape hatch
OptixClient.sdk returns the underlying SDKClient. Use it when you need the Management API or any other low-level access alongside your pipeline calls:
from optixlog import SDKClient
from optixlog.management import Management
from optixlog_gen import OptixClient
client = OptixClient()
# Management API via the escape hatch.
mgmt = Management(client.sdk)
project = mgmt.project("proj_grating_7f3a")
config = project.config.get()
print(config.name)
# Pipeline API via the typed client.
grating = client.project(Projects.GRATING_COUPLER_LAB)The sdk property is read-only; you cannot replace the underlying SDKClient after construction.
Closing the client
Call close() when you are done, or use the client as a context manager if your generated file wraps it (the underlying SDKClient.close() releases connection resources):
client = OptixClient()
try:
result = client.project(Projects.GRATING_COUPLER_LAB).ingest(
data=SimulationNode(config={}, solver="fdtd"),
prompt="Baseline run.",
)
finally:
client.close()Connection reuse
A single OptixClient instance is safe to reuse across multiple ingest calls and across different projects. Create one instance per process and share it.