Complete reference for the MyoSapiens Python SDK (myosdk).
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
)