Skip to main content

braven

Python SDK for Braven, the experiment tracker for hardware and photonics R&D teams.

pip install braven

Install and login

pip install braven
python -m braven login

login asks for your backend URL and an SDK API key (braven_..., from your Braven account's Settings → Watcher Keys) and saves them to ~/.braven/config.json. Every script on the machine picks the credentials up automatically — no need to pass them around.

Direct logging (wandb-style)

The common case: a script you run yourself, logging config, metrics, and plots straight to Braven as it runs.

import braven

run = braven.init(name="My Experiment", company="My Company", project="My Project")

braven.config("radius_um", 55.0)
braven.config("gap_nm", 200.0)

braven.summary("q_factor", 18_400)
braven.summary("extinction_ratio_dB", 22.1)

braven.upload("spectrum.png")
braven.finish()

company/project are only required if your API key can see more than one project — pass them to disambiguate.

Matplotlib figures

Pass a live matplotlib.figure.Figure to upload() instead of a file path and the SDK saves the PNG for you (same as fig.savefig() would) and extracts an interactive companion plot from the figure's line/scatter data, so the experiment page shows a zoomable, hoverable chart alongside the static image — no extra API to learn:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(wavelengths_nm, through_db, label="Through port")
ax.set_xlabel("Wavelength (nm)")
ax.set_ylabel("Transmission (dB)")

braven.upload(fig, name="spectrum.png")

This works the same way whether the figure came from a script you run yourself or a script run through Braven's Pipelines tab — one code path, one behavior, no separate API for "give me a nice list thumbnail."

Prefer to log a plain array without a matplotlib figure at all? plot_series() does that directly:

braven.plot_series("snr_vs_temp", y=snr_values, x=temperatures, x_label="Temp (C)", y_label="SNR (dB)")

Devices — multiple sensors/units in one pipeline run

Tag a value with a stable per-device key and the KPI name stays the same across devices (no SNR_dev1, SNR_dev2) — the device becomes a separate coordinate instead of a suffix. In a pipeline script, each device also gets its own single-device Experiment under the run's Experiment (the "parent") — get_device() returns a handle scoped to it:

for sensor_id, snr in results.items():
    braven.get_device(sensor_id).log_summary("SNR", snr)

braven.log_summary("max_device_mismatch", spread)  # parent-level, across all devices

Logging several values for the same device without threading a handle through every call? set_device() sets an ambient current device for subsequent bare calls, the device-scoped equivalent of how braven.init() sets the ambient current run:

braven.set_device("SENSOR-4471")
braven.log_config("gain_db", 12)
braven.log_summary("SNR", 14.2)
braven.upload(fig, name="spectrum.png")   # this device's own figure
braven.set_device(None)                   # back to parent-level logging

A device is auto-created on first sight and its history accumulates across experiments — pass an optional type on first use (braven.get_device("SENSOR-4471", "Photodiode")) to name what kind of device it is; it's ignored once the device already exists.

A direct-logging Run's device handle (run.get_device(key), not the module-level get_device()) has no parent/child concept — it still tags device-scoped values onto rows of that same Experiment; Device.upload() is pipeline-only.

braven.device() was renamed to get_device()/set_device() in 0.2.0 — calling the old name now raises with migration guidance rather than silently keeping the old shared-row behavior, since it changed what a device-tagged value actually means (its own Experiment, not a tagged row).

Pipeline scripts (run by the Braven worker)

If your script runs through Braven's Pipelines tab (server-side, executed by the Braven worker against uploaded files) rather than on your own machine, the SDK dispatches to the same functions automatically — no braven.init() call needed, and no credentials to manage (the worker supplies the experiment context):

import braven

def process(braven=None):
    braven.log_config("lr", "0.001")
    braven.log_summary("acc", "0.94")
    braven.log_artifact("plot.png")

    # Devices and matplotlib figures work exactly as in direct logging:
    braven.get_device("SENSOR-1").log_summary("SNR", 14.2)
    braven.upload(fig, name="spectrum.png")

braven.files (uploaded file → local temp path) and braven.params (extracted parameters) are populated by the worker before process() runs.

Querying experiments

Read-only access to experiments already logged in Braven — no API key required beyond what you already set up with python -m braven login, or construct a client directly:

from braven import Braven

b = Braven("https://your-backend.example.com", api_key="braven_...")
exp = b.get("high temp run")          # partial, case-insensitive name match
df = exp.file("data.csv").as_dataframe()  # requires: pip install "braven[dataframe]"

print(exp.metadata)   # {key: value} config/summary metadata
for f in exp.files:
    print(f.filename)

b.get() also accepts a list of names and returns a list of Experiment objects. b.experiments() returns lightweight summaries of everything visible to the API key.

Cross-experiment analysis

Pull an explicit, frozen set of experiments out of Braven for local work (training a model, building a comparison plot — anything outside Braven), then log results back onto the same object so the record of what was analyzed can never drift from what was actually read:

analysis = braven.collect(
    experiment_ids=["exp_1", "exp_2", "exp_3"],
    name="Cross-lot yield comparison",
)

for exp in analysis.experiments():
    df = exp.file("data.csv").as_dataframe()
    # ... do local analysis ...

analysis.log_summary("mean_yield", 0.94)
analysis.upload(fig, name="comparison.png")

filter_token (copied from Braven's webapp "Copy as code" action) works as an alternative to an explicit experiment_ids list — it's re-resolved to concrete experiment IDs at call time, never stored as a live query.

Optional dependencies

requests is the only hard dependency. Everything else is optional and imported lazily:

Feature Install
.as_dataframe() on a downloaded file pip install "braven[dataframe]"
Uploading a live matplotlib Figure (and its list thumbnail) pip install "braven[plots]"

Contributing / issues

Source: github.com/bravenlab/braven-python. Found a bug or have a feature request? File it on GitHub Issues — that's the right place for anything specific to the SDK itself.

License

MIT — see LICENSE.

Metadata

Release files for braven 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for braven 0.2.1
File Size Uploaded Provenance Actions
braven-0.2.1.tar.gz 35.3 kB With provenance Details for braven-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for braven 0.2.1
File Interpreter ABI Platform Actions
braven-0.2.1-py3-none-any.whl Python 3 none any Details for braven-0.2.1-py3-none-any.whl

Total release size: 62.7 kB

Release files / braven-0.2.1.tar.gz

Download URL braven-0.2.1.tar.gz
Size 35.3 kB
Tags Source
SHA-256 checksum
How to use checksums
54a34e68bc7bb6e519b34676fd24e08c7625381af337e077896d181fe5d1a3dd
BLAKE2b-256 checksum
How to use checksums
4a763e84a909b633a4f156b3341dde678af7a697a90e1825fe6edf59f131e808
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release files / braven-0.2.1-py3-none-any.whl

Download URL braven-0.2.1-py3-none-any.whl
Size 27.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a11b817b4305c4c9c55d111bf6b0bf47202a410b04c2e0d68d962820f9ae1239
BLAKE2b-256 checksum
How to use checksums
ddc8c0d462503f641052d9900ea933d5c73c73cf90c61db41152981ef20685c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Security for braven 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for braven-0.2.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page