Skip to main content

Nuuduu

PyPI version Python versions Build status License: MIT

Nuuduu is a Python SDK and CLI that gets robotics training data from the Nuuduu Atlas library onto your machine as a PyTorch-ready dataset — and automatically requests new data collection when the library does not have enough.

Step What it does
Search Find episodes in the Atlas library by task description and country
Bundle Package matching episodes into a training dataset (LeRobot by default)
Sync Download ready bundles to your local dataset directory
Request Order new episodes to be collected when the library is short

Use what Atlas already has, or combine --min-episodes on bundle to bundle available episodes and request the rest in one command.

URL
Atlas web app https://nuuduu.ai/atlas
Atlas API (default) https://nuuduu.ai/api/atlas

The CLI talks to the API at nuuduu.ai. Manage your account and payment method in the Atlas web app.

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
pip install -e '.[dev]'
pytest

How it works

Atlas library                    Your machine
─────────────                    ────────────
  search  ──→  find episodes
  bundle  ──→  package as LeRobot / MCAP / HEVC dataset
  sync    ──→  download  ──→  PyTorch / LeRobot training dataset

  request ──→  collect new episodes (when library is short)
       ↑
       └── triggered automatically by bundle --min-episodes

Typical path — library has enough data:

nuuduu search --text "shirt folding"   # explore + see total price
nuuduu bundle --text "shirt folding"   # purchase + package
nuuduu sync                                     # download locally

When you need more than the library has:

nuuduu bundle --text "shirt folding" --country fi,ee --min-episodes 10000
# bundles 6 000 available episodes, requests collection of the remaining 4 000
nuuduu sync   # run again as bundles become ready

The default output format is LeRobot v3.0, ready for PyTorch training via LeRobot or your own data loader.

Quick start (CLI)

nuuduu auth login

# 1. Search Atlas
nuuduu search --text "fold a t-shirt"

# 2. Get 1,000 episodes prepared for NVIDIA GR00T
# Existing episodes are used immediately and any shortfall is collected.
nuuduu bundle \
  --text "fold a t-shirt" \
  --min-episodes 1000 \
  --profile groot

# 3. Download the dataset somewhere explicit
nuuduu sync --dataset-dir ~/nuuduu-atlas/datasets

# 4. Train with NVIDIA GR00T
python gr00t/experiment/launch_finetune.py \
  --base-model-path nvidia/GR00T-N1.7-3B \
  --dataset-path ~/nuuduu-atlas/datasets/lerobot/<download-uuid> \
  ...

Example output:

$ nuuduu auth login
✓ Logged in as researcher@acme.ai

$ nuuduu search --text "fold a t-shirt"
681 episodes found · $486.32 available now

$ nuuduu bundle --text "fold a t-shirt" \
    --min-episodes 1000 --profile groot
Available now: 681   To collect: 319
Estimated total: $742.00
Confirm purchase? [Y/n] y
✓ Bundle 7f3c2a91 created · LeRobot v3.0 · GR00T

$ nuuduu sync --dataset-dir ~/nuuduu-atlas/datasets
✓ 681 episodes synced
~/nuuduu-atlas/datasets/lerobot/7f3c2a91

Need episodes that are not in the library yet? Use --min-episodes to bundle what's available and request collection of the rest, or request directly:

nuuduu bundle --text "shirt folding" --min-episodes 10000 --country fi,ee
nuuduu request --text "pick and place red blocks" --episodes 1000 --country fi,ee

Quick start (library)

from nuuduu import NuuduuAtlas

atlas = NuuduuAtlas.from_config()

# Search the Atlas library
episodes = atlas.search_episodes(text="shirt folding", country="fi,ee", limit=100)
print(f"Found {len(episodes)} episodes")

# Bundle available episodes; automatically request collection for any shortfall
bundle = atlas.bundle_episodes(
    text="shirt folding",
    country="fi,ee",
    min_episodes=10000,
    confirm_request=True,
)
print(f"{bundle.bundled_episodes} bundled, {bundle.requested_episodes} requested")

# Download ready bundles to a local PyTorch-ready dataset
result = atlas.sync(format="lerobot")
for item in result.synced:
    print(item.path)  # e.g. .../lerobot/<uuid>/

Authentication

Use the same email and password as your Atlas web app account. The CLI authenticates against the API at https://nuuduu.ai/api/atlas 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.

Payment

When you confirm a bundle or collection request in the CLI, payment is charged automatically to the card saved on your Atlas account. No browser step or extra checkout flow is required.

The only payment issues you may see:

Situation What to do
No payment method on file Add a card at nuuduu.ai/atlas
Card declined or charge failed Update your payment method in the Atlas web app and retry

nuuduu search shows the total price. nuuduu bundle and nuuduu request ask for confirmation before charging.

Dataset directory

Resolved automatically via priority chain:

  1. --dataset-dir CLI flag
  2. NUUDUU_DATASET_DIR environment variable
  3. dataset_dir in config file
  4. HF_LEROBOT_HOME/nuuduu-atlas (LeRobot ecosystem default)
  5. Project .env, training configs, or ./datasets/nuuduu-atlas
  6. Fallback: ~/nuuduu-atlas/datasets

The dataset directory is created automatically on first sync if it does not exist.

nuuduu config show   # shows resolved path and source

Local layout:

{dataset_dir}/
  .nuuduu/manifest.json
  lerobot/{download_uuid}/     # LeRobot v3.0 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 search [--text QUERY] [--country fi,ee] [--limit N]
nuuduu bundle [--text QUERY] [--country fi,ee] [--limit N] \
  [--min-episodes N] [--format lerobot|mcap|hevc] \
  [--profile groot|openpi|smolvla|openvla|oxe] \
  [--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 search, 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)

nuuduu search prints a total price line after the results table. nuuduu bundle shows the same total and prompts for confirmation before charging your saved payment method.

Bundle-specific options

Option Description
--format / -f Output format: lerobot (default), mcap, or hevc
--profile LeRobot export profile (see Dataset profiles)
--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 bundle purchase and collection request confirmation prompts

Dataset profiles

Use --profile on nuuduu bundle to prepare the dataset for a specific training stack:

Profile ID Name
groot NVIDIA Isaac GR00T
openpi Physical Intelligence π0 / π0.5
smolvla Hugging Face SmolVLA
openvla OpenVLA / OFT
oxe Octo / Open X-Embodiment

Collection requests

Order new data to be collected when the library does not have enough:

nuuduu request --text "pick and place red blocks" --episodes 1000 --country fi,ee
Available now: 681   To collect: 319
Estimated total: $742.00
Confirm purchase? [Y/n]

After confirmation, Atlas collects the episodes. Run nuuduu sync as bundles become ready.

Note: the collection request API may return 404 until the backend endpoint is fully live — the CLI shows a preview of the intended UX when that happens.

Output formats

Bundles are written to your local dataset directory in one of these formats:

Format Contents Best for
lerobot (default) LeRobot v3.0 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:

  1. Verifies the downloaded zip before extracting
  2. Stores the hash in .nuuduu/manifest.json
  3. 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 failed / no payment method Add or update your card at https://nuuduu.ai/atlas, then retry the bundle or 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

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.5.2

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

Source distribution (sdist)

Source distribution for nuuduu 0.5.2
File Size Uploaded
nuuduu-0.5.2.tar.gz 23.9 kB Details

Built distribution (wheel)

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

Total release size: 56.9 kB

Release files / nuuduu-0.5.2.tar.gz

Download URL nuuduu-0.5.2.tar.gz
Size 23.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c3f7507c97867011067d7ec1fe8aa8c4abb7cc59c2d17ab9a42ae74e6738ce54
BLAKE2b-256 checksum
How to use checksums
af0cc669a3a50a47324273553fa9181e9e6d81fb3da87ab52cbad57b70bd5725
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.5.2-py3-none-any.whl

Download URL nuuduu-0.5.2-py3-none-any.whl
Size 33.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6927dd5ead69b1d7a9978d1a9e3c77847a12392f30b84d9287d9fce4c6f25017
BLAKE2b-256 checksum
How to use checksums
384f109d0cbf5927fd80f3343cde7dfb08ca7bb8daf696bac93292d6f2a344b1
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 history Release notifications | RSS feed

0.9.0

2 release files

0.8.0

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

This release

0.5.2 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.1

2 release files

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