OptixLog Docs
CLIWorkflows

Multi-Project Setup

Select multiple projects with init --all or --project. How optixlog.toml and optixlog_gen.py scale across many projects.

A single optixlog.toml can reference multiple projects. optixlog generate fetches the schema for each one and emits a single typed module containing all project node classes and a Projects namespace with constants for every project id.

Selecting multiple projects

All accessible projects

The simplest option: select every project your API key can access:

optixlog init --all

Specific projects

Select only the projects you need, by id or by name (case-insensitive, repeatable):

# By id
optixlog init \
  --project proj_grating_7f3a \
  --project proj_modulator_22b1

# By name
optixlog init \
  --project "Grating Coupler Lab" \
  --project "Modulator Program"

Interactive picker

Without --all or --project, init shows an interactive project picker (checkbox if questionary is installed, numbered list otherwise). You can select any subset of accessible projects.

After the initial setup

To add or remove projects from an existing optixlog.toml, re-run init with --force:

# Replace the project list with all accessible projects
optixlog init --all --force

# Add one specific project to a new selection
optixlog init --project proj_grating_7f3a --project proj_new_abc --force

Then regenerate:

optixlog generate

What optixlog.toml looks like with multiple projects

optixlog.toml
[optixlog]
api_base_url = "https://optixlog.leidos.com"
schema_version = 1

[codegen]
output_path = "optixlog_gen.py"
module_style = "single_file"

[[projects]]
id = "proj_grating_7f3a"
name = "Grating Coupler Lab"

[[projects]]
id = "proj_modulator_22b1"
name = "Modulator Program"

Add as many [[projects]] tables as needed. There is no enforced limit.

How the generated module scales

optixlog generate fetches all configured project schemas in one call and emits a single module. The module contains:

  • A Projects namespace with one Literal constant per project:

    class Projects:
        GRATING_COUPLER_LAB = "proj_grating_7f3a"
        MODULATOR_PROGRAM    = "proj_modulator_22b1"
  • One node class per node type across all projects:

    @dataclass(frozen=True, kw_only=True)
    class SimulationNode:
        config: Mapping[str, JSONValue]
        solver: Literal["fdtd", "eme", "varfdtd"]
        wavelength_nm: float = 1550.0
        # ...
        def to_payload(self) -> dict[str, JSONValue]: ...
  • An OptixClient with overloaded project() methods — one overload per project id. Passing a project id to project() returns a PipelineProject typed to accept only node classes that belong to that project. Passing a node type not in a project's schema is a static type error (pyright reportArgumentType, mypy [call-overload]):

    client = OptixClient()
    
    # OK: SimulationNode is in GRATING_COUPLER_LAB's schema
    client.project(Projects.GRATING_COUPLER_LAB).ingest(
        data=SimulationNode(config={}, solver="fdtd"),
        prompt="Simulated a grating coupler.",
    )
    
    # Static type error: SimulationNode is not in MODULATOR_PROGRAM's schema
    client.project(Projects.MODULATOR_PROGRAM).ingest(
        data=SimulationNode(config={}, solver="fdtd"),  # reportArgumentType
        prompt="Wrong project.",
    )

The number of overloads and node classes scales linearly with the number of projects and node types. For large organizations with many projects, consider using module_style = "package" for better editor performance.

module_style: single_file vs. package

single_filepackage
OutputOne optixlog_gen.py fileOne optixlog_gen/ directory
Importfrom optixlog_gen import ...from optixlog_gen import ... (same)
Best forSmall to medium project countsLarge project counts, better editor indexing

Change the style in optixlog.toml and regenerate:

[codegen]
module_style = "package"
optixlog generate

Node-to-project mapping

The [[projects]] array in optixlog.toml records which projects to generate for. It does not store which node types belong to which project — that mapping is derived from each project's schema at generate time.

This means adding a new node type to a project on the server does not require updating optixlog.toml. It requires only re-running optixlog generate.

Non-interactive multi-project init (CI)

optixlog init \
  --all \
  --output optixlog_gen.py \
  --module-style single_file \
  --no-input

Or with explicit project selection:

optixlog init \
  --project proj_grating_7f3a \
  --project proj_modulator_22b1 \
  --output optixlog_gen.py \
  --no-input

Duplicate projects are collapsed

If you pass the same project id (or a name that resolves to the same id) multiple times via --project, the duplicate is silently dropped. Server ordering is preserved in the final list.

On this page