The built-in export writes LeRobot v3. If your training code wants something else, such as CSV, RLDS, HDF5 or an in-house format, an export algorithm writes the dataset version in that format. The platform stores the files and offers them for download like any other export.
An export algorithm runs once per dataset version. It reads version and writes an artifact through out, an ArtifactWriter:
| Method | Use it to |
|---|---|
out.format(name) | Name the format of the files. |
out.path(rel) | Get a path inside the export to write to. Parent folders are created for you. |
out.add(src, rel) | Copy a file or folder into the export. |
out.summary(dict) | Describe the export, such as counts and sizes. |
Example: episodes as CSV
This algorithm writes one CSV row per episode of the version. The file is packages/sdk-python/examples/v1/export-csv/main.py.
"""Export: one CSV row per episode of the dataset version.
In: the dataset version: its episodes, with their recording, window, task and split.
Out: an artifact: episodes.csv plus a short summary. The platform checks and hashes every file.
Why: the smallest complete export; copy it to write the files another tool expects (a table, a manifest).
"""
import csv
from embodiflow import ArtifactWriter, DatasetVersion, algorithm
@algorithm.export(name="episodes-csv", title="Episodes as CSV")
def run(version: DatasetVersion, out: ArtifactWriter) -> None:
out.format("csv")
with open(out.path("episodes.csv"), "w", newline="", encoding="utf-8") as handle:
writer = csv.writer(handle)
writer.writerow(["episode_id", "recording_id", "start_s", "end_s", "duration_s", "task", "split"])
for member in version.members:
writer.writerow([member.episode_id, member.recording_id, member.start_s, member.end_s, f"{member.duration_s:.3f}", member.task or "", member.split or ""])
out.summary({"episodes": len(version.members)})Its test is packages/sdk-python/examples/v1/export-csv/test_main.py: it runs this code through the real runner on a small fixture and checks the values it writes. To start from it, run embodiflow algorithm init my-algorithm --category export, which writes main.py and test_main.py; then run embodiflow algorithm test my-algorithm (needs Python with pytest and the SDK).
Good to know
When you need the data itself and not only the table of episodes, version.members[i].recording() downloads the recording window of that episode.
An export workflow takes exactly one artifact. Whatever the format, exports still check anonymization, so a custom format never becomes a way around it.
The built-in LeRobot v3 export takes the parameters video_codec, max_width, unsplit, splits and include_labels, and the export options of a version map to them. A task language other than the default is refused with EXPORT_OPTION_UNSUPPORTED, never dropped silently.
You can try an export algorithm on the first episodes of a dataset version from the editor's Test run, just like a curate algorithm. To produce real files, start the export from the dataset version; starting an export workflow run needs permission to run workflows and to write exports.