rod


Namerod JSON
Version 0.3.4 PyPI version JSON
download
home_pageNone
SummaryThe ultimate Python tool for RObot Descriptions processing.
upload_time2024-11-26 14:49:01
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseBSD 3-Clause License Copyright (c) 2022, Artificial and Mechanical Intelligence All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
keywords description gazebo parser robot robotics ros sdf sdformat simulator simulation urdf
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # RObot Description processor

**The ultimate Python tool for RObot Descriptions processing.**

ROD is yet another library to operate on robot descriptions based on the [SDFormat][sdformat] specification.

## Why SDFormat?

Among the many existing robot description formats, SDFormat provides a well-defined and maintained [versioned specification][sdformat_spec] that controls the available fields and their content.
[Open Robotics][open_robotics] already provides the C++ library [`gazebosim/sdformat`](https://github.com/gazebosim/sdformat) with initial support of [Python bindings][sdformat_python].
However, C++ dependencies in pure-Python projects are typically quite complicated to handle and maintain.
Here ROD comes to rescue.

URDF, thanks to native ROS support, is historically the most popular robot description used by the community.
The main problem of URDF is that it is not a specification, and developers of URDF descriptions might produce models and parsers that do not comply to any standard.
Luckily, URDF models can be easily converted to SDF[^urdf_to_sdf].
If the URDF model is not compliant, the process errors with clear messages.
Furthermore, modern versions of the converter produce a SDF description with standardized [pose semantics][pose_semantics],
that greatly simplifies the life of downstream developers that do not have to guess the reference frame or pose elements.
Last but not least, the pose semantics also makes SDF aware of the concept of _frame_ that URDF is missing.

## Features

- Out-of-the-box support for SDFormat specifications [≥ 1.10][sdformat_spec_110].
- Serialization and deserialization support for SDF files.
- In-memory layout based on `dataclasses`.
- Syntax highlighting and auto-completion.
- Programmatic creation of SDF files from Python APIs.
- Transitive support for URDF through conversion to SDF.
- Type validation of elements and attributes.
- Automatic check of missing required elements.
- High-performance serialization and deserialization using [`Fatal1ty/mashumaro`][mashumaro].
- Export in-memory model description to URDF.

[mashumaro]: https://github.com/Fatal1ty/mashumaro
[open_robotics]: https://www.openrobotics.org/
[pose_semantics]: http://sdformat.org/tutorials?tut=pose_frame_semantics_proposal&cat=pose_semantics_docs&
[sdformat]: http://sdformat.org/
[sdformat_python]: http://sdformat.org/tutorials?tut=python_bindings&cat=developers&
[sdformat_spec]: http://sdformat.org/spec
[sdformat_spec_110]: http://sdformat.org/spec?elem=sdf&ver=1.10
[urdf]: http://wiki.ros.org/urdf

[^urdf_to_sdf]: Conversion can be done using the `gz sdf` command included in Gazebo Sim starting from Garden.

## Installation

> [!TIP]
> ROD does not support out-of-the-box URDF files.
> URDF support is obtained by converting URDF files to SDF using the `gz sdf` command provided by [sdformat][sdformat_repo] and [gz-tools][gz-tools_repo].
> Ensure these tools are installed on your system if URDF support is needed (more information below).

[sdformat_repo]: https://github.com/gazebosim/sdformat
[gz-tools_repo]: https://github.com/gazebosim/gz-tools

<details>
<summary>Using conda (recommended)</summary>

Installing ROD using `conda` is the recommended way to obtain a complete installation with out-of-the-box support for both URDF and SDF descriptions:

```bash
conda install rod -c conda-forge
```

This will automatically install `sdformat` and `gz-tools`.

</details>

<details>
<summary>Using pip</summary>

You can install ROD from PyPI with [`pypa/pip`][pip], preferably in a [virtual environment][venv]:

```bash
pip install rod[all]
```

If you need URDF support, follow the [official instructions][gazebo_sim_docs] to install Gazebo Sim on your operating system,
making sure to obtain `sdformat ≥ 13.0` and `gz-tools ≥ 2.0`.

You don't need to install the entire Gazebo Sim suite.
For example, on Ubuntu, you can only install the `libsdformat13 gz-tools2` packages.

[pip]: https://github.com/pypa/pip/
[venv]: https://docs.python.org/3.10/tutorial/venv.html
[gazebo_sim_docs]: https://gazebosim.org/docs

</details>

## Examples

<details>
<summary>Serialize and deserialize SDF files</summary>

```python
import pathlib

from rod import Sdf

# Supported SDF resources
sdf_resource_1 = "/path/to/file.sdf"
sdf_resource_2 = pathlib.Path(sdf_resource_1)
sdf_resource_3 = sdf_resource_2.read_text()

# Deserialize SDF resources
sdf_1 = Sdf.load(sdf=sdf_resource_1)
sdf_2 = Sdf.load(sdf=sdf_resource_2)
sdf_3 = Sdf.load(sdf=sdf_resource_3)

# Serialize in-memory Sdf object
print(sdf_3.serialize(pretty=True))
```

</details>

<details>
<summary>Create SDF models programmatically</summary>

```python
from rod import Axis, Inertia, Inertial, Joint, Limit, Link, Model, Sdf, Xyz

sdf = Sdf(
    version="1.7",
    model=Model(
        name="my_model",
        link=[
            Link(name="base_link", inertial=Inertial(mass=1.0, inertia=Inertia())),
            Link(name="my_link", inertial=Inertial(mass=0.5, inertia=Inertia())),
        ],
        joint=Joint(
            name="base_to_my_link",
            type="revolute",
            parent="base_link",
            child="my_link",
            axis=Axis(xyz=Xyz(xyz=[0, 0, 1]), limit=Limit(lower=-3.13, upper=3.14)),
        ),
    ),
)

print(sdf.serialize(pretty=True))
```

```xml
<?xml version="1.0" encoding="utf-8"?>
<sdf version="1.7">
  <model name="my_model">
    <link name="base_link">
      <inertial>
        <mass>1.0</mass>
        <inertia>
          <ixx>1.0</ixx>
          <iyy>1.0</iyy>
          <izz>1.0</izz>
          <ixy>0.0</ixy>
          <ixz>0.0</ixz>
          <iyz>0.0</iyz>
        </inertia>
      </inertial>
    </link>
    <link name="my_link">
      <inertial>
        <mass>0.5</mass>
        <inertia>
          <ixx>1.0</ixx>
          <iyy>1.0</iyy>
          <izz>1.0</izz>
          <ixy>0.0</ixy>
          <ixz>0.0</ixz>
          <iyz>0.0</iyz>
        </inertia>
      </inertial>
    </link>
    <joint name="base_to_my_link" type="revolute">
      <parent>base_link</parent>
      <child>my_link</child>
      <axis>
        <xyz>0 0 1</xyz>
        <limit>
          <lower>-3.13</lower>
          <upper>3.14</upper>
        </limit>
      </axis>
    </joint>
  </model>
</sdf>
```

</details>

<details>
<summary>Exporting SDF to URDF</summary>

```python
# Generate first the 'sdf' object with the collapsed code
# of the section 'Create SDF models programmatically'.

from rod.urdf.exporter import UrdfExporter

urdf_string = UrdfExporter(pretty=True, gazebo_preserve_fixed_joints=True).to_urdf_string(
    sdf=sdf
)

print(urdf_string)
```

```xml
<?xml version="1.0" encoding="utf-8"?>
<robot name="my_model">
  <link name="base_link">
    <inertial>
      <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
      <mass value="1.0"/>
      <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
    </inertial>
  </link>
  <link name="my_link">
    <inertial>
      <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
      <mass value="0.5"/>
      <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
    </inertial>
  </link>
  <joint name="base_to_my_link" type="revolute">
    <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
    <parent link="base_link"/>
    <child link="my_link"/>
    <axis xyz="0 0 1"/>
    <limit effort="3.4028235e+38" velocity="3.4028235e+38" lower="-3.13" upper="3.14"/>
  </joint>
</robot>
```

</details>

## Similar projects

- https://github.com/gazebosim/sdformat
- https://github.com/mmatl/urdfpy
- https://github.com/clemense/yourdfpy
- https://github.com/ros/urdf_parser_py
- https://github.com/FirefoxMetzger/python-sdformat/

## Contributing

Pull requests are welcome.
For major changes, please open an issue first to discuss what you would like to change.

## People

### Author

| [<img src="https://github.com/diegoferigo.png" width="40">][df] | [@diegoferigo][df] |
|:---------------------------------------------------------------:|:------------------:|

[df]: https://github.com/diegoferigo

### Maintainers

| [<img src="https://github.com/flferretti.png" width="40">][ff] | [@flferretti][ff] | [<img src="https://github.com/CarlottaSartore.png" width="40">][cs] | [@CarlottaSartore][cs] |
|:---------------------------------------------------------------:|:------------------:|:---------------------------------------------------------------:|:------------------:|



[ff]: https://github.com/flferretti
[cs]: https://github.com/CarlottaSartore

## License

[BSD3](https://choosealicense.com/licenses/bsd-3-clause/)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "rod",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": "Filippo Luca Ferretti <filippo.ferretti@iit.it>, Carlotta Sartore <carlotta.sartore@iit.it>",
    "keywords": "description, gazebo, parser, robot, robotics, ros, sdf, sdformat, simulator, simulation, urdf",
    "author": null,
    "author_email": "Diego Ferigo <dgferigo@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/d9/6e/83f825f6015e09b0ee248b5226f461deeaaf80f79748a6dd338271086df2/rod-0.3.4.tar.gz",
    "platform": null,
    "description": "# RObot Description processor\n\n**The ultimate Python tool for RObot Descriptions processing.**\n\nROD is yet another library to operate on robot descriptions based on the [SDFormat][sdformat] specification.\n\n## Why SDFormat?\n\nAmong the many existing robot description formats, SDFormat provides a well-defined and maintained [versioned specification][sdformat_spec] that controls the available fields and their content.\n[Open Robotics][open_robotics] already provides the C++ library [`gazebosim/sdformat`](https://github.com/gazebosim/sdformat) with initial support of [Python bindings][sdformat_python].\nHowever, C++ dependencies in pure-Python projects are typically quite complicated to handle and maintain.\nHere ROD comes to rescue.\n\nURDF, thanks to native ROS support, is historically the most popular robot description used by the community.\nThe main problem of URDF is that it is not a specification, and developers of URDF descriptions might produce models and parsers that do not comply to any standard.\nLuckily, URDF models can be easily converted to SDF[^urdf_to_sdf].\nIf the URDF model is not compliant, the process errors with clear messages.\nFurthermore, modern versions of the converter produce a SDF description with standardized [pose semantics][pose_semantics],\nthat greatly simplifies the life of downstream developers that do not have to guess the reference frame or pose elements.\nLast but not least, the pose semantics also makes SDF aware of the concept of _frame_ that URDF is missing.\n\n## Features\n\n- Out-of-the-box support for SDFormat specifications [\u2265 1.10][sdformat_spec_110].\n- Serialization and deserialization support for SDF files.\n- In-memory layout based on `dataclasses`.\n- Syntax highlighting and auto-completion.\n- Programmatic creation of SDF files from Python APIs.\n- Transitive support for URDF through conversion to SDF.\n- Type validation of elements and attributes.\n- Automatic check of missing required elements.\n- High-performance serialization and deserialization using [`Fatal1ty/mashumaro`][mashumaro].\n- Export in-memory model description to URDF.\n\n[mashumaro]: https://github.com/Fatal1ty/mashumaro\n[open_robotics]: https://www.openrobotics.org/\n[pose_semantics]: http://sdformat.org/tutorials?tut=pose_frame_semantics_proposal&cat=pose_semantics_docs&\n[sdformat]: http://sdformat.org/\n[sdformat_python]: http://sdformat.org/tutorials?tut=python_bindings&cat=developers&\n[sdformat_spec]: http://sdformat.org/spec\n[sdformat_spec_110]: http://sdformat.org/spec?elem=sdf&ver=1.10\n[urdf]: http://wiki.ros.org/urdf\n\n[^urdf_to_sdf]: Conversion can be done using the `gz sdf` command included in Gazebo Sim starting from Garden.\n\n## Installation\n\n> [!TIP]\n> ROD does not support out-of-the-box URDF files.\n> URDF support is obtained by converting URDF files to SDF using the `gz sdf` command provided by [sdformat][sdformat_repo] and [gz-tools][gz-tools_repo].\n> Ensure these tools are installed on your system if URDF support is needed (more information below).\n\n[sdformat_repo]: https://github.com/gazebosim/sdformat\n[gz-tools_repo]: https://github.com/gazebosim/gz-tools\n\n<details>\n<summary>Using conda (recommended)</summary>\n\nInstalling ROD using `conda` is the recommended way to obtain a complete installation with out-of-the-box support for both URDF and SDF descriptions:\n\n```bash\nconda install rod -c conda-forge\n```\n\nThis will automatically install `sdformat` and `gz-tools`.\n\n</details>\n\n<details>\n<summary>Using pip</summary>\n\nYou can install ROD from PyPI with [`pypa/pip`][pip], preferably in a [virtual environment][venv]:\n\n```bash\npip install rod[all]\n```\n\nIf you need URDF support, follow the [official instructions][gazebo_sim_docs] to install Gazebo Sim on your operating system,\nmaking sure to obtain `sdformat \u2265 13.0` and `gz-tools \u2265 2.0`.\n\nYou don't need to install the entire Gazebo Sim suite.\nFor example, on Ubuntu, you can only install the `libsdformat13 gz-tools2` packages.\n\n[pip]: https://github.com/pypa/pip/\n[venv]: https://docs.python.org/3.10/tutorial/venv.html\n[gazebo_sim_docs]: https://gazebosim.org/docs\n\n</details>\n\n## Examples\n\n<details>\n<summary>Serialize and deserialize SDF files</summary>\n\n```python\nimport pathlib\n\nfrom rod import Sdf\n\n# Supported SDF resources\nsdf_resource_1 = \"/path/to/file.sdf\"\nsdf_resource_2 = pathlib.Path(sdf_resource_1)\nsdf_resource_3 = sdf_resource_2.read_text()\n\n# Deserialize SDF resources\nsdf_1 = Sdf.load(sdf=sdf_resource_1)\nsdf_2 = Sdf.load(sdf=sdf_resource_2)\nsdf_3 = Sdf.load(sdf=sdf_resource_3)\n\n# Serialize in-memory Sdf object\nprint(sdf_3.serialize(pretty=True))\n```\n\n</details>\n\n<details>\n<summary>Create SDF models programmatically</summary>\n\n```python\nfrom rod import Axis, Inertia, Inertial, Joint, Limit, Link, Model, Sdf, Xyz\n\nsdf = Sdf(\n    version=\"1.7\",\n    model=Model(\n        name=\"my_model\",\n        link=[\n            Link(name=\"base_link\", inertial=Inertial(mass=1.0, inertia=Inertia())),\n            Link(name=\"my_link\", inertial=Inertial(mass=0.5, inertia=Inertia())),\n        ],\n        joint=Joint(\n            name=\"base_to_my_link\",\n            type=\"revolute\",\n            parent=\"base_link\",\n            child=\"my_link\",\n            axis=Axis(xyz=Xyz(xyz=[0, 0, 1]), limit=Limit(lower=-3.13, upper=3.14)),\n        ),\n    ),\n)\n\nprint(sdf.serialize(pretty=True))\n```\n\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<sdf version=\"1.7\">\n  <model name=\"my_model\">\n    <link name=\"base_link\">\n      <inertial>\n        <mass>1.0</mass>\n        <inertia>\n          <ixx>1.0</ixx>\n          <iyy>1.0</iyy>\n          <izz>1.0</izz>\n          <ixy>0.0</ixy>\n          <ixz>0.0</ixz>\n          <iyz>0.0</iyz>\n        </inertia>\n      </inertial>\n    </link>\n    <link name=\"my_link\">\n      <inertial>\n        <mass>0.5</mass>\n        <inertia>\n          <ixx>1.0</ixx>\n          <iyy>1.0</iyy>\n          <izz>1.0</izz>\n          <ixy>0.0</ixy>\n          <ixz>0.0</ixz>\n          <iyz>0.0</iyz>\n        </inertia>\n      </inertial>\n    </link>\n    <joint name=\"base_to_my_link\" type=\"revolute\">\n      <parent>base_link</parent>\n      <child>my_link</child>\n      <axis>\n        <xyz>0 0 1</xyz>\n        <limit>\n          <lower>-3.13</lower>\n          <upper>3.14</upper>\n        </limit>\n      </axis>\n    </joint>\n  </model>\n</sdf>\n```\n\n</details>\n\n<details>\n<summary>Exporting SDF to URDF</summary>\n\n```python\n# Generate first the 'sdf' object with the collapsed code\n# of the section 'Create SDF models programmatically'.\n\nfrom rod.urdf.exporter import UrdfExporter\n\nurdf_string = UrdfExporter(pretty=True, gazebo_preserve_fixed_joints=True).to_urdf_string(\n    sdf=sdf\n)\n\nprint(urdf_string)\n```\n\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<robot name=\"my_model\">\n  <link name=\"base_link\">\n    <inertial>\n      <origin xyz=\"0.0 0.0 0.0\" rpy=\"0.0 0.0 0.0\"/>\n      <mass value=\"1.0\"/>\n      <inertia ixx=\"1.0\" ixy=\"0.0\" ixz=\"0.0\" iyy=\"1.0\" iyz=\"0.0\" izz=\"1.0\"/>\n    </inertial>\n  </link>\n  <link name=\"my_link\">\n    <inertial>\n      <origin xyz=\"0.0 0.0 0.0\" rpy=\"0.0 0.0 0.0\"/>\n      <mass value=\"0.5\"/>\n      <inertia ixx=\"1.0\" ixy=\"0.0\" ixz=\"0.0\" iyy=\"1.0\" iyz=\"0.0\" izz=\"1.0\"/>\n    </inertial>\n  </link>\n  <joint name=\"base_to_my_link\" type=\"revolute\">\n    <origin xyz=\"0.0 0.0 0.0\" rpy=\"0.0 0.0 0.0\"/>\n    <parent link=\"base_link\"/>\n    <child link=\"my_link\"/>\n    <axis xyz=\"0 0 1\"/>\n    <limit effort=\"3.4028235e+38\" velocity=\"3.4028235e+38\" lower=\"-3.13\" upper=\"3.14\"/>\n  </joint>\n</robot>\n```\n\n</details>\n\n## Similar projects\n\n- https://github.com/gazebosim/sdformat\n- https://github.com/mmatl/urdfpy\n- https://github.com/clemense/yourdfpy\n- https://github.com/ros/urdf_parser_py\n- https://github.com/FirefoxMetzger/python-sdformat/\n\n## Contributing\n\nPull requests are welcome.\nFor major changes, please open an issue first to discuss what you would like to change.\n\n## People\n\n### Author\n\n| [<img src=\"https://github.com/diegoferigo.png\" width=\"40\">][df] | [@diegoferigo][df] |\n|:---------------------------------------------------------------:|:------------------:|\n\n[df]: https://github.com/diegoferigo\n\n### Maintainers\n\n| [<img src=\"https://github.com/flferretti.png\" width=\"40\">][ff] | [@flferretti][ff] | [<img src=\"https://github.com/CarlottaSartore.png\" width=\"40\">][cs] | [@CarlottaSartore][cs] |\n|:---------------------------------------------------------------:|:------------------:|:---------------------------------------------------------------:|:------------------:|\n\n\n\n[ff]: https://github.com/flferretti\n[cs]: https://github.com/CarlottaSartore\n\n## License\n\n[BSD3](https://choosealicense.com/licenses/bsd-3-clause/)\n",
    "bugtrack_url": null,
    "license": "BSD 3-Clause License  Copyright (c) 2022, Artificial and Mechanical Intelligence All rights reserved.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ",
    "summary": "The ultimate Python tool for RObot Descriptions processing.",
    "version": "0.3.4",
    "project_urls": {
        "Changelog": "https://github.com/ami-iit/rod/releases",
        "Source": "https://github.com/ami-iit/rod",
        "Tracker": "https://github.com/ami-iit/rod/issues"
    },
    "split_keywords": [
        "description",
        " gazebo",
        " parser",
        " robot",
        " robotics",
        " ros",
        " sdf",
        " sdformat",
        " simulator",
        " simulation",
        " urdf"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4e93c332842a815a7b8813936f22b05cafb6c74b98044a8aa0193fd7195482e1",
                "md5": "8cedb0e5ed779192d77134fc27df5b2f",
                "sha256": "7bff955ad6a5b49fde7dfed2d45d07f56af319ffd4ee3039c648add6b67daffc"
            },
            "downloads": -1,
            "filename": "rod-0.3.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8cedb0e5ed779192d77134fc27df5b2f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 41727,
            "upload_time": "2024-11-26T14:48:59",
            "upload_time_iso_8601": "2024-11-26T14:48:59.757167Z",
            "url": "https://files.pythonhosted.org/packages/4e/93/c332842a815a7b8813936f22b05cafb6c74b98044a8aa0193fd7195482e1/rod-0.3.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d96e83f825f6015e09b0ee248b5226f461deeaaf80f79748a6dd338271086df2",
                "md5": "b8a47252474cb7ef867ff9512f464a93",
                "sha256": "8f4028a56264f35907d0fdfbf9f36f6131fd35a8e721f1301b91892c9622c5e6"
            },
            "downloads": -1,
            "filename": "rod-0.3.4.tar.gz",
            "has_sig": false,
            "md5_digest": "b8a47252474cb7ef867ff9512f464a93",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 43605,
            "upload_time": "2024-11-26T14:49:01",
            "upload_time_iso_8601": "2024-11-26T14:49:01.759674Z",
            "url": "https://files.pythonhosted.org/packages/d9/6e/83f825f6015e09b0ee248b5226f461deeaaf80f79748a6dd338271086df2/rod-0.3.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-26 14:49:01",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ami-iit",
    "github_project": "rod",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "rod"
}
        
Elapsed time: 0.39040s