EmbodiFlowDocs
Get startedDataWorkflows and algorithmsTraining and deploymentDeveloper reference
  • Workflows and algorithms

Workflows

  • How workflows work
  • Build your own workflow
  • Runs and logs

Algorithms

  • Algorithm catalog
  • Write a custom algorithm

Algorithm developer guide

  • Your first algorithm
    • Standardize
    • Check
    • Transform
    • Enrich
    • Segment
    • Curate
    • Export
  • Image algorithms
  • Use your algorithm in a workflow
  • Interface reference
  • SDK reference
  • Command line
  • MCP tools
  • Troubleshooting

© 2026 EmbodiFlow

llms.txtOpenAPI JSON
  1. Workflows and algorithms
  2. Algorithm developer guide
  3. SDK reference

SDK reference

Every public class, method and decorator argument of the embodiflow Python SDK, generated from the SDK itself.

This page is generated from the same SDK index the browser editor uses for completion, so it always matches the SDK you run. Everything is imported from embodiflow:

from embodiflow import Context, Feature, FeatureWriter, Recording, algorithm, param

The SDK ships type hints (py.typed), so your own editor completes it too, and every class and method has a docstring that the browser editor shows on hover. The descriptions below are those docstrings.

Beta. Custom algorithms and workflows are in the product and ready to try, but they haven't been through a full acceptance on real data yet. Expect some rough edges, and check results before you rely on them.

Decorators

@algorithm.standardize

Declare a standardizer: it turns one raw recording into the canonical recording.

ArgumentTypeRequiredDefault
namestryes
titlestryes
descriptionstr | NonenoNone
checkslist[Check] | NonenoNone
requiresdict[str, Any] | NonenoNone
paramstype | NonenoNone
resourcesdict[str, Any] | NonenoNone
requirementslist[str] | NonenoNone
retriesint | NonenoNone
cachebool | NonenoNone
serviceslist[str] | NonenoNone

@algorithm.check

Declare a check: it judges data and never changes it.

ArgumentTypeRequiredDefault
namestryes
titlestryes
checkslist[Check]yes
descriptionstr | NonenoNone
levelstr | NonenoNone
readsstr | NonenoNone
inputsdict[str, Input] | NonenoNone
requiresdict[str, Any] | NonenoNone
paramstype | NonenoNone
resourcesdict[str, Any] | NonenoNone
requirementslist[str] | NonenoNone
retriesint | NonenoNone
cachebool | NonenoNone
serviceslist[str] | NonenoNone

@algorithm.transform

Declare a transform: it returns a recording with some streams replaced or cut.

ArgumentTypeRequiredDefault
namestryes
titlestryes
descriptionstr | NonenoNone
inputsdict[str, Input] | NonenoNone
checkslist[Check] | NonenoNone
requiresdict[str, Any] | NonenoNone
paramstype | NonenoNone
resourcesdict[str, Any] | NonenoNone
requirementslist[str] | NonenoNone
retriesint | NonenoNone
cachebool | NonenoNone
serviceslist[str] | NonenoNone
privacystr | NonenoNone

@algorithm.enrich

Declare an enricher: it computes new information without changing the recording.

ArgumentTypeRequiredDefault
namestryes
titlestryes
featureslist[Feature]yes
descriptionstr | NonenoNone
levelstr | NonenoNone
inputsdict[str, Input] | NonenoNone
checkslist[Check] | NonenoNone
requiresdict[str, Any] | NonenoNone
paramstype | NonenoNone
resourcesdict[str, Any] | NonenoNone
requirementslist[str] | NonenoNone
retriesint | NonenoNone
cachebool | NonenoNone
serviceslist[str] | NonenoNone
privacystr | NonenoNone

@algorithm.segment

Declare a segmenter: it proposes episodes, time ranges with a task text.

ArgumentTypeRequiredDefault
namestryes
titlestryes
descriptionstr | NonenoNone
labelsdict[str, str] | NonenoNone
inputsdict[str, Input] | NonenoNone
checkslist[Check] | NonenoNone
requiresdict[str, Any] | NonenoNone
paramstype | NonenoNone
resourcesdict[str, Any] | NonenoNone
requirementslist[str] | NonenoNone
retriesint | NonenoNone
cachebool | NonenoNone
serviceslist[str] | NonenoNone
segment_sourcestr | NonenoNone

@algorithm.curate

Declare a curator: it decides per episode of a dataset version whether to keep it, its split and its task.

ArgumentTypeRequiredDefault
namestryes
titlestryes
descriptionstr | NonenoNone
requiresdict[str, Any] | NonenoNone
paramstype | NonenoNone
resourcesdict[str, Any] | NonenoNone
requirementslist[str] | NonenoNone
retriesint | NonenoNone
cachebool | NonenoNone

@algorithm.export

Declare an exporter: it turns a dataset version into downloadable files.

ArgumentTypeRequiredDefault
namestryes
titlestryes
descriptionstr | NonenoNone
requiresdict[str, Any] | NonenoNone
paramstype | NonenoNone
resourcesdict[str, Any] | NonenoNone
requirementslist[str] | NonenoNone
retriesint | NonenoNone
cachebool | NonenoNone

Functions

param(default, *, minimum=None, maximum=None, enum=None, title=None, description=None, widget=None)

Declare a field of the Params dataclass with its default and limits.

Classes

ArtifactWriter

Collects the files of an export (embodiflow-artifact/v1).

AttributeMeaning
checks: 'CheckWriter'The CheckWriter for the checks this algorithm declared (checks=[Check(...)]).
MethodMeaning
format(name: str) -> NoneName the format of the files (lerobot-v3, csv, ...).
path(rel: str) -> PathA path inside the artifact to write to (parent folders are created).
add(src: str | Path, rel: str) -> NoneCopy the file or folder src into the artifact at rel.
summary(doc: dict[str, Any]) -> NoneDescribe the export (counts, sizes); shown on the download page.

Camera

One camera of a recording.

AttributeMeaning
anonymized: bool
distortion: list[float] | None
height: int
intrinsics: list[list[float]] | None
key: str
model: str | None
role: str
video_path: PathThe camera's mp4 in the recording tree.
width: int
MethodMeaning
valid() -> 'np.ndarray'A boolean per frame: False where the camera had a gap and the video holds a black placeholder.
frames(start: int=0, stop: int | None=None, step: int=1, gray: bool=False, size: tuple[int, int] | None=None) -> Iterator[Frame]Decode frames start..stop every step (indices relative to this recording or episode window).
frame(i: int) -> FrameDecode the single frame i.

Check

One check result id an algorithm may report through CheckWriter.result.

AttributeMeaning
description: str
id: str
title: str
MethodMeaning
to_dict() -> dict[str, Any]The declaration as the manifest input.

CheckWriter

Collects check results (embodiflow-checks/v1).

AttributeMeaning
checks: 'CheckWriter'The CheckWriter for the checks this algorithm declared (checks=[Check(...)]).
MethodMeaning
result(id: str, status: str, value: float | None=None, threshold: float | None=None, message: str='', evidence: Sequence[str | Path] | None=None, at: Mapping[str, Any] | None=None) -> NoneReport one result.
evidence_path(name: str) -> PathA path under evidence/ to write a picture or file to; pass it to result(evidence=[...]).
metrics(doc: dict[str, Any]) -> NoneAttach an embodiflow-quality-metrics/v1 body (built-in checks only).

Column

One tabular column of a recording: name, dtype, shape, names and the conventions unit, frame, source.

AttributeMeaning
dtype: str
frame: str | None
name: str
names: list[str] | None
shape: list[int]
source: str | None
type: str | None
unit: str | None

Context

Everything a run knows about itself: params, facts, identifiers, scratch space, log, progress.

AttributeMeaning
facts: Facts
log: logging.Logger
params: P
platform_params: dict[str, Any]What the platform resolved for a standardize step (rigProfiles, teamDataFormat); empty otherwise.
recording_id: str | NoneThe recording this step works on (None for a dataset-level step).
run_id: strThe workflow run id.
step_id: strThe id of the step in the workflow.
team_slug: str | NoneThe storage slug of the team (names a team feature); None when the job does not state it.
tmp: Path
MethodMeaning
progress(done: int, total: int, message: str='') -> NoneReport progress to the run view (progress bar and ETA); safe to call often.
not_applicable(code: str, message: str) -> NoReturnEnd the step as *not applicable* (exit 85, grey in the run view, never a failure).
input_unusable(code: str, message: str) -> NoReturnEnd the step because the data is broken (exit 87): the step fails and the recording is quarantined.

DatasetVersion

A frozen dataset version: id, features (declared names and types) and members.

AttributeMeaning
document: dict[str, Any]
features: dict[str, dict[str, Any]]
id: str
members: list[Member]
MethodMeaning
to_pandas() -> 'pd.DataFrame'One row per member: id, recording, start/end/duration, task, split, labels, quality status, session, operator.

Episode

An episode of a recording: index, start_s, end_s (recording timeline), task, labels, confidence.

AttributeMeaning
confidence: float | None
duration_s: floatLength in seconds.
end_s: float
index: int
labels: dict[str, Any]
start_s: float
task: str | None

EpisodeWriter

Collects proposed episodes (embodiflow-episodes/v1).

AttributeMeaning
checks: 'CheckWriter'The CheckWriter for the checks this algorithm declared (checks=[Check(...)]).
MethodMeaning
episode(start_s: float, end_s: float, task: str, labels: Mapping[str, Any] | None=None, confidence: float | None=None) -> NoneAdd one episode: startS/endS in seconds, the task text, optional labels and a confidence in 0..1.

Facts

Facts of the main input (contract 2.1) with attribute access: ctx.facts.kind, ctx.facts.stereo.

AttributeMeaning
action: bool | None
cameras: int | None
duration_s: float | None
episodes: int | None
format: str | None
gripper_width: bool | None
imu: bool | None
kind: str | None
privacy_required: bool | None
recorded_hand_pose: bool | None
stereo: bool | None
MethodMeaning
get(name: str, default: Any=None) -> AnyThe value of a fact, or default when it is unknown.
as_dict() -> dict[str, Any]All known facts as a plain dict.

Feature

One feature an enrich algorithm declares and later writes through FeatureWriter.

AttributeMeaning
describe: dict[str, Any] | None
dtype: str | None
frame: str | None
name: str
names: list[str] | None
per: str
shape: list[int] | None
source: str | None
type: str
unit: str | None
MethodMeaning
to_dict() -> dict[str, Any]The declaration as the manifest input: only the arguments that were given.

FeatureWriter

Collects the features an enrich algorithm computes (embodiflow-features/v1).

AttributeMeaning
checks: 'CheckWriter'The CheckWriter for the checks this algorithm declared (checks=[Check(...)]).
MethodMeaning
per_frame(name: str, values: Any, confidence: str | None=None) -> NoneWrite one row per frame: values has shape (num_frames, *shape) (a 1-D array for a scalar).
per_recording(name: str, value: Any) -> NoneWrite one value for the whole recording (JSON, at most 1 MiB).
per_episode(name: str, value: Any) -> NoneWrite the value for the episode being processed (episode-level enrich only).
file(name: str, path: str | Path, describe: Mapping[str, Any] | None=None) -> NoneAttach a file (such as a depth video) to a per="file" feature.

Features

A features input (features.json plus frames.parquet, episodes.parquet and files/).

AttributeMeaning
document: dict[str, Any]
names: list[str]The names of all features.
num_frames: int
MethodMeaning
info(name: str) -> dict[str, Any]The features.json entry of name (type, per, dtype, shape, unit, frame, source, describe).
of_type(semantic_type: str) -> list[str]Names of the features whose semantic type is semantic_type.
per_frame(name: str) -> 'np.ndarray'The values of a per-frame feature, shape (num_frames, *shape); rows outside an episode window are NaN/None.
per_recording(name: str) -> AnyThe value of a per-recording feature.
per_episode(name: str) -> dict[int, Any]{episodeIndex: value} of a per-episode feature.
file(name: str) -> PathThe path of a per-file feature (a depth video).

Frame

One decoded video frame: index (in the recording or episode window), time_s and image (RGB H x W x 3 uint8, or H x W when gray).

AttributeMeaning
image: 'np.ndarray'
index: int
time_s: float

Input

An extra input of type features (a calibration, a hand pose).

AttributeMeaning
optional: bool
requires: list[str]
MethodMeaning
to_dict() -> dict[str, Any]The declaration as the manifest input.

InputUnavailableError

An input the algorithm asked for is not there (absent port, missing file or download).

ManifestDriftError

The code's interface differs from the frozen manifest of this version.

ManifestError

The algorithm interface is invalid (ALGORITHM_FILE_INVALID and its siblings).

McapMessage

A decoded ROS 2 message: topic, schema, log_time_s (seconds since the file's first message).

McapReader

An MCAP file read through its summary and only the chunks a query needs.

AttributeMeaning
duration_s: float
end_ns: int
start_ns: int
topics: list[McapTopic]
MethodMeaning
messages(topics: Sequence[str] | None=None, start_s: float | None=None, end_s: float | None=None) -> Iterator[McapMessage]Decoded messages in log-time order; topics filters by name, start_s/end_s bound log time.

McapTopic

One topic of an MCAP file: name, message schema name, message count and average rate in Hz.

AttributeMeaning
count: int
name: str
rate: float
schema: str

Member

One episode of a dataset version.

AttributeMeaning
duration_s: floatLength of the episode in seconds.
end_s: float
episode_id: str
features: dict[str, Any]
labels: dict[str, Any]
operator: str | None
quality: dict[str, Any]
recording_id: str
root: str
session: str | None
split: str | None
start_s: float
task: str | None
MethodMeaning
recording() -> RecordingThe episode's recording window, downloading its files on first use.

OutputError

A writer refused what the algorithm gave it.

RawFile

One uploaded file: path (relative to the upload root), size in bytes and local_path on disk.

AttributeMeaning
local_path: Path
path: str
size: int
MethodMeaning
open(mode: str='rb') -> IO[Any]Open the file (read-only; binary by default).

RawFiles

One recording's uploaded files, at their upload-relative paths.

AttributeMeaning
files: list[RawFile]
MethodMeaning
find(pattern: str) -> list[RawFile]The files whose path matches the glob pattern (* within a folder, ** across folders).
read_json(path: str) -> AnyParse the JSON file at path.
read_yaml(path: str) -> AnyParse the YAML file at path.
mcap(path: str | None=None) -> 'McapReader'Open an MCAP file; path may be omitted when the upload holds exactly one.

Recording

The canonical recording (LeRobot v3 tree plus meta/embodiflow/recording.json), or a time window of it.

AttributeMeaning
calibration: dict[str, Any]The conventions sidecar's calibration: frames, stereoPairs and timeOffsets as stored.
cameras: list[Camera]
columns: list[Column]
conventions: dict[str, Any]
duration_s: floatLength in seconds.
facts: dict[str, Any]
fps: float
info: dict[str, Any]
kind: str | None
meta: dict[str, Any]
num_frames: int
start_s: floatWhere this recording (or episode window) starts on the recording timeline, in seconds.
stereo_pairs: list[dict[str, str]]
task: str | None
total_frames: int
MethodMeaning
window(start_s: float, end_s: float) -> 'Recording'The part of this recording between start_s and end_s (seconds on this recording's own timeline).
table(columns: Sequence[str] | None=None) -> 'pa.Table'The frame table (one row per frame of this recording or window) as a pyarrow.Table.
column(name: str) -> 'np.ndarray'One column as a numpy array of shape (num_frames, *shape).

RecordingBuilder

Builds the canonical recording from a source format.

AttributeMeaning
checks: 'CheckWriter'The CheckWriter for the checks this algorithm declared (checks=[Check(...)]).
root: PathThe output folder of the recording port (for :meth:adopt_tree).
MethodMeaning
adopt_tree() -> NoneSay that the run wrote the complete canonical tree under out.root itself (a built-in standardizer with its own tree writer).
fps(value: int) -> NoneDeclare the frame rate of the recording: 30 (the platform grid; other rates are refused).
task(text: str) -> NoneSet the task text of the recording (one episode, one task).
camera(key: str, role: str, frames: Iterable[Any] | Any=None, video: str | Path | None=None, intrinsics: Sequence[Sequence[float]] | None=None, distortion: Sequence[float] | None=None, model: str | None=None) -> NoneAdd a camera from RGB frames (an array N x H x W x 3 uint8 or an iterator of H x W x 3 frames) or a video file.
column(name: str, values: Any, type: str='vector', unit: str='none', frame: str='none', source: str='recorded', names: Sequence[str] | None=None) -> NoneAdd a tabular column with one row per frame: values has shape (N,) or (N, ...).
timestamps(seconds: Any) -> NoneRecord the source capture time of each row (seconds, non-decreasing); kept beside the recording.
stereo_pair(left: str, right: str) -> NoneName two added cameras as a stereo pair (keys or short names).
dropped(what: str, reason: str) -> NoneDeclare something of the source that did not make it into the recording, and why.

RecordingEditor

Edits the input recording: replace or drop a camera, replace a column, trim.

AttributeMeaning
checks: 'CheckWriter'The CheckWriter for the checks this algorithm declared (checks=[Check(...)]).
root: PathThe output folder of the recording port (for :meth:adopt_tree).
MethodMeaning
adopt_tree() -> NoneSay that the run wrote the complete edited tree under out.root itself (a built-in transform with its own video path, such as anonymize with its hardware encoder).
unchanged() -> NoneHand the input recording through untouched (zero copy).
replace_camera(key: str, frames: Iterable[Any] | Any=None, video: str | Path | None=None, anonymized: bool | None=None) -> NoneReplace the pictures of camera key with frames (an iterator of H x W x 3 uint8 images, one per input frame) or a video.
drop_camera(key: str) -> NoneRemove camera key from the recording.
replace_column(name: str, values: Any) -> NoneReplace the values of column name; values has the shape of the existing column (one row per input frame).
trim(start_s: float, end_s: float) -> NoneKeep only start_s..end_s (seconds) of the recording.

SelectionWriter

Collects per-episode decisions (embodiflow-selection/v1).

AttributeMeaning
checks: 'CheckWriter'The CheckWriter for the checks this algorithm declared (checks=[Check(...)]).
MethodMeaning
keep(episode_id: str, split: str | None=None, task: str | None=None, reason: str | None=None) -> NoneKeep the episode, optionally assigning a split (train/val/test) and replacing its task text.
count(name: str, value: int) -> NoneReport a named count in the selection summary (summary.counts), e.g. count("grouped_by_recording", 3).
drop(episode_id: str, reason: str) -> NoneDrop the episode from the new version; reason is shown to the team.

SetupContext

What setup(ctx) sees: the params, the facts, a scratch directory and a logger.

AttributeMeaning
facts: Facts
log: logging.Logger
params: Any
run_id: strThe workflow run id.
step_id: strThe id of the step in the workflow.
tmp: Path

TransientError

Raise it when a retry may succeed (network, GPU busy): the step exits 88 and is retried.

Vocabulary

NameAllowed values
categoriesstandardize, check, transform, enrich, segment, curate, export
levelsrecording, episode, dataset
statusespass, warn, fail, error, not_evaluated, not_applicable
perframe, recording, episode, file
sourcesrecorded, imported, estimated, computed, retargeted
dtypesfloat32, float64, int8, int16, int32, int64, uint8, uint16
splitstrain, val, test
semanticTypesscalar, vector, label.bool, label.category, label.text, spans, embedding, pose.se3, keypoints3d.hand21, skeleton.hand21, skeleton.body22, keypoints2d, confidence, calibration.stereo, calibration.cam_imu, depth.video, mask.video, video.preview, ros2.mcap, action.joint, action.ee_pose, json
factskind, format, privacy_required, duration_s, cameras, stereo, imu, action, recorded_hand_pose, gripper_width, episodes
privacyredacts, numbers_only
servicesvlm
runParametersraw, recording, version, episode, out, ctx, state

Next

  • Interface reference
  • Troubleshooting
Previous

Interface reference

Next

Command line