Skip to main content

Official Python SDK for the ThrustLab API

Project description

thrustlab — official Python SDK for the ThrustLab API

PyPI Python License

Install

pip install thrustlab

Requires Python 3.10+.

Quickstart

from thrustlab import Client

client = Client()  # reads $THRUSTLAB_API_KEY (never hard-code the key)

# Create a project
project = client.projects.create(name="my project")

# Run a single-point simulation and wait for the result.
# A rotor group carries the motor + propeller + throttle (0–100); the battery
# and flight condition are top-level. Resolve component IDs from the catalog
# (client.components.find(name=...)) or paste them directly.
sim = client.simulations.create(
    project_id=project["id"],
    battery_component_id="comp_batt_xxx",
    airspeed_m_s=0.0,
    density_kg_m3=1.225,
    battery_charge_pct=100,
    rotor_groups=[
        {
            "label": "main",
            "count": 4,
            "motor_component_id": "comp_motor_xxx",
            "propeller_component_id": "comp_prop_xxx",
            "throttle_pct": 70,
        }
    ],
)
result = client.simulations.wait(sim["id"], timeout=300)

# Canonical snake_case result: per-rotor group under "1"/"2"/…, roll-ups
# under "All" (a sibling `display_labels` map carries the human labels).
print(result["result"]["1"]["thrust_n"], result["result"]["All"]["total_thrust_n"])

Runnable end-to-end examples for every simulation type live in examples/: simulations/run_sync.py, sweeps/run_and_poll.py, and dynamic/run_and_poll.py.

Why the SDK (and not urllib / wget)?

Use this SDK — or, if you hand-roll a client, an HTTP library that is not stdlib urllib. Requests from Python's urllib.request (and wget) are blocked at the Cloudflare edge by a managed WAF rule matching the literal Python-urllib/* User-Agent. The block is terminated at the edge: the request never reaches the ThrustLab API, so you get an opaque HTML error 1010 challenge page — not a JSON error envelope. The API cannot return a structured error for a request it never sees.

This SDK is built on httpx and sends its own thrustlab-python/<version> User-Agent, so it is unaffected. If you must hand-roll a client, set an explicit non-urllib User-Agent header (e.g. requests, httpx, or curl) and you will reach the API normally.

Configuration

Setting Constructor arg Env var Default
API key api_key= THRUSTLAB_API_KEY (required)
Base URL base_url= THRUSTLAB_BASE_URL https://thrustlab.com
Timeout timeout= 30 (seconds)
Max retries max_retries= 3

Resources

Every /v1/ route family is exposed as an attribute on the client:

client.users
client.projects
client.simulations
client.sweeps
client.dynamic_simulations
client.components
client.submissions
client.starred_components
client.compute_units
client.webhook_endpoints

Error handling

from thrustlab import Client
from thrustlab.exceptions import (
    AuthenticationError,
    ValidationError,
    RateLimitError,
    NotFoundError,
)

client = Client()
try:
    client.simulations.create(project_id="proj_xxx", rotor_groups=[...], ...)
except ValidationError as exc:
    print(f"bad request: {exc.code} ({exc.param}): {exc.message}")
except RateLimitError as exc:
    print(f"rate limited; retry after {exc.retry_after}s")
except NotFoundError as exc:
    print(f"not found: {exc.message}")
except AuthenticationError as exc:
    print(f"auth failed: {exc.message}")

Every error carries .code, .type, .request_id, .http_status, and .message. ValidationError additionally exposes .param. See thrustlab.com/docs/guides/errors for the full code reference.

Pagination

List endpoints return a CursorPager — a lazy iterator that fetches the next page only when needed:

# Iterate all pages automatically
for project in client.projects.list():
    print(project["id"])

# Materialise the first page only
first_page = list(client.projects.list(limit=20))

Async polling

simulations.wait(), sweeps.wait(), and dynamic_simulations.wait() block until the resource reaches a terminal state (completed, failed, or canceled — one 'l' on the wire) or the timeout fires. On timeout the returned dict carries the SDK-side sentinel status="timed_out" (never a server state):

sweep = client.sweeps.create(...)
result = client.sweeps.wait(sweep["id"], timeout=600, poll_interval=2.0)
if result["status"] == "completed":
    for point in client.sweeps.list_points(sweep["id"]):
        print(point["rotors"]["1"]["thrust_n"])

Webhooks

from thrustlab import Webhook
from thrustlab.exceptions import SignatureVerificationError

WEBHOOK_SECRET = "whsec_..."

@app.post("/webhooks/thrustlab")
async def handle(request):
    payload = await request.body()
    sig    = request.headers["Thrustlab-Signature"]
    try:
        event = Webhook.verify(payload, sig, WEBHOOK_SECRET)
    except SignatureVerificationError:
        return Response(status_code=400)
    if event.type == "simulation.succeeded":
        print(event.data)

Retries

The client automatically retries on 429 (rate limit) and 5xx responses using exponential backoff with jitter. Set max_retries=0 to disable:

client = Client(max_retries=0)

Links

License

Apache-2.0. See LICENSE and NOTICE.

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

thrustlab-0.3.1.tar.gz (110.5 kB view details)

Uploaded Source

Built Distribution

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

thrustlab-0.3.1-py3-none-any.whl (198.1 kB view details)

Uploaded Python 3

File details

Details for the file thrustlab-0.3.1.tar.gz.

File metadata

  • Download URL: thrustlab-0.3.1.tar.gz
  • Upload date:
  • Size: 110.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for thrustlab-0.3.1.tar.gz
Algorithm Hash digest
SHA256 057072b84ca639bec608d047ddc34d82c90e090ecd27c463f7a7a249509f88ba
MD5 631c17c2d3d3b6d47e6c4ee95b7d1035
BLAKE2b-256 a78ba21526a388232aeb8dce1b81107ab8239da9c393d68a58e0a838046bb556

See more details on using hashes here.

File details

Details for the file thrustlab-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: thrustlab-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 198.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for thrustlab-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 91e1657b32bc7b12c75943d6e7ac28cc2a1fc0f41e96ce6d8ad9800b758799b9
MD5 bd1209e8b571e3c3dc85b46e5ca07e98
BLAKE2b-256 cda249dea1664b62ea98dc85eb28e202b31e6852d47a664d05a112ff9c519cee

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