Extensions


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.rs is the cdylib entry point: it declares the python/* submodules and the #[pymodule]. The #[pyclass(name = "Orbitron")] wrapper and the Scene / Trajectory / RenderFrame classes live in src/python/ (e.g. src/python/types.rs). Each method delegates to OrbitronServices, the analyzer, or the renderer, returning Python-native structures (PyDict, PyList) to avoid leaking internal types.
  • python/orbitron/__init__.py provides 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

  1. Activate the project environment:

    source ~/.bash_profile
    conda activate orbitron-dev
  2. Build/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
  3. 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 a Scene, while Orbitron.load_trajectory(path) returns a Trajectory with frame accessors. Scene exposes 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 a RenderFrame object 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 Orbitron with a remote="[user@]host:/root" argument (scp-style), which builds an SftpDataSource; max_file_size feeds ServicesConfig.

Development notes

  • When extending the API, ensure new methods leverage OrbitronServices so 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 8082

Endpoints: - 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.

  1. 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.py
  2. Build 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.1
  3. Load the scene bytes:

    http://127.0.0.1:8081/?scene=/scene.bin