Python SDK for the Movix QC API
Project description
movix-qc-sdk
Production-ready Python SDK for the Movix QC API. It keeps the surface small, handles authentication safely, and focuses on the core QC workflow.
For a full API surface description, see overview.md.
Requirements
- Python 3.11+
- Validation requires
numpy,trimesh, andDracoPy(installed automatically).
Base URLs
The API is available in two environments. Use staging during integration and testing, and switch to production for go-live.
- Staging:
https://api-staging.movixtech.com - Production:
https://api.movixtech.com
Installation
python -m pip install -e .
Quick start
You can initialize the client in two ways.
Environment variables + Client():
export MOVIX_QC_API_URL="https://api-staging.movixtech.com"
export MOVIX_QC_USERNAME="user@example.com"
export MOVIX_QC_PASSWORD="..."
Explicit arguments:
from movix_qc_sdk import Client
client = Client(
api_url="https://api-staging.movixtech.com",
username="user@example.com",
password="...",
timeout=45,
retries=10,
user_agent="Movix/1.2 (+example@movixtech.com)",
)
If you use Client() or with Client() as client: without arguments, make
sure the environment variables are set first.
Full example (submit, then poll for completion). submit() creates the default
validation task for the case:
from movix_qc_sdk import Client
with Client() as client:
case = client.cases.submit(
paths=["/path/to/upper.stl", "/path/to/lower.stl"],
metadata={"note": "Demo", "client": "ACME-001"},
)
tasks = client.tasks.list(case_id=case.case_id)
if tasks:
task = client.tasks.wait(task_id=tasks[0].task_id, case_id=case.case_id)
print(task.status)
Upload from public URLs (two files):
from movix_qc_sdk import Client
with Client() as client:
case = client.cases.submit_urls(
urls=[
"https://files.example.com/upper.stl",
"https://files.example.com/lower.stl",
],
metadata={"note": "Demo", "client": "ACME-001"},
)
Generate result summary
After all validation tasks complete, generate a narrative summary ready to share with stakeholders:
from movix_qc_sdk import Client, TasksNotCompletedError
with Client() as client:
# Wait for tasks to complete first
tasks = client.tasks.list(case_id=case.case_id)
for task in tasks:
client.tasks.wait(task_id=task.task_id, case_id=case.case_id)
# Generate summary (uses user's language by default)
summary = client.cases.generate_summary(case_id=case.case_id)
if summary.message:
print("Issues found:")
print(summary.message)
else:
print("No issues detected")
# Or generate summary in a specific language
summary_es = client.cases.generate_summary(
case_id=case.case_id,
language_code="es"
)
Generate viewer link
After Occlusal Evaluation and IQC Holes Detection tasks complete, generate a secure link to share visualization results:
from movix_qc_sdk import Client, TasksNotCompletedError
with Client() as client:
try:
link = client.cases.generate_viewer_link(case_id=case.case_id)
print(f"Viewer URL: {link.url}")
print(f"Expires at: {link.expires_at}")
# Share link.url with stakeholders
# The link is valid for 24 hours by default
except TasksNotCompletedError:
print("Required tasks (Occlusal Evaluation and IQC Holes Detection) not complete yet")
The viewer link endpoint is idempotent—if a valid link already exists, it returns that link. Only one link per case can be active at a time.
Configuration
All settings can be passed to Client(...) or set via environment variables.
Environment variables
| Variable | Client arg | Required | Default | Description | Example |
|---|---|---|---|---|---|
MOVIX_QC_API_URL |
api_url |
Yes | None | Base URL of the Movix QC API. Use https://api-staging.movixtech.com for staging or https://api.movixtech.com for production. The SDK strips a trailing slash. |
https://api-staging.movixtech.com |
MOVIX_QC_USERNAME |
username |
Yes | None | Login username (typically an email) for password-based auth. | user@example.com |
MOVIX_QC_PASSWORD |
password |
Yes | None | Login password for password-based auth. | s3cr3t |
MOVIX_QC_TIMEOUT |
timeout |
No | 45 |
Per-request timeout in seconds. Must be greater than zero. | 30 |
MOVIX_QC_RETRIES |
retries |
No | 10 |
Number of retries for transient errors (network errors, 429, 5xx). Must be zero or greater. | 2 |
MOVIX_QC_USER_AGENT |
user_agent |
No | movix-qc-sdk/0.2.0 |
Custom user-agent string. Recommended format: <Company>/<AppVersion> (+contact) for traceability. |
Movix/1.2 (+example@movixtech.com) |
MOVIX_QC_OCCLUSION_THRESHOLD_MM |
occlusion_threshold_mm |
No | 0.0 |
Occlusion threshold in millimeters. Set based on quality requirements. | 0.2 |
MOVIX_QC_HOLES_THRESHOLD_AREA_MM |
holes_threshold_area_mm |
No | 0.0 |
Holes threshold in mm². Set based on quality requirements. | 10.0 |
Complete Examples
See the examples/ directory for a full workflow demonstration:
-
examples/main.py - Complete QC workflow showing:
- Case creation with STL file upload
- Data validation (synchronous)
- Parallel occlusion and holes detection (asynchronous)
- Summary and viewer link generation
- Proper error handling and result interpretation
-
examples/README.md - Setup instructions and configuration guide
The example demonstrates enterprise-ready code with proper threshold configuration, error handling, and result interpretation.
Authentication
The SDK logs in with username and password and refreshes tokens automatically.
Error handling
Exceptions raised by the SDK:
ValidationErrorfor invalid input or unexpected payload shapesAuthenticationError,AuthorizationError,NotFoundError,RateLimitErrorTasksNotCompletedErrorwhen required tasks are not complete for an operationApiErrorfor other HTTP failures (includesstatus_codewhen available)MovixQCErroras the base class
Security notes
- The SDK never logs tokens or passwords.
- Authorization headers and cookies are redacted if logging is enabled.
- Tokens are stored in memory by default and refreshed automatically.
- Credentials (username, password) and tokens are stored in plaintext in memory during the session. In high-security environments, ensure proper process isolation and avoid core dumps.
- URL uploads are capped at 256 MB per file; clients must validate/approve URLs.
- Presigned URLs are validated against an allowed list of storage domains to prevent unauthorized upload destinations.
SSRF Protection
When using submit_urls() or upload_urls() on a server that accepts URLs from untrusted users, you are responsible for validating those URLs to prevent SSRF (Server-Side Request Forgery) attacks.
Example of safe usage:
from urllib.parse import urlparse
ALLOWED_DOMAINS = {"your-storage.com", "trusted-cdn.com"}
def validate_user_urls(urls: list[str]) -> None:
"""Validate URLs from untrusted users before passing to SDK."""
for url in urls:
parsed = urlparse(url)
if parsed.netloc not in ALLOWED_DOMAINS:
raise ValueError(f"Domain not allowed: {parsed.netloc}")
# In your API endpoint:
@app.post("/upload")
def upload(urls: list[str]):
validate_user_urls(urls) # Validate BEFORE passing to SDK
client.cases.submit_urls(urls=urls)
Risk: If you pass untrusted URLs directly to the SDK without validation, attackers may access your internal services (localhost, private networks, cloud metadata endpoints).
Async task results
Tasks are typically polled until they complete. The SDK provides a wait()
helper to do this safely. Confirm with the Movix team before choosing the
long-term approach. Options to consider:
- Polling (simple, current default)
- Webhooks/callbacks (preferred if available)
- Long-polling or server-sent events (only if supported)
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file movix_qc_sdk-0.2.0.tar.gz.
File metadata
- Download URL: movix_qc_sdk-0.2.0.tar.gz
- Upload date:
- Size: 30.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96c24f719bf2b6db744cc4e961f7e64e31af32808e8bdc5c7f3e2bffbfe8394d
|
|
| MD5 |
39f087f3ad0ce3c24d804f99e0ec6e5e
|
|
| BLAKE2b-256 |
2f6bfb4191049044022a7992f1c88f458438609d89ff9f6025bc7507a0665937
|
Provenance
The following attestation bundles were made for movix_qc_sdk-0.2.0.tar.gz:
Publisher:
publish.yml on Movixtech-Workspace/movix-qc-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
movix_qc_sdk-0.2.0.tar.gz -
Subject digest:
96c24f719bf2b6db744cc4e961f7e64e31af32808e8bdc5c7f3e2bffbfe8394d - Sigstore transparency entry: 869261542
- Sigstore integration time:
-
Permalink:
Movixtech-Workspace/movix-qc-sdk@9fc46556aae9d22326802ca37e5aa151f0d55f12 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Movixtech-Workspace
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9fc46556aae9d22326802ca37e5aa151f0d55f12 -
Trigger Event:
release
-
Statement type:
File details
Details for the file movix_qc_sdk-0.2.0-py3-none-any.whl.
File metadata
- Download URL: movix_qc_sdk-0.2.0-py3-none-any.whl
- Upload date:
- Size: 22.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a6270b75cccd536cdcf3133fb2d6271bc4623b3d90f82e92efcca309c33947d
|
|
| MD5 |
fa539ce88f51c0e5b87746a44ca3911d
|
|
| BLAKE2b-256 |
0c84297550e23be78dae026866a33ea73d24f66041fedca3071c776d50268365
|
Provenance
The following attestation bundles were made for movix_qc_sdk-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on Movixtech-Workspace/movix-qc-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
movix_qc_sdk-0.2.0-py3-none-any.whl -
Subject digest:
8a6270b75cccd536cdcf3133fb2d6271bc4623b3d90f82e92efcca309c33947d - Sigstore transparency entry: 869261550
- Sigstore integration time:
-
Permalink:
Movixtech-Workspace/movix-qc-sdk@9fc46556aae9d22326802ca37e5aa151f0d55f12 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Movixtech-Workspace
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9fc46556aae9d22326802ca37e5aa151f0d55f12 -
Trigger Event:
release
-
Statement type: