Skip to content

Getting Started

miura-nexus is the Python client for Nexus. You install it, authenticate, and run a first end-to-end call — upload simulation files, verify the cases Nexus discovered, transform those cases with a recipe, and read the result table.

Documentation version

The version in the header is the client build used to generate this site. Your installed miura-nexus package may show a different number until you upgrade.

Install

python -m pip install miura-nexus
# optional extras: python -m pip install "miura-nexus[pandas,sigma,torch]"
py -m pip install miura-nexus
# optional extras: py -m pip install "miura-nexus[pandas,sigma,torch]"

Quick start

Authenticate against your Nexus deployment. Use any one of: the miura-auth CLI, the MIURA_NEXUS_API_KEY environment variable, or a stored credentials file.

# Option A — miura-auth (stores a token locally)
miura-auth token set --token "<TOKEN>"
miura-auth test   # exit 0 when a token is stored

# Option B — environment variable for this shell
export MIURA_NEXUS_API_KEY="<TOKEN>"
# Option A — miura-auth (stores a token locally)
miura-auth token set --token "<TOKEN>"
miura-auth test   # exit 0 when a token is stored

# Option B — environment variable for this session
$env:MIURA_NEXUS_API_KEY="<TOKEN>"

Each folder below represents one simulation:

cases/
├── case_000001/
│   └── field.xdmf
└── case_000002/
    └── field.xdmf

Nexus groups the files that belong to one simulation into a case — the unit of work for that simulation. Here each case_* folder is one case; the file inside it is what that case carries.

First upload and admit those cases so you can inspect what Nexus discovered. Then process exactly those admitted cases with a recipe.

1. Upload and inspect cases

Describe the layout once with CaseStructure.folder. From that definition, Nexus derives a schema that checks each folder and a grouping that turns each folder into one processable case. Member names are roles — the part each file plays inside the case:

from pathlib import Path

from miura import Nexus
from miura.sdk import (
    CaseStructure,
    File,
    LocalDataSource,
    Number,
    capture,
    one_or_more,
)

# Digits in case_000001 become the case identifier
case_id = capture("case_id", Number(min_digits=6, max_digits=6))

# Each matching folder is one case; result_field is the role of field.xdmf
structure = CaseStructure.folder(
    path="case_" + case_id,
    members={"result_field": File("field.xdmf")},
)

# Gate: reject trees that do not match this layout
schema = structure.schema(count=one_or_more())

# Build the case-grouping rule from this structure
grouping = structure.case_grouping()

with Nexus() as nexus:
    project = nexus.create_project("feature-showcase")
    simulations = project.create_collection("simulations", schema=schema)

    # Validate, upload, and admit cases in one step
    data_path = Path("/my-simulations/cases")
    upload = simulations.upload(LocalDataSource(data_path), case_grouping=grouping)

    # Browse the admitted cases and the logical assets they published
    case_set = simulations.case_set(upload.cases)
    try:
        case_set.get_projection()
    except Exception:
        case_set.materialize_projection()
    cases = case_set.list_cases()
    assets = case_set.list_logical_assets()

You should see two cases (case_000001, case_000002), each with role result_field. Logical assets are the published pieces of those cases: each keeps that role and adds a modality — the platform type of the content. Here result_field publishes as modality field. Keep those admitted cases — you will pin them into a recipe next.

upload() validates and applies the upload in one operation. To inspect validation results before applying it, use simulations.plan(...).

2. Process those cases with a recipe

Continue in the same project. Deploy a recipe pinned to the admitted cases from the upload, run it, and read the result table:

from miura.adapters.dataframe import to_dataframe
from miura.sdk import RecipeSpec, Schema
from miura.sdk.sigma import sigma

# Collection that receives the extracted table rows
tables = project.create_collection(
    "tables",
    schema=Schema.permissive(),
)

# Pull param_1 from each case's XDMF Information entry
dataset_generator = sigma.DataSetGenerator(
    sigma.GlobalExtractionSchema(
        sealed_algorithm={"global_param_name": "param_1"},
    )
)
spec = RecipeSpec.from_sigma_dataset_generator(
    source=simulations.name,
    target=tables.name,
    dataset_generator=dataset_generator,
    writer="parquet_tabular",
)
recipe = project.deploy_recipe(
    "simulations-to-tables",
    spec,
    description="Quick start simulations to tables",
    cases=upload.cases,  # pin to the admitted cases from the upload
)
recipe.run().wait()

df = to_dataframe(tables, limit_rows=10)
print(df.head())
   param_1
0     1.02
1     0.97

writer="parquet_tabular" writes the extracted parameters as Parquet tables. See Transforming data for writer ids and validation.

Needs the [pandas,sigma] extras (see Install). The complete combined script is quick_start.py. More detail is in the user guide.

This example uses one folder per simulation. When a simulation is assembled from several directory trees, shared files, or values stored inside a table, see Describing your data.

User guide

Topic Section
Upload data, folder layout (CaseStructure.folder) Uploading data
Import from a remote bucket an admin registered Import files from a remote connector
Group cases, browse assets, tag items, select work Describing your data
Build, validate, and run recipe specs Transforming data
Read collections or published tables with pandas / PyTorch Working with results
Choose an upgrade path Migration guides

Snippets use Nexus(). Example scripts are listed below.

API Reference

Generated module docs live under API Reference. Useful entry points:

Topic API page
Sync client Nexus client
Collections, schema, cases Collection, Schema, ResourceMap, Annotations
Case grouping / CaseSet Case discovery, Cases
Upload / plan Datasources, Ingestion
Remote connectors Connectors
Recipes Recipe
Published tables and datasets Published tables, Dataframe, Torch
Async, hooks, advanced grouping Advanced