Extensions
- Rust SDK (
extensions/rust-sdk): Defines theOrbitronPlugintrait, plugin metadata, and a backend SDK facade (OrbitronSdk) for loading, measuring, rendering, and applying delta updates. The plugin loader is still gated behindexperimental-plugins. - Python bridge (
extensions/python-bridge): PyO3 bindings that wrap the service layer for notebooks, scripts, and downstream automation. See §9.1 for architecture and usage. - Remote SSH/SFTP access (
core/servicesSftpDataSource): reads files on a remote host over the user’s systemssh(via theopenssh/openssh-sftp-clientcrates) — no server is deployed. A target is a scp-style[user@]host:/rootspec; connection details come from~/.ssh/configand ssh-agent. A requested file is fetched whole into a temp file and parsed by the usual loaders. TheORBITRON_REMOTEenvironment variable overrides the target for one process; the GUI/CLI otherwise persist it inOrbitronConfig. Because it is just anotherDataSource, the GUI, CLI, and Python share the same code paths.
10.1 Python Bridge internals
The Python API is implemented in extensions/python-bridge using PyO3. Its mission is to expose the same high-level services (OrbitronServices) that power the CLI and GUI so that Python notebooks/scripts stay in lockstep with the core behaviour.
Crate layout
src/lib.rsis thecdylibentry point: it declares thepython/*submodules and the#[pymodule]. The#[pyclass(name = "Orbitron")]wrapper and theScene/Trajectory/RenderFrameclasses live insrc/python/(e.g.src/python/types.rs). Each method delegates toOrbitronServices, the analyzer, or the renderer, returning Python-native structures (PyDict,PyList) to avoid leaking internal types.python/orbitron/__init__.pyprovides the import shim and version metadata.examples/contains runnable assets:api_smoke_test.py– end-to-end script that loads fixtures, runs analysis, renders, and writes a JSON summary.api_quickstart.ipynb/api_analysis_walkthrough.ipynb– notebooks exercising geometry basics, frontier orbitals, population analysis, and vibrational summaries.
- Tests live in Rust (
cargo test -p orbitron-python-bridge) and the smoke script/notebooks act as post-install verification.
Building & installing
Activate the project environment:
source ~/.bash_profile conda activate orbitron-devBuild/install the extension:
- Preferred:
cd extensions/python-bridge && maturin develop --release - Alternative:
pip install -e extensions/python-bridge/python - Widget dev flow:
cd extensions/python-bridge && ./scripts/develop_with_widget.sh
- Preferred:
Quick sanity check:
python -c "from orbitron import Orbitron; print(Orbitron().load('io/pipelines/tests/fixtures/xyz/water.xyz').atom_count())"The crate depends on workspace versions of
anyhow,tracing,orbitron-backbone, etc., so changes to core services automatically propagate to Python consumers after rebuilding.
API surface
Orbitron.load(path)returns aScene, whileOrbitron.load_trajectory(path)returns aTrajectorywith frame accessors.Sceneexposes atom/bond counts, coordinate and metadata accessors, digest lookup, unit cell inspection, and bond iteration.- Measurement helpers (
distance,angle,dihedral), structural analytics (center_of_mass,bounding_box,geometric_center), export (export), and the headless renderer (render) delegate to the services layer. Orbitron.render_frame(...)returns aRenderFrameobject that exposes zero-copy byte access for notebook embedding or dashboard rendering.- Analysis helpers (
analyze_geometry,analyze_orbitals,analyze_populations,analyze_vibrations) match the CLI commands and return Python dictionaries suitable for JSON serialisation. - Remote loading is supported by constructing
Orbitronwith aremote="[user@]host:/root"argument (scp-style), which builds anSftpDataSource;max_file_sizefeedsServicesConfig.
Development notes
- When extending the API, ensure new methods leverage
OrbitronServicesso behaviour stays consistent across surfaces. Add Rust unit tests and update the smoke script/notebooks to exercise the new functionality.
10.2 SDK backend service (draft)
The SDK facade is intended to power lightweight backend services that serve scene.bin plus delta updates to web/presentation viewers. The current prototype binary is extensions/sdk-service:
cargo run -p orbitron-sdk-service -- --scene fixtures/benzene.xyz --port 8082Endpoints: - GET /scene.bin - GET /scene.json - GET /status (digest + delta state) - GET /delta (204 when empty) - GET /delta/stream (SSE stream of deltas) - POST /delta (accepts JSON DeltaEnvelope) - POST /render (accepts JSON {width,height,camera}; returns PNG) - POST /render.jpg returns JPEG - Response headers: x-render-width, x-render-height - ETag on scene.bin, scene.json, and status
Web viewer embed example:
http://127.0.0.1:8080/?scene=http://127.0.0.1:8082/scene.bin&delta=http://127.0.0.1:8082/delta
Docker/deploy example:
cd extensions/sdk-service
docker build -t orbitron-sdk-service -f Dockerfile ../..
docker run --rm -p 8082:8082 -v "$(pwd)/../../fixtures/benzene.xyz:/data/scene.xyz:ro" \
orbitron-sdk-service --scene /data/scene.xyz --host 0.0.0.0 --port 8082
Or with docker-compose:
cd extensions/sdk-service
docker compose up --build
Auth (optional): - Set SDK_SERVICE_TOKEN to require Authorization: Bearer <token> on every endpoint. - For hosted deployments, prefer signed URLs or edge auth; keep the service stateless.
WebSockets vs SSE: - SSE is the default for one-way delta delivery (/delta/stream). - Add WebSockets only if you need client-to-server control commands or collaborative editing.
Versioning policy: - SDK and delta protocol are versioned independently. - DeltaEnvelope.version is required and validated by the service. - SDK minor releases may add new delta ops; SDK major releases may remove/change ops. - The bridge is compiled with abi3 so wheels remain compatible with CPython ≥3.8. Avoid linking against ABI-unstable libraries. - The longer-term plan is to embed the full viewer in Jupyter (the current bridge is analysis/headless rendering only). - Phase 3 widget scaffolds: - ViewerWidget provides a lightweight iframe helper (requires ipywidgets). - ViewerDomWidget provides a traitlets-backed DOMWidget stub (requires ipywidgets + traitlets). - Frontend scaffolding lives under extensions/python-bridge/widget_frontend and can be built via npm run build (see TESTING.md in the extensions/python-bridge/ directory). - Packaging is not wired yet; when ready, bundle the dist/orbitron-viewer.js output with the Python package (likely via jupyter-packaging). - Interim packaging flow: extensions/python-bridge/scripts/build_with_widget.sh runs the frontend verification before maturin build.
Wasm viewer scaffold
The Phase 2 wasm shell lives under viewer/wasm. To sanity-check the pipeline:
Additional notes: - The wasm shell is being split into smaller modules under viewer/wasm/src/wasm (e.g. delta parsing, selection handling, overlay label helpers). Keep new changes localized to these modules and update viewer/wasm/src/wasm/mod.rs when adding files.
Generate a SceneGraph payload:
ORBITRON_ENV="$(conda run -n orbitron-dev printenv CONDA_PREFIX)" HDF5_DIR="$ORBITRON_ENV" \ DYLD_LIBRARY_PATH="$ORBITRON_ENV/lib" \ ORBITRON_CARGO="$ORBITRON_ENV/bin/cargo" \ conda run -n orbitron-dev python3 viewer/wasm/scripts/generate_scene_bin.pyBuild and serve the wasm app with the scene on the same origin:
cd viewer/wasm conda run -n orbitron-dev trunk build cp /tmp/scene.bin dist/scene.bin cd dist python3 -m http.server 8081 --bind 127.0.0.1Load the scene bytes:
http://127.0.0.1:8081/?scene=/scene.bin