# robot_descriptions: robot models as Python imports, cached after first use

> This package turns URDF, MJCF and Xacro robot descriptions into Python modules that download on first import and cache for later, with loaders for six robotics toolkits. The trade-off is that your test suite now depends on a network fetch and a git clone, and the description list is a moving target.

**robot-descriptions/robot_descriptions.py** — Access 200+ robot descriptions from the main Python robotics frameworks

- Repository: https://github.com/robot-descriptions/robot_descriptions.py
- Stars: 846 · Forks: 75
- Language: Python
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/robot-descriptions-robot-descriptions-py

## Robot descriptions become importable modules

The project is a Python library whose purpose is to import open source robot descriptions as Python modules. The description of the repository puts the scope plainly: 200+ robot descriptions from the main Python robotics frameworks. A robot description in this context is a URDF or MJCF file plus its meshes, and the practical problem is that every project ends up vendoring them, in different versions, with different conventions. This package replaces that with an import. A module named after the robot, for example upkie_description, becomes importable, and the underlying files are fetched on first use and cached locally. The README states that most descriptions in the Awesome Robot Descriptions catalog are available and that all of them load successfully in respectively MuJoCo, PyBullet, iDynTree, Pinocchio or yourdfpy. The value is not that the files are novel, it is that the retrieval, the cache and the path handling are handled once, in one place, with a consistent interface.

## The cache is what makes the first import expensive

Importing a description for the first time automatically downloads and caches files for future imports. That sentence is the whole operational profile of the library. The first import in a fresh environment is a network operation that can take a while, because a robot description is a git repository with meshes, and the REPOSITORY_PATH the submodule exposes is described as the path to the working directory of the git repository hosting the robot description. GitPython is a runtime dependency for that reason, alongside tqdm which provides the progress reporting. The consequence for a test suite is direct: a run on a cold machine spends time fetching, and a run on a warm machine does not. If your CI gives each job a fresh container, that cost is paid every time. The library does provide a way to decouple the fetch from the use, since the command line has a pull command to download a description to the cache ahead of time, which is the shape of a warm-up step in a pipeline. The README does not document a way to pin a specific commit of a description, so the revision you get depends on what the upstream repository serves at fetch time.

## One loader per simulator, and the extras are optional

The library provides load_robot_description functions that return an instance of a robot description directly usable in the corresponding software, and the smallest possible example shows it:

```python
from robot_descriptions.loaders.pinocchio import load_robot_description

robot = load_robot_description("upkie_description")
```

There is one loader module per supported toolkit: robot_descriptions.loaders.idyntree, .mujoco, .pinocchio, .pybullet, .robomeshcat and .yourdfpy. The pattern is consistent enough that switching simulator means changing the import, which is the property that matters when a team has one model and several simulators. The optional dependency groups mirror that list exactly, in the pyproject.toml, where the opts extra names idyntree, mujoco, pin, pybullet, robomeshcat, xacrodoc and yourdfpy with their version floors. Only two things are hard requirements: GitPython and tqdm. So you can install the base package and use only the submodule import form, which gives you paths rather than a loaded model, and you pay for a simulator integration only when you use one. The classifier list also marks the package as a Robot Framework library, which suggests it is usable as a fixture provider in Robot Framework suites.

## Submodule import gives you paths, not a model

There is a second, lower-level way to use the package, importing the description as a submodule of robot_descriptions:

```python
from robot_descriptions import my_robot_description
```

That import still downloads and caches the description if it is not already local. What it gives you is a set of path constants rather than a loaded robot. URDF_PATH or MJCF_PATH points to the main description file, PACKAGE_PATH points to the root of the description package, and REPOSITORY_PATH points to the working directory of the git repository that hosts the description. This is the form to use when you are feeding the file into your own tooling, a URDF parser, a mesh pipeline or a viewer you control. Descriptions can also export extra fields, and the example given is that iiwa14_description exports URDF_PATH_POLYTOPE_COLLISION with more detailed collision meshes, so a description is not guaranteed to expose only the three standard paths. A description can also define XACRO_PATH with an optional XACRO_ARGS instead of a static URDF_PATH, in which case the library renders the Xacro to a cached URDF transparently at load time.

## A command line for pulling and viewing without writing code

The package ships a command line, and the README recommends uv for it. The command is a uvx invocation, so no install is needed for a one-off:

```bash
# Download a robot description to cache
uvx robot_descriptions pull iiwa14_description

# Display a robot description
uvx --with mujoco-python-viewer robot_descriptions show_in_mujoco go2_mj_description
uvx --with meshcat --with pin robot_descriptions show_in_meshcat go2_description
uvx --with robomeshcat robot_descriptions show_in_meshcat go2_description
uvx --with pybullet robot_descriptions show_in_pybullet go2_description
uvx --with yourdfpy robot_descriptions show_in_yourdfpy go2_description
```

The pull command is the one that belongs in a pipeline, since it moves the network cost out of the first import. The show commands are the practical way to check that a description loads in a given simulator before you write code against it, and each one pulls in the viewer it needs with an extra --with flag, so you are not forced to install six simulators to look at one robot. Once the package is installed from PyPI or conda-forge you can call the robot_descriptions alias directly, replace uvx with uv run, or use python -m robot_descriptions for the old school path. The entry point is declared in the pyproject.toml as robot_descriptions = robot_descriptions.__main__:main.

## The catalogue is community maintained, and categories overlap

The list of descriptions is generated rather than hand written, and the README marks a generated block of tables in the source. Descriptions are sorted into arms, bipeds, dual arms, drones, educational, end effectors, humanoids, mobile manipulators, quadrupeds and wheeled. A DOF column denotes the number of actuated degrees of freedom, and the README notes that descriptions may appear in more than one category when tags overlap, which is a small sign that the taxonomy is derived from tags rather than curated by hand. The underlying source of truth is the Awesome Robot Descriptions gallery. That has an upside and a downside. The upside is breadth, and the fact that a new robot model shows up without anyone writing a loader. The downside is that the catalogue is a community project rather than a curated, versioned dependency of this package, so a description can change upstream and change behaviour in your simulation without a release of robot_descriptions. If your work depends on a specific collision mesh or a specific joint limit, that is exactly the kind of thing to verify rather than assume.

## Apache-2.0, a 3.x line, and two lock files in the repository

The licence is Apache-2.0, recorded in the LICENSE file and confirmed by the OSI approved Apache Software License classifier in the project metadata. That is a permissive licence with an explicit patent grant, which is why it is a comfortable choice for a library that is imported rather than vendored. The repository is not archived and the last push was on 2026-10-16, and the releases are frequent: v3.1.0 on 2026-07-23, v3.2.0 on 2026-09-12 and v3.3.0 on 2026-10-12, three minor releases in one quarter. The version is still below a 4.0, and the project is marked Development Status 5, Production/Stable. The build backend is flit_core through flit_core.buildapi, and the version and description are dynamic, which means they are read from the package source rather than duplicated in the manifest. The repository carries two lock files, uv.lock and pixi.lock, alongside pyproject.toml, which tells you the maintainer supports both the uv and pixi workflows, and there is a CHANGELOG.md and a CITATION.cff for academic use.

## Conclusion

Adopt robot_descriptions if you work in simulation or robotics and want a maintained, uniform way to fetch robot models instead of vendoring URDF files into your repository, and if your environment can reach the network on first import. Do not adopt it for an offline or hermetic test environment, because the first import downloads and caches files, and do not treat the model list as a stable contract because descriptions come from a community catalog and the package does not pin which revision a given robot uses. Before you commit, warm the cache for the robots your tests need, check the loader optional dependencies you actually install, and read the CHANGELOG.md for how the loading behaviour has changed between releases.

## FAQ

### What is robot_descriptions?

It is an Apache-2.0 licensed Python package that imports open source robot descriptions as Python modules, covering 200+ descriptions from the main Python robotics frameworks. Importing a description for the first time downloads and caches the files for later imports.

### How do I install robot_descriptions?

From conda-forge with conda install -c conda-forge robot_descriptions, or from PyPI with pip install robot_descriptions. The package requires Python 3.10 or later, and simulator support is installed through optional dependency groups named idyntree, mujoco, pin, pybullet, robomeshcat, xacrodoc and yourdfpy.

### How do I load a robot description in Python?

Import the loader for the simulator you want and call load_robot_description with the description name, for example from robot_descriptions.loaders.pinocchio import load_robot_description followed by load_robot_description("upkie_description"). The result is an instance directly usable in that software.

### Can robot_descriptions work offline?

Not without preparation. The first import downloads and caches the description files, so a network fetch is required the first time. The command line provides uvx robot_descriptions pull iiwa14_description to download a description to the cache in advance, which is the way to warm the cache ahead of a test run.

## Sources

- [Issues](https://github.com/robot-descriptions/robot_descriptions.py/issues)
- [License: Apache-2.0](https://github.com/robot-descriptions/robot_descriptions.py/blob/main/LICENSE)
- [README](https://github.com/robot-descriptions/robot_descriptions.py/blob/main/README.md)
- [Releases](https://github.com/robot-descriptions/robot_descriptions.py/releases)
- [robot-descriptions/robot_descriptions.py on GitHub](https://github.com/robot-descriptions/robot_descriptions.py)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/robot-descriptions-robot-descriptions-py
