ThrustLab

client.components

The catalog of motors, propellers, and batteries. You reference component ids in simulation and sweep bodies; create() adds your own private custom components. Custom components you submit through submissions appear here once approved.

Methods

MethodEndpointReturns
client.components.list(**filters)GET /v1/componentsCursorPager of components
client.components.find(**filters)GET /v1/componentsSingle component (one-hit-or-raise)
client.components.create(type=..., name=..., spec_json=...)POST /v1/componentsNew private component
client.components.retrieve(component_id)GET /v1/components/{id}Single component
client.components.brands()GET /v1/components/brandsList of {name, count} brand summaries

Filter by type

Every simulation needs at least one motor, one propeller, and one battery. The type filter is the fastest way to scope the catalog:

from thrustlab import Client
client = Client()

motors = list(client.components.list(type="motor", limit=100))
print(f"{len(motors)} motors in catalog")

Valid type values: motor, propeller, battery. Anything else — esc included, ThrustLab doesn't catalog ESCs — is rejected with a 422.

Filter by brand

brand is a discrete filter that takes the bracket [in] suffix, with a comma-separated list of names:

kde_or_tmotor = client.components.list(
    type="motor",
    **{"brand[in]": "KDE,T-Motor"},
)
for m in kde_or_tmotor:
    print(m["id"], m["name"], m["spec_json"].get("brand"))

The full list of brands, with per-brand counts, is available via client.components.brands():

brands = client.components.brands()
for b in brands["data"]:
    print(b["name"], b["count"])  # KDE 42, T-Motor 38, ...

Filter motors by Kv rating

Numeric spec fields take a bracket-suffixed filter — kv[gte] / kv[lte] (also [gt] / [lt], currently treated the same as the inclusive forms). Pass them through **extra_filters:

mid_kv = client.components.list(type="motor", **{"kv[gte]": 400, "kv[lte]": 900})
for m in mid_kv:
    print(m["id"], m["name"], m["spec_json"]["kv"])

Type-specific filters

Every other numeric spec filter follows the same key[gte] / key[lte] pattern and maps to a spec_json field server-side:

TypeFilter keyspec_json field
motorkv[gte] / kv[lte]kv
motorweight[gte] / weight[lte]weight
motorresistance[gte] / resistance[lte]R
motorcurrent_max[gte] / current_max[lte]iq_max
motorpoles[gte] / poles[lte]n
propellerdiameter[gte] / diameter[lte]diameter
propellerpitch[gte] / pitch[lte]pitch
propellerweight[gte] / weight[lte]weight
propellermax_rpm[gte] / max_rpm[lte]maxRPM
propellerinertia[gte] / inertia[lte]inertia
batteryseries_cells[gte] / series_cells[lte]series_cells
batterycapacity[gte] / capacity[lte]total_capacity_mAh
batteryc_rating[gte] / c_rating[lte]c_rating
batteryweight[gte] / weight[lte]weight_g

An unrecognized filter key — a typo, or a key that doesn't apply to the given type — is silently dropped rather than erroring, so a filter that returns everything usually means the key doesn't match this table.

# 14-16 inch propellers with at least 8 inch pitch
props = client.components.list(
    type="propeller",
    **{"diameter[gte]": 14, "diameter[lte]": 16, "pitch[gte]": 8},
)

Other list filters

FilterTypeNotes
visibility"public" | "private"Restrict to the shared catalog or your own private customs. Omit for both.
search (or q)strCase-insensitive substring match on name. If both are supplied, search wins.
sort_bystrname, created_at, or (with type set) a type-specific spec key.
sort_order"asc" | "desc"Default asc.
ids_onlyboolReturns every matching id in one bounded response (for "select all") instead of a cursor-paginated page.

See the API reference for the full list of per-type sort keys and spec filter keys.

Retrieve one component

motor = client.components.retrieve("comp_2c5tQ...")
print(motor["spec_json"])

The spec_json field carries every type-specific spec that the catalog has recorded — Kv, internal resistance, mass, etc. for motors; chord and twist for propellers; cell count and chemistry for batteries.

Create your own

create() persists a private custom component and returns its id:

prop = client.components.create(
    type="propeller",
    name="My Custom 10.5x4.5",
    spec_json={...},
)

The per-type required spec_json fields, units, and validation rules are in Creating your own components.

Recipe: pick the highest-thrust prop for a given motor

motor_id = "comp_2c5tQ..."

# Find every prop, then pick by trying them and reading thrust.
results = []
for prop in client.components.list(type="propeller", limit=50):
    sim = client.simulations.create(
        project_id="proj_xxx",
        battery_component_id="comp_xxx",
        airspeed_m_s=0.0, density_kg_m3=1.225, battery_charge_pct=100,
        rotor_groups=[{
            "label": "main", "count": 4,
            "motor_component_id": motor_id,
            "propeller_component_id": prop["id"],
            "throttle_pct": 100,
        }],
    )
    final = client.simulations.wait(sim["id"], timeout=120)
    if final["status"] == "completed":
        results.append((prop["name"], final["result"]["1"]["thrust_n"]))

results.sort(key=lambda r: -r[1])
for name, thrust in results[:5]:
    print(f"{name}: {thrust:.1f} N")

For larger searches, use sweeps to run all combinations in one request instead of N round-trips.

See also

We use cookies and analytics tools to understand how you use ThrustLab and improve the experience. Privacy Policy

Python SDK — Components · ThrustLab API