VOLT
Open Source Ecosystem

VoltClient (Python)

Python SDK for the Volt platform — run native plugins locally, browse REST resources, convert Apache Parquet to DataFrames, and visualize GLB models.

Overview

voltsdk wraps the Volt REST API and also: downloads, caches, and runs native C++ analysis plugins locally (PluginHub); browses resources; assembles and renders GLB 3D models (SpatialAssembler, open_in_volt); and loads analysis output into pandas DataFrames.

Packagevoltsdk
Python3.10+
LinksGitHub · PyPI

Installation

pip install voltsdk

Optional extras:

pip install "voltsdk[visualization]"   # VTK desktop render window for view_glb
pip install "voltsdk[notebook]"        # VTK + k3d for inline rendering in Jupyter
pip install "voltsdk[ovito]"           # OVITO pipeline integration
pip install "voltsdk[all]"             # everything above

Quick Start

from voltsdk import VoltClient, PluginHub

# Run a native plugin locally — no Volt account required
hub = PluginHub(default_publisher="voltlabs")
ptm = hub.get("polyhedral-template-matching")
run = ptm("frame.dump", output_dir="out", crystal_structure="FCC", rmsd=0.1)
print(run["annotated.dump"].path)

# Or browse Volt resources with an authenticated client
client = VoltClient.from_env()
traj = client.trajectories.get("trajectory-id")
for analysis in traj.analyses:
    print(analysis.id, analysis.status, analysis.plugin_name)

Authentication

The authenticated client uses secret keys (prefixed with vsk_), generated from your Volt team settings. The constructor takes secret_key and base_url; no network calls happen during construction — the first request fires lazily when you access a resource.

from voltsdk import VoltClient

client = VoltClient(
    secret_key="vsk_abc123...",
    base_url="https://server.voltcloud.dev",
)

VoltClient.from_env() (recommended) reads VOLT_SECRET_KEY and VOLT_BASE_URL from the environment. Inside a Volt Jupyter container the base URL is auto-detected from the Jupyter/server proxy configuration, so from_env() is zero-config there.

client = VoltClient.from_env()

base_url is the server origin. The /api suffix is optional — both https://server.voltcloud.dev and https://server.voltcloud.dev/api work, since the client appends /api when it is missing. The constructor accepts only secret_key and base_url — there is no timeout parameter.

Resources

VoltClient exposes resource collections as lazy, auto-paginating properties — iterating fetches pages on demand. Resources are typed objects, not dicts, so use attribute access (analysis.status), not subscripting.

PropertyReturns
client.teamThe Team tied to the secret key
client.trajectoriesTrajectoryCollection (team-wide)
client.analysesAnalysisCollection (team-wide)
client.pluginsPluginHub (download/cache/run native plugins)

Trajectories

# Iterate the team's trajectories (lazy pagination)
for traj in client.trajectories:
    print(traj.id, traj.name, traj.frame_count)

# Optional server-side name filter
coppers = client.trajectories.list(search="copper")

# Fetch one by ID
traj = client.trajectories.get("trajectory-id")
print(traj.name, traj.status, traj.is_public)

# Download the original trajectory file(s)
traj.download(dest="downloads/")

Each Trajectory exposes sub-resources: traj.frames, traj.analyses, traj.simulation_cell, and traj.listings.

Frames

traj.frames is built from the trajectory metadata (no extra API call). Each Frame has timestep and natoms.

frame = traj.frames[0]
print(frame.timestep, frame.natoms)

# Per-atom data as a DataFrame (optionally scoped to an analysis)
df = frame.atoms(analysis_id="analysis-id")

# Downloads
frame.download_dump(dest="downloads/")                 # raw LAMMPS dump (.dump.gz)
frame.download_glb(analysis_id="analysis-id")          # GLB for this frame

frame.download_glb() accepts analysis_id (default 'default') and dest.

Analyses

# Analyses for a trajectory
for analysis in traj.analyses:
    print(analysis.id, analysis.status, analysis.plugin_name, analysis.progress)

# Team-wide analyses
for analysis in client.analyses:
    print(analysis.id, analysis.plugin_name)

Analysis properties: id, status, plugin_name, plugin_id, trajectory_id, config, and progress (fraction of frames completed, 0.0–1.0).

Download every artifact (parquet + GLB) for an analysis as a zip:

# Download and recursively extract (default)
path = analysis.download_artifacts(dest="out/")

# Keep the zip
zip_path = analysis.download_artifacts(dest="out/", unzip=False)

Analysis results

analysis.df() returns the listing rows (one per timestep) as a DataFrame. analysis.listings exposes the same data with extra controls (columns=, to_csv(...)).

analysis = traj.analyses.first()

df = analysis.df()                       # results table
df = analysis.listings.to_dataframe(columns=["timestep", "energy"])
analysis.listings.to_csv("out.csv")

# 3D model for a frame, and the raw artifact bundle:
frame.download_glb(analysis_id=analysis.id, dest="out/")
analysis.download_artifacts(dest="out/")

Plugin Hub

PluginHub (new in VoltSDK 3.0) is also available on an authenticated client via client.plugins.

from voltsdk import PluginHub

hub = PluginHub(default_publisher="voltlabs")
print(hub.list())                       # publisher-qualified marketplace listing

ptm = hub.get("polyhedral-template-matching")
run = ptm(
    "frame.dump",
    output_dir="out",
    crystal_structure="FCC",
    rmsd=0.1,
)
print(run["annotated.dump"].path)

Plugin arguments are passed as snake_case keyword arguments matching the plugin's plugin.json argument keys. Calling a plugin returns a PluginRun; index it by artifact name to get a PluginArtifact (a path-like object) with helpers such as .path, .df(), .json(), .glb(), and .open_in_volt().

df = run["annotated.dump"].df()             # artifact as a DataFrame
glb = run["dislocations"].glb()             # assemble a GLB from an exporter payload
run["dislocations"].open_in_volt()          # render in the Volt web canvas

Identifiers and versions

Plugin keys use the canonical @scope/name form. Versions may be exact, the literal latest, or a semver range.

hub.get("@voltlabs/opendxa", "1.0.0")    # explicit version
hub.get("@voltlabs/opendxa", "^1.0.0")   # semver range
hub["@voltlabs/opendxa"]                  # shorthand for the latest version
hub.install("@voltlabs/opendxa")         # pre-download the latest bundle
hub.uninstall("@voltlabs/opendxa")       # drop every cached version

Configuration

VariablePurposeDefault
VOLT_PLUGIN_REGISTRYVolt-Registry base URLhttps://registry.voltcloud.dev
VOLT_CACHE_DIRLocal plugin cache$XDG_CACHE_HOME/volt
VOLT_REGISTRY_TOKENOptional Bearer JWT/PAT for authenticated readsunset

Visualization

open_in_volt(source, *, title=None, volt_url=None, open_browser=True)

Renders local GLB files, a GLB sequence, or an existing Volt resource using the Volt web canvas. Inside a Volt notebook it serves files through the Jupyter proxy; on a local machine it starts a background file server. The browser still needs an authenticated Volt session.

from voltsdk import open_in_volt

# A single GLB
open_in_volt("out/frame.glb")

# A timestep-keyed sequence
open_in_volt({
    0:     "out/frame-0000.glb",
    5000:  "out/frame-5000.glb",
    10000: "out/frame-10000.glb",
})

Resource objects expose the same helper to open their exact canvas route: trajectory.open_in_volt(timestep=5000), frame.open_in_volt(), analysis.open_in_volt(timestep=5000), and exposure.open_in_volt(5000).

By default the viewer opens against https://app.voltcloud.dev; override it with volt_url=... or the VOLT_APP_URL environment variable.

SpatialAssembler

Builds GLBs locally from Volt exporter payloads (AtomisticExporter, MeshExporter, LineExporter). It accepts the full artifact file (.json or a line-entity-table .parquet) or the raw nested payload.

from voltsdk import SpatialAssembler, open_in_volt

assembler = SpatialAssembler()
glb_path = assembler.lines_glb(
    "out/ptm-dxa_dislocations.parquet",
    output_path="out/ptm-dxa_dislocations.glb",
    color_by="burgers_family",
)

open_in_volt(glb_path)

assembler.glb(source, output_path=..., exporter=...) auto-dispatches to the right exporter; atomistic_glb, mesh_glb, and lines_glb are the per-exporter entry points.

view_glb(file_path)

Renders a GLB 3D model interactively. In a Jupyter notebook it uses k3d for inline rendering; otherwise it opens a VTK desktop window.

from voltsdk import view_glb

view_glb("out/frame-5000.glb")

Requires voltsdk[visualization] (VTK desktop window). For the inline notebook path, install voltsdk[notebook] to add k3d.

Utility Functions

parquet_as_df(file_path, iterable_key=None)

Converts a Volt Apache Parquet result file to a pandas DataFrame, merging chunked (streamed) messages.

from voltsdk import parquet_as_df

df = parquet_as_df("out/output.parquet")
print(df.head())
print(df.columns.tolist())

iterable_key is a dot-separated path extracted from each chunk before merging — for results that wrap their rows under a named key:

df = parquet_as_df("out/output.parquet", iterable_key="main_listing")

Example Workflow

from voltsdk import VoltClient, parquet_as_df

client = VoltClient.from_env()

# 1. Pick a trajectory and its first analysis
traj = client.trajectories.get("my-trajectory-id")
analysis = traj.analyses.first()
print(analysis.plugin_name, analysis.status)

# 2. Download all artifacts (extracted)
out_dir = analysis.download_artifacts(dest="out/")

# 3. Convert a result file to a DataFrame
df = parquet_as_df(f"{out_dir}/output.parquet")
print(f"Rows: {len(df)}")
print(f"Columns: {df.columns.tolist()}")
print(df.describe())

On this page