Complete reference for the MyoSapiens Python SDK (myosdk).
Experimental Notice: The MyoSapiens SDKs are currently experimental and subject to change. Breaking changes may occur without prior notice as we iterate on the platform.
Main client class for interacting with the MyoSapiens API.
from myosdk import Client
client = Client(
api_key="your_api_key_here",
base_url="https://api.myolab.ai", # optional
timeout=30.0 # optional
)
api_key (str, required) - Your API key from dev.myolab.aibase_url (str, optional) - Base URL of the API (default: https://api.myolab.ai)timeout (float, optional) - Request timeout in seconds (default: 30.0)assets - Access the assets resourcejobs - Access the jobs resourceclose() - Close the HTTP client and release resourcesThe client can be used as a context manager to automatically close connections:
with Client(api_key="your_api_key") as client:
# Use client here
assets = client.assets.list()
# Client is automatically closed
Manage file uploads and downloads.
Upload a file in one step (convenience method).
asset = client.assets.upload_file(
file_path="path/to/file.c3d",
purpose="retarget", # optional, auto-detected if not provided
metadata={"description": "My motion capture file"} # optional
)
file_path (str | Path, required) - Path to the file to uploadpurpose (str, optional) - Asset purpose. Auto-detected from file extension if not provided. See File Formats for supported purposes and file types.metadata (dict, optional) - Optional metadata dictionaryDict with completed asset details:
{
"asset_id": "uuid",
"verified": True,
"size_bytes": 1024000,
"checksum_sha256": "..."
}
# Upload a C3D file
c3d_asset = client.assets.upload_file("motion.c3d")
print(f"Uploaded asset ID: {c3d_asset['asset_id']}")
# Upload with explicit purpose (usually auto-detected)
c3d_asset = client.assets.upload_file(
"motion.c3d",
purpose="retarget",
metadata={"source": "mocap_session"}
)
Get asset details.
asset = client.assets.get(asset_id)
asset_id (str, required) - Asset identifierDict with asset details including download_url:
{
"asset_id": "uuid",
"purpose": "retarget",
"filename": "motion.c3d",
"size_bytes": 1024000,
"status": "completed",
"download_url": "https://...",
"created_at": "2024-01-01T00:00:00Z"
}
Download an asset to a local file.
client.assets.download(asset_id, "output.npz")
# or
client.assets.download(asset_dict, "output.npz")
asset (str | dict, required) - Asset identifier (string) or asset dict from get()destination (str | Path, required) - Destination file path# Download by asset ID
client.assets.download(asset_id, "output.npz")
# Download from asset dict
asset = client.assets.get(asset_id)
client.assets.download(asset, "output.npz")
List assets with optional filtering.
result = client.assets.list(
purpose="retarget", # optional
reference_count=0, # optional
limit=50, # optional, default: 50
offset=0 # optional, default: 0
)
purpose (str, optional) - Filter by purpose. See File Formats for supported purposes.reference_count (int, optional) - Filter by reference count (e.g., 0 for unused assets)limit (int, optional) - Items per page (default: 50)offset (int, optional) - Items to skip (default: 0)Dict with assets list and pagination info:
{
"assets": [...],
"total": 100,
"limit": 50,
"offset": 0
}
Delete an asset.
client.assets.delete(asset_id)
asset_id (str, required) - Asset identifierValidationError - If asset has active references or cannot be deletedManage retargeting jobs.
Start a retarget job.
job = client.jobs.start_retarget(
c3d_asset_id="uuid", # or c3d_s3="s3://..."
markerset_asset_id="uuid", # or markerset_s3="s3://..."
character_id="uuid", # optional, default provided
character_version="v1.0.0", # optional, default: "v1.0.0"
enable_scaling=True, # optional, default: True
subject_gender="male", # optional, default: "male"
subject_height=1.75, # optional
subject_weight=70.0, # optional
metadata={"description": "..."} # optional
)
c3d_asset_id (str, optional) - Asset ID of the C3D motion capture file (either this or c3d_s3 required)c3d_s3 (str, optional) - Direct S3 key of the C3D file (either this or c3d_asset_id required)markerset_asset_id (str, optional) - Asset ID of the markerset XML file (either this or markerset_s3 required)markerset_s3 (str, optional) - Direct S3 key of the markerset XML file (either this or markerset_asset_id required)character_id (str, optional) - Character identifier (default: "0199e278-06e6-7726-a6ba-9929f79005e8")character_version (str, optional) - Character version (default: "v1.0.0")enable_scaling (bool, optional) - Whether to enable body scaling during retargeting (default: True)subject_gender (str, optional) - Subject gender for anthropometric scaling: "male" or "female" (default: "male")subject_height (float, optional) - Subject height in meters for anthropometric scalingsubject_weight (float, optional) - Subject weight in kilograms for anthropometric scalingmetadata (dict, optional) - Optional metadata dictionaryDict with job information:
{
"job_id": "uuid",
"type": "retarget",
"status": "QUEUED",
"message": "Retarget job created successfully",
"estimated_wait_time_seconds": 10
}
# Start retarget job with asset IDs
job = client.jobs.start_retarget(
c3d_asset_id=c3d_asset["asset_id"],
markerset_asset_id=markerset_asset["asset_id"],
character_id="0199e278-06e6-7726-a6ba-9929f79005e8",
character_version="v1.0.0",
enable_scaling=True,
subject_gender="male",
subject_height=1.75,
subject_weight=70.0
)
Get job status.
job = client.jobs.get(job_id)
job_id (str, required) - Job identifierDict with job status and results:
{
"job_id": "uuid",
"type": "retarget",
"status": "SUCCEEDED",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:05:00Z",
"started_at": "2024-01-01T00:01:00Z",
"completed_at": "2024-01-01T00:05:00Z",
"message": "Job completed successfully",
"output": {
"retarget_output_asset_id": "uuid"
},
"download_urls": {
"retarget_output": "https://..."
}
}
Wait for a job to complete.
result = client.jobs.wait(
job_id,
interval=2.0, # optional, polling interval in seconds
timeout=None # optional, maximum time to wait in seconds
)
job_id (str, required) - Job identifierinterval (float, optional) - Polling interval in seconds (default: 2.0)timeout (float, optional) - Maximum time to wait in seconds (None = no timeout)Final job status dict (same format as get()).
TimeoutError - If timeout is exceeded# Wait for job to complete (no timeout)
result = client.jobs.wait(job["job_id"])
# Wait with timeout (5 minutes)
result = client.jobs.wait(job["job_id"], timeout=300)
# Custom polling interval (check every 5 seconds)
result = client.jobs.wait(job["job_id"], interval=5.0)
Cancel a job.
result = client.jobs.cancel(job_id)
job_id (str, required) - Job identifierDict with cancellation confirmation:
{
"job_id": "uuid",
"status": "CANCELED",
"message": "Job canceled successfully"
}
List jobs with optional filtering.
result = client.jobs.list(
status="SUCCEEDED", # or ["SUCCEEDED", "FAILED"]
job_type="retarget",
created_after=datetime(2024, 1, 1), # optional
created_before=datetime(2024, 12, 31), # optional
run_id="uuid", # optional
has_output=True, # optional
input_asset_id="uuid", # optional
limit=50, # optional, default: 50
offset=0 # optional, default: 0
)
status (str | liststr, optional) - Filter by status: "QUEUED", "RUNNING", "SUCCEEDED", "FAILED", "CANCELED" (or list of statuses)job_type (str | liststr, optional) - Filter by job type: "retarget"created_after (datetime | str, optional) - ISO 8601 timestamp or datetime for lower boundcreated_before (datetime | str, optional) - ISO 8601 timestamp or datetime for upper boundrun_id (str, optional) - Filter by run identifierhas_output (bool, optional) - Filter jobs that have (or do not have) output assetsinput_asset_id (str, optional) - Filter jobs that used a given input assetlimit (int, optional) - Items per page (default: 50)offset (int, optional) - Items to skip (default: 0)Dict with jobs list and pagination info:
{
"jobs": [...],
"total": 100,
"limit": 50,
"offset": 0
}
from datetime import datetime, timedelta
# List all succeeded retarget jobs from the last week
week_ago = datetime.now() - timedelta(days=7)
result = client.jobs.list(
status="SUCCEEDED",
job_type="retarget",
created_after=week_ago
)
# List jobs with multiple statuses
result = client.jobs.list(
status=["SUCCEEDED", "FAILED"],
limit=100
)