Metadata-Version: 2.4
Name: buildai-data
Version: 0.4.2
Summary: The standard API for egocentric data.
Project-URL: Homepage, https://build.ai
Project-URL: Documentation, https://build.ai/docs
Project-URL: Repository, https://github.com/build-ai-ego/buildai-sdk
License: MIT
Keywords: data,egocentric,imu,robotics,video
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: numpy>=1.24
Requires-Dist: rich>=13.0
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Provides-Extra: torch
Requires-Dist: decord>=0.6; extra == 'torch'
Requires-Dist: torch>=2.1; extra == 'torch'
Requires-Dist: webdataset>=0.2.86; extra == 'torch'
Description-Content-Type: text/markdown

# BuildAI

The standard API for egocentric data. `$1/hr`.

## Quickstart

```bash
pip install buildai-data
```

```python
from buildai import BuildAI

client = BuildAI(api_key="build_data_xxxx")
client.download(hours=10, output_dir="./data")
```

That's it. Ten shards download to `./data/`. Each shard is one hour of egocentric video with frame-synced IMU data.

## What you get

Each shard is a tar file containing 20 three-minute clips:

```
shard-000001.tar
  ├── 000001.mp4       # H.265, 1080p, 30fps, no audio
  ├── 000001.imu.npy   # (5400, 6) float32, frame-synced
  ├── 000002.mp4
  ├── 000002.imu.npy
  └── ...              # 20 clips total
```

**Video**: H.265, 1080p, 30fps, no audio. Three minutes per clip.

**IMU**: NumPy array, shape `(5400, 6)`, float32. Columns: `[acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z]`. Row N = frame N (30 fps x 180 seconds = 5400 frames). Units: accelerometer in m/s2, gyroscope in rad/s.

**Shard size**: ~2 GB per shard, ~1 hour of footage, 20 clips.

Shards are standard [WebDataset](https://github.com/webdataset/webdataset) format. If you already have a WebDataset pipeline, point it at the downloaded tars directly.

## Download

```python
from buildai import BuildAI

client = BuildAI(api_key="build_data_xxxx")

# Download 100 hours of data
client.download(hours=100, output_dir="/data/buildai/")

# Download more - you'll get new shards you haven't seen before
client.download(hours=1000, output_dir="/data/buildai/")
```

Every call gets new shards. You never receive the same shard twice. Shards are downloaded sequentially. Every researcher gets the same sequence.

For a named research grant, pass the dataset from your award onboarding email:

```python
client.download(
    dataset="buildai-research-100k",
    grant="jhu-egocentric-2026",
    hours=100,
    output_dir="/data/buildai-research/",
)
```

Granted downloads are bounded by the award's expiry, hour cap, and frozen
logical-hour inventory. Each hour is materialized as a directory containing 20
`.mp4` / `.imu.txt` pairs. Opaque proxy URLs expire after one hour; Build AI
bucket, factory/worker, and source-filename identities are never shared with
the researcher. Granted hours are not billed to the researcher's account. The
SDK checks both the byte size and MD5 of every video and IMU file before
acknowledging the hour.

Download the source-free Parquet index independently when a dataframe is the
more convenient starting point:

```python
client.download_manifest(
    dataset="buildai-research-100k",
    grant="jhu-egocentric-2026",
    output_path="./buildai-research-100k.parquet",
)
```

Downloads resume on failure. If a shard already exists locally and the checksum matches, it's skipped.
For a granted download, the SDK keeps the same server reservation until every
allocated hour is acknowledged and raises an error on any incomplete page or
failed acknowledgement, so batch jobs cannot silently treat a partial transfer
as success. Re-run the same call with the same output directory to resume it.

| Parameter | Default | Description |
|-----------|---------|-------------|
| `hours` | required | Number of one-hour units to download |
| `output_dir` | `./buildai-data` | Where to save shard tars or granted hour directories |
| `dataset` | None | Named dataset grant, when provided by Build AI |
| `grant` | None | Isolated research-grant tenant slug from onboarding |
| `workers` | 8 | Parallel download threads |
| `verify_checksum` | True | SHA-256 verification after download |

## Visualize

```python
from buildai import BuildAI

BuildAI.visualize(source="/data/buildai/")
```

Opens a local web viewer in your browser. Shows a grid of all clips across your downloaded shards. Click any clip to watch the video with accelerometer and gyroscope data graphed below, time-synced.

No data is uploaded. Everything runs locally. Press Ctrl+C to stop.

No API key needed. `visualize` is a static method that works on any directory of shard tars.

## Pricing

$1 per hour. Billed monthly. No minimum, no commitment.

## API key

Get your API key at [build.ai](https://build.ai). You can also set it via environment variable:

```bash
export BUILDAI_API_KEY=build_data_xxxx
```

```python
# Picks up BUILDAI_API_KEY automatically
client = BuildAI()
```

## Account

```python
info = client.account
print(info["total_hours"])
print(info["total_spent_usd"])
print(info["shards_remaining"])
```

## Requirements

- Python 3.10+
- httpx (HTTP client)
- numpy (IMU data)
