Skip to main content

Python SDK for RoboInfra — URDF validation, kinematic analysis, 3D model conversion and mesh analysis APIs for ROS developers

Project description

roboinfra-sdk

Python SDK for RoboInfra Robotics API for URDF validation, kinematic analysis, 3D model conversion and mesh quality analysis.

PyPI version Python 3.8+

API: https://roboinfra-api.azurewebsites.net
Dashboard: https://roboinfra-dashboard.azurewebsites.net
PyPI: https://pypi.org/project/roboinfra-sdk/
GitHub Action: uses: roboinfra/validate-urdf-action@v1


Installation

pip install roboinfra-sdk

Quick Start

import roboinfra as roboinfra

# Create client with your API key from the dashboard
client = roboinfra.Client("rk_your_api_key_here")

# 1. Check API health (no auth needed)
status = client.health()
print(status["status"])          # "Healthy"

# 2. Validate a URDF file (Free plan)
result = client.urdf.validate("robot.urdf")
if result.is_valid:
    print("URDF is valid!")
else:
    for error in result.errors:
        print(f"  Error: {error}")

# 3. Kinematic analysis (Basic + Pro plan)
analysis = client.urdf.analyze("robot.urdf")
print(f"DOF: {analysis.dof}")
print(f"End effectors: {analysis.end_effectors}")

# 4. Convert 3D model (Pro plan)
output = client.model.convert("robot.obj", "fbx", "robot.fbx")
print(f"Saved: {output}")

# 5. Mesh quality analysis (Pro plan)
mesh = client.model.analyze("robot.stl")
print(f"Triangles: {mesh.total_triangles}")
print(f"Watertight: {mesh.is_watertight}")
if not mesh.is_watertight:
    print("WARNING: mesh has holes  will cause physics simulation issues!")

Get an API Key

  1. Register at roboinfra-dashboard.azurewebsites.net
  2. Go to API Keys → Create key
  3. Keys start with rk_
  4. Free plan: 50 calls/month for URDF validation no credit card required

API Reference

client.health() Public, no key needed

Check API connectivity and service status.

result = client.health()
# Returns dict:
# {
#   "status": "Healthy",
#   "version": "1.0.0",
#   "uptime": "2d 4h 12m"
# }

client.urdf.validate(file_path) All plans (Free/Basic/Pro)

Validates a URDF file against 9 structural checks.

result = client.urdf.validate("robot.urdf")

result.is_valid   # bool   True if all 9 checks pass
result.errors     # list   empty when valid, list of strings when invalid

9 checks performed:

  1. Root element must be <robot>
  2. At least one <link> must exist
  3. No duplicate link names
  4. No duplicate joint names
  5. All joint parent links must reference a defined link
  6. All joint child links must reference a defined link
  7. Joint type must be valid (revolute, continuous, prismatic, fixed, floating, planar)
  8. revolute and prismatic joints must include <limit>
  9. Exactly one root link (no cycles, no orphans)

Valid URDF example:

result = client.urdf.validate("robot.urdf")
# result.is_valid → True
# result.errors   → []

Invalid URDF example:

result = client.urdf.validate("bad_robot.urdf")
# result.is_valid → False
# result.errors   → [
#     "Root element must be <robot>",
#     "At least one <link> must exist"
# ]

client.urdf.analyze(file_path) Basic + Pro plan

Kinematic analysis DOF, joint chain, end effectors.

result = client.urdf.analyze("robot.urdf")

result.robot_name      # str    name from <robot name="...">
result.link_count      # int    total links
result.joint_count     # int    total joints
result.dof             # int    degrees of freedom (non-fixed joints)
result.max_chain_depth # int    longest kinematic chain
result.root_link       # str    root link name
result.end_effectors   # list   end effector link names
result.joints          # list   joint details

Example:

result = client.urdf.analyze("robot.urdf")
# result.robot_name      → "sample_arm"
# result.dof             → 2
# result.end_effectors   → ["tool0"]
# result.joints[0]       → {"name": "joint_1", "type": "revolute",
#                            "parent": "base_link", "child": "link_1"}

client.model.convert(file_path, target_format, output_path) Pro plan

Convert 3D model files between formats. No Blender required.

output = client.model.convert("robot.stl", "obj", "robot.obj")
# Returns absolute path to saved output file

# All supported conversions:
# .fbx  → obj, stl, glb, gltf
# .obj  → stl, glb, gltf, fbx
# .stl  → obj, glb, gltf
# .gltf → obj, stl, glb
# .glb  → obj, stl, gltf
# .dae  → obj, stl, glb
# .3ds  → obj, stl, glb
# .blend→ obj, stl, glb

Examples:

client.model.convert("robot.stl", "obj",  "robot.obj")
client.model.convert("robot.obj", "fbx",  "robot.fbx")
client.model.convert("robot.fbx", "glb",  "robot.glb")
client.model.convert("robot.obj", "gltf", "robot.gltf")

client.model.analyze(file_path) Pro plan

Mesh quality analysis for physics simulation readiness.

result = client.model.analyze("robot.stl")

result.mesh_count       # int    number of mesh objects
result.total_vertices   # int    total vertex count
result.total_triangles  # int    triangle count after triangulation
result.material_count   # int    number of materials
result.has_bones        # bool   True if skeletal data detected
result.is_watertight    # bool   True if ALL meshes are watertight (required for physics)
result.bounding_box     # dict   {"x": 0.42, "y": 0.38, "z": 0.75}
result.center_of_mass   # dict   {"x": 0.0, "y": 0.0, "z": 0.21}
result.meshes           # list   per-mesh breakdown

Example:

result = client.model.analyze("robot_arm.stl")
# result.total_triangles → 30240
# result.is_watertight   → True
# result.bounding_box    → {"x": 0.42, "y": 0.38, "z": 0.75}

if not result.is_watertight:
    print("WARNING: mesh has holes  robot will fall through ground in Gazebo!")

Error Handling

from roboinfra import (
    RoboInfraError,   # base  any API error
    AuthError,        # 401  invalid API key
    PlanError,        # 403  endpoint requires higher plan
    QuotaError,       # 429  monthly quota exceeded
)

try:
    result = client.urdf.validate("robot.urdf")
except AuthError:
    print("Invalid API key  get one at roboinfra-dashboard.azurewebsites.net/keys")
except PlanError:
    print("Upgrade your plan at roboinfra-dashboard.azurewebsites.net/subscription")
except QuotaError:
    print("Monthly quota exceeded  upgrade or wait until next month")
except RoboInfraError as e:
    print(f"API error: {e} (HTTP {e.status_code})")

Note: 400 errors (bad file, oversized file) also count against your monthly quota. The SDK validates file size and extension locally before any HTTP call to avoid wasting quota on obvious errors.


Plans and Limits

Plan Price Quota Features
Free $0/month 50 calls URDF validation only
Basic $25/month 500 calls URDF validation + kinematic analysis
Pro $75/month 5,000 calls All features (3D conversion + mesh analysis)

File Limits

Endpoint Max file size Allowed extensions
urdf.validate 1 MB .urdf
urdf.analyze 1 MB .urdf
model.convert 20 MB .fbx .obj .stl .gltf .glb .dae .3ds .blend
model.analyze 20 MB .fbx .obj .stl .gltf .glb .dae .3ds .blend

The SDK validates file size and extension locally before any HTTP call no wasted quota on obvious errors.


CI/CD Integration

Option 1 GitHub Action (simplest, recommended)

No Python required. Just add 3 lines to your workflow:

# .github/workflows/validate-urdf.yml
name: Validate URDF
on: [push, pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: roboinfra/validate-urdf-action@v1
        with:
          api-key: ${{ secrets.ROBOINFRA_API_KEY }}
          file: urdf/robot.urdf

Full docs: github.com/roboinfra/validate-urdf-action


Option 2 SDK inside a run step (more control)

Use this approach when you need custom logic multiple files, conditional checks, or integration with other tools:

- name: Validate URDF
  run: |
    pip install roboinfra-sdk
    python - <<'EOF'
    import roboinfra as roboinfra
    import sys
    client = roboinfra.Client("${{ secrets.ROBOINFRA_API_KEY }}")
    result = client.urdf.validate("urdf/robot.urdf")
    if not result.is_valid:
        print("URDF validation failed:")
        for e in result.errors:
            print(f"  - {e}")
        sys.exit(1)
    print("URDF valid!")
    EOF

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

roboinfra_sdk-1.0.7.tar.gz (18.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

roboinfra_sdk-1.0.7-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

Details for the file roboinfra_sdk-1.0.7.tar.gz.

File metadata

  • Download URL: roboinfra_sdk-1.0.7.tar.gz
  • Upload date:
  • Size: 18.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for roboinfra_sdk-1.0.7.tar.gz
Algorithm Hash digest
SHA256 b61defd7090a8ef0a3a08e7c61faaf27a2225f6e2acf5281ca259f7d4a8e986e
MD5 550753cceeeda637186ecd29ffdf65ce
BLAKE2b-256 8f00909698f61d4e548bbffef723c01dcdc4720890f10b13936fef6ec2ed8f46

See more details on using hashes here.

File details

Details for the file roboinfra_sdk-1.0.7-py3-none-any.whl.

File metadata

  • Download URL: roboinfra_sdk-1.0.7-py3-none-any.whl
  • Upload date:
  • Size: 14.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for roboinfra_sdk-1.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 bcd2b489e64a75c15d1038b32080cff48497949f911a7fb282eb97deed350bd0
MD5 1f69b9696356c290091f93381d3ba810
BLAKE2b-256 c6e6df4505f3ed1050c2f35c5983ca293e1f740850dfe57bbd9eba069cf5f8ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page