> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bravenlab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Querying experiments

> Read existing experiments and their files back out of Braven — a read-only client for analysis notebooks and scripts.

Use the `Braven` client when you want to **read** data that's already in the app — pull a file into pandas, list experiments in a project, or check metadata — rather than log new results.

```python theme={null}
from braven import Braven

b = Braven("https://api.bravenlab.com", api_key="braven_...")

for exp in b.experiments():
    print(exp.name, exp.created_at, exp.file_count)

exp = b.get("High-temp run 1")             # partial, case-insensitive name match
df = exp.file("data.csv").as_dataframe()   # requires pandas
```

## `Braven(url, api_key, timeout=30)`

<ParamField path="url" type="str" required>
  Backend URL — `https://api.bravenlab.com`.
</ParamField>

<ParamField path="api_key" type="str">
  Your `braven_...` Watcher Key.
</ParamField>

<ParamField path="timeout" type="int" default="30">
  Request timeout in seconds.
</ParamField>

## Methods

<ResponseField name="b.experiments()" type="→ list[ExperimentSummary]">
  Lightweight summaries of every experiment you have access to — id, name, notes, created\_at, file\_count, metadata.
</ResponseField>

<ResponseField name="b.get(name_or_names)" type="→ Experiment | list[Experiment]">
  Fetch one or more experiments by **partial, case-insensitive** name match. Pass a `list[str]` to fetch several at once. Raises `ValueError` if a name matches zero or more than one experiment — make the name more specific rather than guessing.
</ResponseField>

## `Experiment`

<ResponseField name="exp.id / exp.name / exp.notes / exp.created_at" type="fields">
  Basic experiment metadata.
</ResponseField>

<ResponseField name="exp.metadata" type="dict[str, str | None]">
  Every Config and Summary value, keyed by name.
</ResponseField>

<ResponseField name="exp.files" type="list[BravenFile]">
  Every file attached to the experiment.
</ResponseField>

<ResponseField name="exp.file(filename)" type="→ BravenFile">
  Look up one file by exact filename. Raises `FileNotFoundError` (with the available filenames listed) if there's no exact match.
</ResponseField>

## `BravenFile`

<ResponseField name="f.download()" type="→ bytes">
  Download and return the raw file content.
</ResponseField>

<ResponseField name="f.save(dest)" type="→ None">
  Download and write to a local path.
</ResponseField>

<ResponseField name="f.as_dataframe()" type="→ pandas.DataFrame">
  Parse as CSV. Requires `pandas`; raises `ValueError` if the filename isn't `.csv`.
</ResponseField>

## Full cheat sheet

```python theme={null}
b = Braven(url, api_key=key)
b.experiments()
b.get("name")
exp.metadata
exp.file("x.csv").as_dataframe()
```
