Skip to main content

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, and DracoPy (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 Email address for password-based authentication. 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.3.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_OCCLUSION_THRESHOLD_GAP_MM occlusion_threshold_gap_mm No 0.0 Gap threshold in millimeters for open-contact detection. 0.15
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, holes detection, and scan integrity (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 authenticates using email and password (passed as username and password parameters) and refreshes tokens automatically. The username parameter accepts your email address.

Error handling

Exceptions raised by the SDK:

  • ValidationError for invalid input or unexpected payload shapes
  • AuthenticationError, AuthorizationError, NotFoundError, RateLimitError
  • TasksNotCompletedError when required tasks are not complete for an operation
  • ApiError for other HTTP failures (includes status_code when available)
  • MovixQCError as 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

movix_qc_sdk-0.3.0.tar.gz (32.3 kB view details)

Uploaded Source

Built Distribution

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

movix_qc_sdk-0.3.0-py3-none-any.whl (23.4 kB view details)

Uploaded Python 3

File details

Details for the file movix_qc_sdk-0.3.0.tar.gz.

File metadata

  • Download URL: movix_qc_sdk-0.3.0.tar.gz
  • Upload date:
  • Size: 32.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for movix_qc_sdk-0.3.0.tar.gz
Algorithm Hash digest
SHA256 667109d393e849bfe49e8571808c21645c04cbff25654a2339d86baec2f7976f
MD5 542895efa68407ba2ff80ceb1ac02bc2
BLAKE2b-256 6b623173327c9d8fe4b731f5fce1c8144e84f805b60524394635e12c2e02c7f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for movix_qc_sdk-0.3.0.tar.gz:

Publisher: publish.yml on Movixtech-Workspace/movix-qc-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file movix_qc_sdk-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: movix_qc_sdk-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 23.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for movix_qc_sdk-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 10aa29f5db82feab3104fbbfc71be7b4de266901865d091af7ccf16dd7c61704
MD5 4d0c9f16bc1e41e6da265a109b269982
BLAKE2b-256 24cf609981f26b18c9c4eef78bd9fb4f8bdad18607ae0f944a534da27be0fe09

See more details on using hashes here.

Provenance

The following attestation bundles were made for movix_qc_sdk-0.3.0-py3-none-any.whl:

Publisher: publish.yml on Movixtech-Workspace/movix-qc-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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