Skip to content
Console

Python SDK

Use the Python SDK when your client or agent runs in Python.

The package name is thalovant.

Install with pip install thalovant.

Terminal window
pip install thalovant

This flow discovers a public hub, creates a client identity, and sends one request.

from thalovant import ThalovantClient, ThalovantControlPlane
api = ThalovantControlPlane()
public_hubs = api.list_public_hubs(limit=12)
for hub in public_hubs["data"]:
print(hub["id"], hub["slug"], hub["title"])
api.login("[email protected]", "password")
result = api.create_client_identity(
"hub-id",
name="python-demo-client",
preferred_protocols=("wss", "https", "mqtt"),
)
with ThalovantClient(result.identity, protocol="wss") as client:
reply = client.ask("Tell me a short clean joke.")
print(reply.text)

ThalovantControlPlane() uses https://api.thalovant.com by default.

Accounts with multi-factor authentication enabled must include a TOTP code or a one-time recovery code with the login. Without one, the API rejects the sign-in with HTTP 401 and code mfa_required. Both parameters are sent only when provided. MFA support needs SDK 0.4.21 or newer.

api.login("[email protected]", "password", otp_code="123456")
# Or use a one-time recovery code instead:
api.login("[email protected]", "password", recovery_code="abcd-efgh-ijkl")

Device login asks your browser to approve the sign-in, so scripts, CLIs, and agents never handle your password. The SDK prints a short code and the address https://dash.thalovant.com/activate, opens that page when it can, and waits while you approve the request in the dashboard with your normal sign-in, including Google sign-in or MFA. On approval the SDK holds a scoped, revocable API token and behaves exactly like after api.login(...).

Device login needs SDK 0.4.22 or newer. Approving the request needs a paid workspace plan; a free plan gets HTTP 402.

api.login_with_browser()
# Optional: narrow the scopes and label the token in the dashboard.
api.login_with_browser(scopes=["hubs:read", "clients:write"], client_name="my-cli")

Manage the resulting token on the dashboard’s API Tokens page.

Pass a stored API token when the process should start authenticated, such as CI jobs and services. Mint one on the API Tokens page or with login_with_browser; the page shows scopes, expiry, and last use, and can revoke the token at any time.

import os
from thalovant import ThalovantControlPlane
api = ThalovantControlPlane(access_token=os.environ["THALOVANT_API_TOKEN"])
# Ready immediately; no login call needed.

Use this when the identity was downloaded from Thalovant, stored in a secret volume, or saved in your protected SDK config.

from thalovant import ThalovantClient
with ThalovantClient.from_config(profile="prod", protocol="wss") as client:
reply = client.ask("What can this hub do?")
print(reply.text)
from thalovant import ThalovantClient
with ThalovantClient.from_identity_file("_identity.json") as client:
reply = client.ask("What can this hub do?")
print(reply.text)

Environment variables work too:

from thalovant import ThalovantClient
with ThalovantClient.from_env(protocol="https") as client:
print(client.ask("Say hello.").text)
identity = result.identity
print(identity.enabled_protocols())
print(identity.endpoint_for("wss"))
print(identity.endpoint_for("https"))
print(identity.endpoint_for("mqtt"))
for protocol in ("wss", "https", "mqtt"):
if not identity.supports_protocol(protocol):
continue
if protocol == "mqtt" and identity.mqtt is None:
continue
with ThalovantClient(identity, protocol=protocol) as client:
print(protocol, client.ask(f"Reply over {protocol}.").text)

MQTT requires the identity.mqtt broker credentials returned for that client.

For broker details, see MQTT.

Use a conversation when related turns should share one session.

with ThalovantClient.from_identity_file("_identity.json") as client:
with client.conversation(lang="en-us") as convo:
print(convo.ask("Remember that my favorite color is blue.").text)
print(convo.ask("What color did I mention?").text)
from thalovant import ThalovantClient, build_client_context
context = build_client_context(
user_id="user-42",
user_name="Ada",
source="checkout-kiosk",
platform="kiosk",
locale="en-US",
metadata={"trace_id": "req-2026-06-09-001"},
)
with ThalovantClient.from_identity_file("_identity.json") as client:
reply = client.ask("Show the next instruction.", context=context)
print(reply.text)
from thalovant import EVENT_SPEAK, ThalovantClient
with ThalovantClient.from_identity_file("_identity.json", protocol="wss") as client:
client.send_utterance("Say the current status.")
for event in client.listen(EVENT_SPEAK, timeout=10, max_events=1):
print(event.text)

ask

Send one request and receive a normalized reply.

listen

Wait for hub events with a timeout.

send_action

Send a button, menu, or tool action.

send_code

Send a QR value, serial number, barcode, or typed code.

For the full method list, see SDK Functions. Use api.get_operation(operation_id) to follow an accepted command; see Operations.

Since SDK 0.4.25 the control plane can create hubs, runtime groups, and skill installs. Browsing the catalog with api.list_marketplace_skills() needs hubs:read and works on any plan. create_hub, create_runtime_group, install_runtime_group_skill, release_hub, and release_runtime_group need hubs:write and a paid plan.

group = api.create_runtime_group({"name": "kiosks"})
hub = api.create_hub({"name": "joke-garden", "runtime_group_id": group["id"], "spec": {}})
hub = api.get_hub(hub["id"])
api.update_hub(hub["id"], {"active": False}, etag=hub["etag"])

update_hub and delete_hub require the hub’s current etag. See Provision Hubs for the full flow, the immutable fields, and the error table.

Symptom Check
Missing Thalovant API access token Call api.login(...) or api.login_with_browser() before private API actions, or pass access_token= to ThalovantControlPlane.
HTTP 401 with code mfa_required Pass otp_code or recovery_code to api.login(...).
API access requires a paid plan Upgrade the workspace before provisioning private resources through the API.
Unsupported protocol Enable that protocol on the hub and create a fresh identity.
MQTT fails immediately Confirm the identity has mqtt broker credentials.
  1. Start with WSS.
  2. Add HTTPS only for request-response clients.
  3. Add MQTT only when the client needs broker-mediated traffic.