Python SDK and CLI for direct Thalovant hub data-plane clients and agents
Project description
Thalovant Python SDK
The Thalovant Python SDK is the developer layer for direct Thalovant hub access. Thalovant provisions client identities and policy; this SDK connects directly to the hub endpoint over the enabled data-plane protocol.
Thalovant API / dashboard -> provision identity, policy, and endpoints
Python SDK / CLI -> direct hub data-plane connection
Hub runtime -> skills, events, and replies
Full documentation: docs.thalovant.com/developers/sdks/python
Install
pip install thalovant
For local SDK development:
pip install -e ".[dev]"
Quick Start
Download or copy the client identity created in Thalovant, then:
from thalovant import ThalovantClient
with ThalovantClient.from_identity_file("_identity.json") as client:
reply = client.ask("Tell me a short clean joke.")
print(reply.text)
For async apps and agent runtimes:
import asyncio
from thalovant import AsyncThalovantClient
async def main():
async with AsyncThalovantClient.from_identity_file("_identity.json") as client:
reply = await client.ask("What time is it?")
print(reply.text)
asyncio.run(main())
Identity
The identity file uses the same fields produced for Thalovant hub clients:
{
"access_key": "client-access-key",
"password": "client-password",
"crypto_key": "optional-preshared-key",
"site_id": "my-client-site",
"default_master": "https://hub.example.com",
"default_port": 443,
"default_path": "/public",
"data_plane_endpoints": {
"https": "https://hub.example.com/public",
"wss": "wss://hub.example.com/public",
"mqtt": "mqtts://mqtt.example.com:8883"
},
"protocols": {
"wss": {"enabled": true},
"http": {"enabled": true},
"mqtt": {"enabled": false}
},
"mqtt": {
"endpoint": "mqtts://mqtt.example.com:8883",
"username": "client-access-key",
"password": "client-broker-password",
"topic_prefix": "hivemind/hub/client-access-key",
"tls": true
}
}
```
Environment variables are also supported:
```bash
export THALOVANT_ACCESS_KEY=...
export THALOVANT_PASSWORD=...
export THALOVANT_CRYPTO_KEY=...
export THALOVANT_SITE_ID=...
export THALOVANT_HUB_HTTP_HOST=https://hub.example.com
export THALOVANT_HUB_WSS_HOST=wss://hub.example.com
export THALOVANT_HUB_MQTT_HOST=mqtts://mqtt.example.com:8883
export THALOVANT_MQTT_USERNAME=...
export THALOVANT_MQTT_PASSWORD=...
export THALOVANT_MQTT_TOPIC_PREFIX=hivemind/hub/client
export THALOVANT_HUB_HTTP_PORT=443
export THALOVANT_HUB_HTTP_PATH=/public
from thalovant import ThalovantClient
with ThalovantClient.from_env() as client:
print(client.ask("Tell me a joke").text)
Keep identity files secret. They are client credentials, not public API keys.
You can also provision a client identity through the Thalovant API:
from thalovant import ThalovantControlPlane
api = ThalovantControlPlane("https://dash.thalovant.com/api")
api.login("you@example.com", "password")
result = api.create_client_identity("hub-id", name="kiosk-1")
with ThalovantClient(result.identity) as client:
print(client.ask("Say hello").text)
The SDK generates apiKey, password, and cryptoKey locally and sends them
to the API once. The API can store them in Vault and return only secret
references. When MQTT is enabled for the hub, the API also returns a per-client
broker password and ACL-scoped topic prefix on result.identity.mqtt.
result.identity is the usable local client identity. Do not log
result.identity.as_dict(include_secrets=True).
Protocols
The SDK understands the same protocol shape returned by the Thalovant API:
protocols.wss.enabledcontrols the public WebSocket path.protocols.http.enabledexposes the HTTP protocol as HTTPS at the edge.protocols.mqtt.enabledexposes MQTT over TLS when enabled for the hub.
from thalovant import ThalovantIdentity
identity = ThalovantIdentity.from_file("_identity.json")
print(identity.enabled_protocols())
print(identity.endpoint_for("https"))
print(identity.endpoint_for("wss"))
print(identity.endpoint_for("mqtt"))
The Python runtime supports HTTPS, WSS, and MQTT:
client = ThalovantClient(identity, protocol="wss")
client = ThalovantClient(identity, protocol="mqtt")
MQTT requires the per-client broker credentials returned on identity.mqtt.
Conversations
Use a conversation when multiple messages should share a stable session and correlation context:
from thalovant import ThalovantClient
with ThalovantClient.from_identity_file("_identity.json") as client:
with client.conversation(lang="en-us") as convo:
first = convo.ask("Remember that my favorite color is blue.")
second = convo.ask("What color did I mention?")
print(second.text)
Conversation helpers add session and request metadata automatically. When the hub echoes that metadata, SDK listeners filter unrelated events from other sessions.
Client Context
Use build_client_context when a web, mobile, kiosk, or service client needs
to pass user, device, channel, and platform metadata to skills:
from thalovant import ThalovantClient, build_client_context
context = build_client_context(
user_id="user-42",
user_name="Ada",
auth_provider="oidc",
roles=["member"],
platform="kiosk",
source="checkout-kiosk",
channel="chat",
)
with ThalovantClient.from_identity_file("_identity.json") as client:
reply = client.ask("Show the next instruction.", context=context)
Provider-specific fields can still be passed through context or metadata.
The SDK keeps the public helper generic.
Actions And Exact Inputs
Use send_action for button/quick-reply payloads, and send_code for exact
values such as QR codes, serial numbers, asset IDs, or scanned labels:
with client.conversation(session_id="work-session") as convo:
convo.send_action('/choose{"id":"42"}', title="Choose item")
convo.send_code("SN-001-XYZ", kind="qr", label="serial")
Both helpers still emit normal recognizer_loop:utterance events, but add
generic input metadata so downstream skills can distinguish typed/scanned
values from speech transcription.
Rich Responses
Assistant responses can include text, choices, images, attachments, and tables.
Use reply.display_items() or event.display_items() to render a UI without
hand-parsing common rich media payloads:
reply = client.ask("Show matching parts.")
for item in reply.display_items(max_text_chars=600):
if item.kind == "text":
print(item.text)
elif item.kind == "choices":
print([choice["title"] for choice in item.data])
Agents
Use ThalovantAgent for long-running synchronous workers:
from thalovant import ThalovantAgent, EVENT_SPEAK
agent = ThalovantAgent.from_identity_file("_identity.json")
@agent.on(EVENT_SPEAK)
def handle_speak(event):
print(event.text)
agent.run_forever()
Async agents work the same way:
import asyncio
from thalovant import AsyncThalovantAgent, EVENT_SPEAK
agent = AsyncThalovantAgent.from_identity_file("_identity.json")
@agent.on(EVENT_SPEAK)
async def handle_speak(event):
print(event.text)
asyncio.run(agent.run_forever())
CLI
The package installs a thalovant command for smoke tests and operational
debugging:
thalovant --identity _identity.json doctor
thalovant --identity _identity.json health
thalovant --identity _identity.json ask "Tell me a joke"
thalovant --identity _identity.json listen speak --timeout 30 --max-events 3
thalovant --identity _identity.json emit recognizer_loop:utterance \
--data '{"utterances":["hello"],"lang":"en-us"}'
Add --json to commands that return structured output.
Events
For common flows, prefer helpers over raw event strings:
from thalovant import EVENT_SPEAK, ThalovantClient
with ThalovantClient.from_identity_file("_identity.json") as client:
for event in client.listen(EVENT_SPEAK, timeout=30, max_events=1):
print(event.text)
Use emit when you already know the hub event shape:
from thalovant import EVENT_RECOGNIZER_LOOP_UTTERANCE, ThalovantClient
with ThalovantClient.from_identity_file("_identity.json") as client:
client.emit(
EVENT_RECOGNIZER_LOOP_UTTERANCE,
{"utterances": ["turn on the lights"], "lang": "en-us"},
)
ThalovantEvent normalizes common fields:
event.textevent.utterancesevent.session_idevent.request_idevent.is_failureevent.is_policy_denied
Diagnostics
Use doctor() before debugging application code:
with ThalovantClient.from_identity_file("_identity.json") as client:
report = client.doctor()
print(report.format())
The report checks identity shape, endpoint configuration, hub connection, handshake completion, and the live HTTP polling thread.
Documentation
The canonical public documentation lives on the Thalovant docs site:
This repository also keeps generated API reference material for maintainers:
- Local preview:
pip install -e ".[docs]" && mkdocs serve - Build check:
mkdocs build --strict
Notes
- This SDK is the developer convenience layer. It does not proxy messages through the Thalovant API.
- The Thalovant API remains the control plane for creating clients, rotating or revoking identity material, and managing ACL/policy.
- The data plane is direct hub protocol traffic from this SDK to the hub listener. The SDK supports HTTPS, WSS, and MQTT runtime transports.
Publishing
This repository is configured for PyPI trusted publishing through
.github/workflows/publish.yml. Use these values in the PyPI publisher form:
- PyPI Project Name:
thalovant - Owner:
thalovant - Repository name:
thalovant-python-sdk - Workflow name:
publish.yml - Environment name:
pypi
Project details
Release history Release notifications | RSS feed
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 thalovant-0.4.7.tar.gz.
File metadata
- Download URL: thalovant-0.4.7.tar.gz
- Upload date:
- Size: 46.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0415a9df751f205f01f199d0d49f4df5f8b7a778d66921b3681f5e9befbb473b
|
|
| MD5 |
3caaddc3ec312784c1281648e893923b
|
|
| BLAKE2b-256 |
a122a8c7d3e3a79af5de40dcd0299d3ff3ab165e536664a86034b3053254e46c
|
File details
Details for the file thalovant-0.4.7-py3-none-any.whl.
File metadata
- Download URL: thalovant-0.4.7-py3-none-any.whl
- Upload date:
- Size: 41.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e3eb775d3d6c49c584ba4602b88c9290d2807d08abb370335ea4bcdfe9f0163
|
|
| MD5 |
3367e1a1f385d23e521cce38fc7c4189
|
|
| BLAKE2b-256 |
43e2dd205d0797697580a1a6a28ca13219a488fc7b93a06c982d38a215321992
|