LeRobot documentation

Создание docstrings

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Создание docstrings

Справочник API LeRobot генерируется непосредственно из docstrings в src/lerobot/. Docstring — это не комментарий, а опубликованная документация для данного объекта, и формат, описанный ниже, является тем, что парсят рендерер и проверки CI.

Эта страница является контрактом. Если вы добавляете или редактируете что-либо публичное в src/lerobot/, следуйте ему.

Недокументированный публичный метод — это невидимый метод. [[autodoc]] молча пропускает элементы, у которых нет docstring, — без предупреждений и ошибок, они просто не появляются на отрендеренной странице. Покрытие и полнота справочника API — это одна и та же проблема.

Формат в одном примере

Заголовки разделов Google, форматирование типов Hugging Face. И то, и другое, а не одно из них.

def send_action(self, action: RobotAction, rate_hz: float = 30.0) -> RobotAction:
    """Command the robot to move to a target joint configuration.

    Values are clipped by the configured maximum relative target before reaching the motors, so the
    returned action may differ from the requested one.

    Args:
        action (`dict[str, float]`):
            Target values keyed by motor name, e.g. `{"shoulder_pan.pos": 0.0}`. Keys must match the
            robot's action features.
        rate_hz (`float`, *optional*, defaults to `30.0`):
            Control loop frequency.

    Returns:
        `dict[str, float]`: The action actually written to the motors after safety clipping.

    Raises:
        DeviceNotConnectedError: If the robot has not been connected.

    Example:
        ```python
        >>> from lerobot.robots.so_follower import SO101Follower, SO101FollowerConfig
        >>> robot = SO101Follower(SO101FollowerConfig(port="/dev/ttyACM0"))  # doctest: +SKIP
        >>> robot.connect()  # doctest: +SKIP
        >>> robot.send_action({"shoulder_pan.pos": 0.0})  # doctest: +SKIP
        ```
    """

Ссылки на другие разделы опущены в примерах на этой странице — см. Ссылки на другие разделы для синтаксиса и объяснения, почему их нельзя отображать внутри блока кода.

Правила

Разделы

Args: · Returns: · Raises: · Yields: · Example: · Note:

В таком порядке. Никаких других заголовков разделов. Сначала — однострочное резюме, затем — необязательное свободное описание, а после — разделы.

Строка Args: обрабатывается машиной

name (`type`, *optional*, defaults to `X`):
    Description, indented on its own line.

Кlaus *optional*, defaults to проверяется на соответствие фактическому значению по умолчанию в сигнатуре с помощью make check-docstrings. Это не просто формальность — если указанное вами значение по умолчанию разошлось с кодом, CI завершится с ошибкой. Для обязательных параметров полностью опускайте этот klaus:

    Args:
        port (`str`):
            Serial port the arm is connected to, e.g. `/dev/ttyACM0`.
        max_relative_target (`float | dict[str, float]`, *optional*):
            Caps the magnitude of the relative positional target vector. `None` disables clipping.
        use_degrees (`bool`, *optional*, defaults to `True`):
            Keep `True` for backward compatibility with existing policies and datasets.

Типы указываются в обратных кавычках. Используйте *optional* без defaults to, если значение по умолчанию равно None или его не стоит повторять.

Возвращает: is type-first

Одна отступная строка: сначала тип, затем двоеточие, затем описание:

    Returns:
        `dict[str, float]`: The action actually written to the motors after safety clipping.

Yields: принимает ту же форму.

**Атрибуты**: , никогда Атрибуты:

doc-builder интерпретирует одиночное Attributes: как синоним Parameters:, из-за чего ваши атрибуты отображаются как аргументы конструктора. Это происходит без предупреждений и является ошибкой. Если атрибуты отличаются от параметров конструктора, используйте жирную форму с разделителем --:

class Robot(abc.ABC):
    """The base abstract class for all LeRobot-compatible robots.

    **Attributes**:
        - **config_class** (`type[RobotConfig]`) -- The expected configuration class for this robot.
        - **name** (`str`) -- The unique robot name used to identify this robot type.
    """

Обратите внимание --, а не :.

Ссылки

Используйте синтаксис скобок doc-builder: путь в квадратных скобках, заключённый в обратные кавычки. Роли Sphinx (:pymeth:, :pyattr:) не поддерживаются и отображаются на странице как обычный текст.

ХотитеЗапись
Класс в основном пакете[Robot]
Метод, показать полный путь[Robot.connect]
Метод, показать только имя[~Robot.connect]
Вложенный путь[~robots.Robot.connect]
Объект в другой библиотеке HF[~accelerate.Accelerator]

Символ ~ удаляет путь только из текста ссылки; сама ссылка по-прежнему указывает на полный путь.

doc-builder разрешает этот синтаксис везде на странице — в том числе внутри блоков кода с ограничителями. Именно поэтому примеры в docstring на этой странице используют обычный текст, а не перекрёстные ссылки: блок кода, содержащий такую ссылку, отобразит разрешённую ссылку, а не синтаксис, который нужно ввести. В собственных docstring вы можете свободно использовать перекрёстные ссылки; это ограничение касается только документации о синтаксисе.

Выделенные блоки

Используйте цитаты в стиле GitHub:

> [!TIP]
> Call this once at startup — it takes about two seconds.

> [!WARNING]
> Torque is disabled on disconnect. The arm will drop if it is holding a load.

Компонент <Tip> считается устаревшим в doc-builder; не добавляйте новые.

Примеры должны быть заключены в забор

Пример находится внутри блока ```python, содержащего >>>. Именно этот блок заставляет его отображаться как фрагмент кода, и именно его ищет регулярное выражение препроцессора doctest:

    Example:
        ```python
        >>> from lerobot.robots.so_follower import SO101FollowerConfig
        >>> cfg = SO101FollowerConfig(port="/dev/ttyACM0")
        >>> cfg.use_degrees
        True
        ```

Незакрытый >>> всё равно будет собран — doctest находит промпты в любом месте docstring. Вы теряете только отображение, поэтому на странице это выглядит как сплошной текст. Каждому примеру нужен забор.

Каждый пример либо выполняется в CI, либо содержит # doctest: +SKIP. Всё, что связано с оборудованием, GPU или загрузкой с Hub, получает +SKIP:

    Example:
        ```python
        >>> robot.connect()  # doctest: +SKIP
        >>> policy = ACTPolicy.from_pretrained("lerobot/act_aloha_sim_transfer_cube_human")  # doctest: +SKIP
        ```

Добавьте файлы с запускаемыми примерами в utils/documentation_tests.txt.

Размещайте примеры на трёх-пяти реальных точках входа модуля. Примеры для тривиальных аксессоров — это шум.

Три паттерна, с которыми вы будете сталкиваться постоянно

Данные классов конфигурации

Поле конфигурации исторически документируется с помощью комментариев # над каждым полем. doc-builder не видит инлайн-комментарии — такой класс отображается со списком всех полей, но без единого описания. Перенесите их в блок Args: в docstring класса:

@dataclass
class SOFollowerConfig:
    """Configuration for SO-family follower arms.

    Args:
        port (`str`):
            Serial port the arm is connected to, e.g. `/dev/ttyACM0`.
        max_relative_target (`float | dict[str, float]`, *optional*):
            Caps the magnitude of the relative positional target vector. A scalar applies to all motors;
            a dict maps motor name to a per-motor cap. `None` disables clipping.
        use_degrees (`bool`, *optional*, defaults to `True`):
            Keep `True` for backward compatibility with existing policies and datasets.
    """

    port: str
    max_relative_target: float | dict[str, float] | None = None
    use_degrees: bool = True

doc-builder не наследует docstrings от базовых классов. Зарегистрированные классы конфигурации LeRobot часто представляют собой тонкие обёртки с множественным наследованием:

@RobotConfig.register_subclass("so101_follower")
@dataclass
class SOFollowerRobotConfig(RobotConfig, SOFollowerConfig):
    pass

Этот класс отображает все поля — включая унаследованные — без каких-либо описаний, независимо от того, насколько хорошо документированы базовые классы. Блок Args: должен находиться в конкретном классе, который указывает [[autodoc]], и он должен покрывать и унаследованные поля.

Базовый класс, затем конкретный подкласс

Абстрактный базовый класс содержит канонический контракт. Подклассы документируют только то, что отклоняется от него — семантику портов, особенности калибровки, компоновку моторов, поддерживаемые ключи функций. Не копируйте базовый контракт в каждый подкласс.

Robot, Teleoperator, Camera, MotorsBusBase, ProcessorStep и PreTrainedPolicy все следуют этой структуре.

Псевдонимы на уровне модуля

Несколько публичных имён являются псевдонимами, а не отдельными классами:

SO100FollowerConfig = SOFollowerRobotConfig
SO101FollowerConfig = SOFollowerRobotConfig

[[autodoc]] разрешает псевдоним и отображает каноническое имя класса, поэтому заголовок ## SO101FollowerConfig в тексте будет показывать class lerobot.robots.so_follower.SOFollowerRobotConfig. Документируйте канонический класс один раз, а псевдонимы упоминайте в тексте страницы, а не создавайте для каждого псевдонима отдельный блок autodoc.

Чего не следует документировать

  • Служебные члены. Всё, что начинается с _, не входит в публичный API.
  • Аннотация типа, переформулированная в виде текста. port (str): A string. ничего не добавляет. Укажите, для чего она предназначена.
  • Вендорный код из upstream. src/lerobot/policies/molmoact2/molmoact2_hf_model/ является вендорным из transformers и уже содержит docstrings в стиле upstream. Не трогайте его — перестиллинг приведёт только к конфликтам при следующей синхронизации. Этот код исключён из API reference и из проверок docstrings.

Как это обеспечивается

ПроверкаЧто он выявляет
make check-docstringsЗапись Args:, не соответствующая сигнатуре; задокументированное значение по умолчанию, отличающееся от фактического
make doctestПримеры, которые больше не работают
make check-doctest-listУстаревшие или не отсортированные записи в utils/documentation_tests.txt
ruff (правила D)Нарушения стиля по конвенции Google
interrogateДоля покрытых docstring ниже текущего порога
doc-builderПуть [[autodoc]], указывающий на несуществующий объект — это приводит к сбою сборки документации

Запускайте их вместе перед созданием PR:

make check-docstrings && make doctest && pre-commit run --all-files

Затем отрендерьте страницу и действительно посмотрите на неё:

doc-builder build lerobot docs/source/ --build_dir /tmp/doc-build

Чек-лист

  • У каждого публичного члена, к которому вы обращались, есть строка документации.
  • Каждая запись Args: соответствует сигнатуре, включая *optional*, defaults to.
  • Returns: имеет тип-сначала на одной отступленной строке.
  • Без «голых» Attributes: — используйте **Attributes**: с разделителями --.
  • Роли Sphinx не используются — перекрёстные ссылки оформляются как [~module.Class.method].
  • Примеры находятся внутри блока ```python и либо запускаются в CI, либо содержат # doctest: +SKIP.
  • Поля dataclass конфигурации находятся в блоке Args: конкретного класса, а не в комментариях #.
  • Отрендеренная страница проверена визуально.
Update on GitHub