Nuuduu
Python SDK and CLI for Nuuduu Atlas — search, bundle, request, and sync robotics training datasets (LeRobot, MCAP, HEVC) to your local machine for PyTorch / LeRobot workflows.
| URL | |
|---|---|
| Atlas web app | https://nuuduu.ai/atlas |
| Atlas API (default) | https://nuuduu.com |
The CLI talks to the API at nuuduu.com. Browse episodes in the Atlas web app. v1 may still send you to the web app for some bundle payments; the destination is fully in-CLI purchase via nuuduu request (see Roadmap).
Source repository: bitbucket.org/nuuduu/nuuduu
Installation
# Library only
pip install nuuduu
# Library + CLI command (quote brackets so the shell does not treat them as globs)
pip install 'nuuduu[cli]'
Development install:
git clone git@bitbucket.org:nuuduu/nuuduu.git
cd nuuduu
uv sync --all-extras
Workflow
search → bundle → sync
↓
request (if you need more episodes than the library has)
- Search — find episodes matching a task description and optional country filter
- Bundle — server packages matching episodes into a downloadable archive (
lerobotby default) - Sync — download ready bundles to your local dataset directory
- Request — order new episodes to be collected when the library does not have enough (
--min-episodeson bundle does this automatically)
Quick start (CLI)
# Authenticate (saves token to ~/.config/nuuduu/config.toml, mode 0600)
nuuduu auth login
# Search episodes
nuuduu episodes search --text "pick up cup"
# Bundle episodes matching a search (server-side packaging job)
nuuduu episodes bundle --text "pick up cup"
# Need 10k episodes but the library only has 6k — bundle what's available, request the rest
nuuduu episodes bundle --text "shirt folding" --country fi,ee --min-episodes 10000
# Request new training data directly (quote + confirm — API coming soon)
nuuduu request --text "pick and place red blocks" --episodes 1000 --country fi,ee
# Sync ready bundles to your local dataset directory
nuuduu sync
# Load in LeRobot (after sync)
python -c "
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
dataset = LeRobotDataset('local', root='~/.cache/huggingface/lerobot/nuuduu-atlas/<download-uuid>')
print(len(dataset))
"
Quick start (library)
from nuuduu import NuuduuAtlas
atlas = NuuduuAtlas.from_config()
# Bundle what's in the library; request any shortfall
bundle = atlas.bundle_episodes(
text="shirt folding",
country="fi,ee",
min_episodes=10000,
confirm_request=True,
)
print(bundle.bundled_episodes, "bundled,", bundle.requested_episodes, "requested")
result = atlas.sync(format="lerobot")
for item in result.synced:
print(item.path)
Authentication
Use the same email and password as your Atlas web app account. The CLI authenticates against the API at https://nuuduu.com with type=api.
Credentials are stored at ~/.config/nuuduu/config.toml with 0600 permissions. The CLI refuses to read config files that are group- or world-readable.
| Method | Usage |
|---|---|
| Config file | api_token = "..." in ~/.config/nuuduu/config.toml |
| Environment | export NUUDUU_API_TOKEN="..." |
| Programmatic | NuuduuAtlas(token="...") |
nuuduu auth login # email + password → saves token
nuuduu auth logout # clear saved token
nuuduu auth token set TOKEN # set token manually
nuuduu auth status # show masked token status
Tokens expire after 24 hours in production. On HTTP 401, run nuuduu auth login again.
Dataset directory
Resolved automatically via priority chain:
--dataset-dirCLI flagNUUDUU_DATASET_DIRenvironment variabledataset_dirin config fileHF_LEROBOT_HOME/nuuduu-atlas(LeRobot ecosystem default)- Project
.env, training configs, or./datasets/nuuduu-atlas - Fallback:
~/.cache/huggingface/lerobot/nuuduu-atlas
nuuduu config show # shows resolved path and source
Local layout:
{dataset_dir}/
.nuuduu/manifest.json
lerobot/{download_uuid}/ # LeRobot v2.1 dataset
mcap/{download_uuid}/ # per-episode .mcap files
hevc/{download_uuid}/ # per-episode .mp4 files
CLI reference
nuuduu --help
nuuduu --version
nuuduu auth login
nuuduu auth logout
nuuduu auth token set TOKEN
nuuduu auth status
nuuduu config show
nuuduu config set KEY VALUE
nuuduu sync [--dataset-dir PATH] [--format lerobot|mcap|hevc|all] [--dry-run] [--verify]
nuuduu episodes search [--text QUERY] [--country fi,ee] [--limit N]
nuuduu episodes latest [--limit N]
nuuduu episodes bundle [--text QUERY] [--country fi,ee] [--limit N] \
[--min-episodes N] [--format lerobot|mcap|hevc] [--uuids UUID[,UUID...]] \
[--wait] [--yes]
nuuduu request --text "TASK" --episodes N [--country fi,ee] [--yes]
nuuduu request list
Add --json to any command for machine-readable output.
Shared search options
These options work the same on episodes search, episodes bundle, and request:
| Option | Description |
|---|---|
--text / -t |
Semantic search query / task description |
--country / -c |
Comma-separated ISO 3166-1 alpha-2 codes (e.g. fi,ee,de); lowercased before sending |
--limit / -n |
Max episodes to search (search and bundle only; defaults to 20) |
Bundle-specific options
| Option | Description |
|---|---|
--format / -f |
Output format: lerobot (default), mcap, or hevc |
--min-episodes |
Target episode count; bundles what's available, then quotes a collection request for any shortfall (requires --text) |
--uuids / -u |
Comma-separated episode UUIDs (skips search when you already know them) |
--wait |
Poll until the bundle job is ready |
--yes / -y |
Skip collection request confirmation when --min-episodes triggers a request |
Roadmap
v1 (today): Search episodes, bundle matching episodes on the server, then nuuduu sync to download ready bundles locally. Some paid bundles still require completing payment in the Atlas web app before nuuduu sync.
Destination UX — order new data entirely from the terminal:
nuuduu request --text "pick and place red blocks" --episodes 1000
Estimated price: €742
Available immediately: 681 episodes
To collect: 319 episodes
Purchase using Acme Robotics account? [Y/n]
After confirmation, Atlas fulfills the order and nuuduu sync materializes bundles locally. No browser step.
Download formats
| Format | Contents | Best for |
|---|---|---|
lerobot |
LeRobot v2.1 dataset (meta/, data/, videos/) | PyTorch / LeRobot training |
mcap |
Per-episode MCAP files | ROS 2 / MCAP tooling |
hevc |
Per-episode HEVC MP4 files | Video analysis pipelines |
Integrity verification
When the Atlas API provides a hash field (SHA256 of the bundle zip), nuuduu sync:
- Verifies the downloaded zip before extracting
- Stores the hash in
.nuuduu/manifest.json - Skips re-download when the local hash matches
nuuduu sync --verify # re-check local bundles without downloading
Library API
| Class / function | Purpose |
|---|---|
NuuduuAtlas |
High-level facade (recommended) |
AtlasClient |
Low-level HTTP API client |
SyncEngine |
Sync and verify engine |
NuuduuConfig |
Config load/save |
resolve_dataset_dir() |
Dataset path resolution |
EpisodeSearchOptions |
Shared search parameters |
BundleResult |
Result of bundle_episodes() (download + optional collection request) |
Key methods on NuuduuAtlas:
| Method | Purpose |
|---|---|
search_episodes(text, country, limit) |
Search ready episodes |
bundle_episodes(text, country, min_episodes, ...) |
Bundle + optional collection request |
request_episodes(task, episodes, country) |
Quote/confirm a collection request |
sync(format, ...) |
Download ready bundles locally |
login() / logout() |
Manage API credentials |
Exceptions: AuthError, ApiError, IntegrityError, ConfigError, NotFoundError
Progress callbacks for sync:
from nuuduu.types import SyncProgressEvent
def on_progress(event: SyncProgressEvent) -> None:
print(event.phase, event.bytes_done, event.bytes_total)
atlas.sync(on_progress=on_progress)
Troubleshooting
| Problem | Solution |
|---|---|
| HTTP 401 | Run nuuduu auth login — token may have expired |
| Config permission error | Run chmod 600 ~/.config/nuuduu/config.toml |
| Payment required (v1) | Complete payment at https://nuuduu.ai/atlas, then nuuduu sync. Future: in-CLI via nuuduu request |
| SHA256 mismatch | Re-run nuuduu sync to re-download the bundle |
| Request API 404 | nuuduu request API not live yet — CLI shows the destination UX preview |
--min-episodes needs --text |
Provide a task description for the collection request |
Development
uv sync --all-extras
uv run pytest
uv build
See CONTRIBUTING.md for release and contribution guidelines.
CI runs on Bitbucket Pipelines for every push and pull request.
Publishing
# Bump version in pyproject.toml and CHANGELOG.md
uv build
git tag v0.4.0 && git push origin v0.4.0 # triggers Bitbucket Pipeline PyPI publish
One-time setup: add a secured PYPI_TOKEN repository variable in
Bitbucket → Repository settings → Pipelines → Repository variables.
Legal
Copyright © 2026 Nuuduu UAB. Licensed under the MIT License.
Nuuduu® is a registered trademark of Nuuduu UAB. All rights reserved. The Nuuduu name and logo may not be used to imply endorsement or affiliation without prior written permission from Nuuduu UAB.
Metadata
Release files for nuuduu 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nuuduu-0.4.0.tar.gz | 21.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nuuduu-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.8 kB
Release files / nuuduu-0.4.0.tar.gz
| Download URL | nuuduu-0.4.0.tar.gz |
|---|---|
| Size | 21.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
15202c383ae129b0ecffede54b203fdc11a2dd55c5a94521e6ac8762d6d51ebd
|
|
BLAKE2b-256 checksum How to use checksums |
6aa28e9aec11e1ed4cb98215696faa47bb4b34e9772115e19adc86b89d8bd96f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / nuuduu-0.4.0-py3-none-any.whl
| Download URL | nuuduu-0.4.0-py3-none-any.whl |
|---|---|
| Size | 30.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
de84ecf3bccf0ec7dfa3787c64fbd9874d99d80ee0d8157b4a36d652f7dc0913
|
|
BLAKE2b-256 checksum How to use checksums |
e329f6d2a890a2e955a37ac6c2c39e1191c3d47c9f7fa2cb5ef7b4414de775b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|