A Python client library for the AssistantHub REST API. Provides both synchronous and asynchronous clients with full type annotations.
pip install assistanthub-sdkRequirements: Python 3.10+, httpx, pydantic >= 2.0
from assistanthub_sdk import AssistantHubClient
client = AssistantHubClient(
base_url="http://localhost:8800",
api_key="your-api-key",
)
# List assistants
result = client.list_assistants()
for assistant in result.objects:
print(assistant.name)
# Send a chat message
from assistanthub_sdk import ChatCompletionMessage
response = client.send_message(
assistant_id="ast_123",
messages=[ChatCompletionMessage(role="user", content="Hello!")],
)
print(response.choices[0].message.content)
client.close()traces = client.list_assistant_tool_calls(
assistant_id="ast_123",
tool_name="collection_search",
trace_id="trace_abc123",
)
deleted = client.delete_assistant_tool_calls(
assistant_id="ast_123",
tool_name="collection_search",
)
print(deleted.deleted_count)from assistanthub_sdk import AssistantHubClient, ChatCompletionMessage, ChatLocalAttachment
with AssistantHubClient(base_url="http://localhost:8800", api_key="key") as client:
selectable = client.list_assistant_documents(
assistant_id="ast_123",
query="guide",
content_type="application/pdf",
)
document_id = selectable.objects[0].id
response = client.send_message(
assistant_id="ast_123",
messages=[
ChatCompletionMessage(role="user", content="Summarize this document.")
],
attached_document_ids=[document_id],
)
local_response = client.send_message(
assistant_id="ast_123",
messages=[
ChatCompletionMessage(role="user", content="Summarize this local file.")
],
local_attachments=[
ChatLocalAttachment(
name="notes.txt",
content_type="text/plain",
base64_content="VGhpcyBpcyBhIGxvY2FsIGZpbGUu",
)
],
)local_attachments require assistant document attachments to be enabled. They are processed for the chat request only and are not added to the assistant collection.
with AssistantHubClient(base_url="http://localhost:8800", api_key="key") as client:
assistant = client.get_assistant("ast_123")
print(assistant.name)import asyncio
from assistanthub_sdk import AsyncAssistantHubClient, ChatCompletionMessage
async def main():
async with AsyncAssistantHubClient(
base_url="http://localhost:8800",
api_key="your-api-key",
) as client:
# List assistants
result = await client.list_assistants()
for assistant in result.objects:
print(assistant.name)
# Send a message
response = await client.send_message(
assistant_id="ast_123",
messages=[ChatCompletionMessage(role="user", content="Hello!")],
)
print(response.choices[0].message.content)
asyncio.run(main())Both clients support streaming responses via SSE.
from assistanthub_sdk import AssistantHubClient, ChatCompletionMessage
with AssistantHubClient(base_url="http://localhost:8800", api_key="key") as client:
for chunk in client.send_message_stream(
assistant_id="ast_123",
messages=[ChatCompletionMessage(role="user", content="Tell me a story")],
):
print(chunk, end="", flush=True)async with AsyncAssistantHubClient(base_url="http://localhost:8800", api_key="key") as client:
async for chunk in client.send_message_stream(
assistant_id="ast_123",
messages=[ChatCompletionMessage(role="user", content="Tell me a story")],
):
print(chunk, end="", flush=True)The SDK raises typed exceptions for common HTTP errors:
from assistanthub_sdk import (
AssistantHubClient,
AssistantHubError,
AuthenticationError,
NotFoundError,
ValidationError,
)
client = AssistantHubClient(base_url="http://localhost:8800", api_key="key")
try:
assistant = client.get_assistant("nonexistent")
except NotFoundError as e:
print(f"Not found: {e} (status={e.status_code})")
except AuthenticationError as e:
print(f"Auth failed: {e}")
except ValidationError as e:
print(f"Bad request: {e}")
except AssistantHubError as e:
print(f"API error: {e} (status={e.status_code})")from assistanthub_sdk import AssistantHubClient, RequestHistorySearchFilter
with AssistantHubClient(base_url="http://localhost:8800", api_key="key") as client:
summary = client.get_request_history_summary(
RequestHistorySearchFilter(max_results=25, path_contains="/v1.0/assistants")
)
print(summary.total_count)
page = client.list_request_history(RequestHistorySearchFilter(max_results=10))
first = page.objects[0] if page.objects else None
if first:
detail = client.get_request_history_detail(first.id)
print(detail.path, detail.status_code)from assistanthub_sdk import AssistantAnalyticsQuery, AssistantHubClient
with AssistantHubClient(base_url="http://localhost:8800", api_key="key") as client:
query = AssistantAnalyticsQuery(range="lastDay", metrics=["request_count", "p95_duration_ms"])
overview = client.get_assistant_analytics_overview("asst_abc123", query)
series = client.get_assistant_analytics_time_series("asst_abc123", query)
endpoints = client.get_assistant_analytics_endpoints("asst_abc123", {"range": "lastWeek", "limit": 10})
print(overview.request_count, len(series.series or []), len(endpoints.endpoints or []))from assistanthub_sdk import (
AssistantHubClient,
CifsCrawlRepositorySettings,
CrawlPlan,
NfsCrawlRepositorySettings,
NfsVersion,
RepositoryType,
WebCrawlRepositorySettings,
)
with AssistantHubClient(base_url="http://localhost:8800", api_key="key") as client:
connectivity = client.test_crawl_plan_draft_connectivity(
CrawlPlan(
name="Website Connectivity Probe",
repository_type=RepositoryType.WEB,
repository_settings=WebCrawlRepositorySettings(
start_url="https://docs.example.com",
follow_links=False,
),
)
)
web_plan = client.create_crawl_plan(
CrawlPlan(
name="Website Crawl",
repository_type=RepositoryType.WEB,
repository_settings=WebCrawlRepositorySettings(
start_url="https://docs.example.com",
max_depth=3,
),
)
)
cifs_plan = client.create_crawl_plan(
CrawlPlan(
name="CIFS Share Crawl",
repository_type=RepositoryType.CIFS,
repository_settings=CifsCrawlRepositorySettings(
cifs_hostname="fileserver.example.com",
cifs_username="crawler",
cifs_password="secret",
cifs_share_name="content",
include_subdirectories=True,
),
)
)
nfs_plan = client.create_crawl_plan(
CrawlPlan(
name="NFS Export Crawl",
repository_type=RepositoryType.NFS,
repository_settings=NfsCrawlRepositorySettings(
nfs_hostname="nfs.example.com",
nfs_user_id=1000,
nfs_group_id=1000,
nfs_share_name="/exports/content",
nfs_version=NfsVersion.V3,
include_subdirectories=True,
),
)
)list_assistants()-- List all assistants (paginated)get_assistant(assistant_id)-- Get a single assistantget_assistant_tools(assistant_id)-- Get effective tool availability for an assistantvalidate_assistant_tool_policy(assistant_id, request)-- Validate draft tool policy without saving ittest_assistant_tool_policy(assistant_id, request)-- Run admin dry-run tool diagnostics without executing toolscreate_assistant(assistant)-- Create a new assistantupdate_assistant(assistant_id, assistant)-- Update an assistantdelete_assistant(assistant_id)-- Delete an assistant
list_assistant_documents(assistant_id, query=..., content_type=...)-- List safe public document metadata selectable in assistant chatsend_message(assistant_id, messages, ...)-- Send a chat messagesend_message_stream(assistant_id, messages, ...)-- Stream a chat responsesearch(assistant_id, query, ...)-- RAG search via chatgenerate(assistant_id, messages, ...)-- Generate without RAGgenerate_stream(assistant_id, messages, ...)-- Stream generation without RAGopen_assistant_chat(assistant_id)-- Notify AssistantHub that a chat window opened and warm configured endpoint models when enabled
list_documents(collection_id, ...)-- List documents (paginated)get_document(document_id)-- Get a single documentupload_document(ingestion_rule_id, content, ...)-- Upload a documentdelete_document(document_id)-- Delete a documentbulk_delete_documents(document_ids)-- Delete multiple documentsreindex_document(document_id)-- Reindex one completed document into Verbexreindex_documents(request, ...)-- Reindex a bounded page or explicit list of completed documents into Verbex
list_ingestion_rules(...)-- List ingestion rules (paginated)get_ingestion_rule(rule_id)-- Get a single rulecreate_ingestion_rule(rule)-- Create a ruleupdate_ingestion_rule(rule_id, rule)-- Update a ruledelete_ingestion_rule(rule_id)-- Delete a rule
list_collections(...)-- List collections (paginated)get_collection(collection_id)-- Get a single collectioncreate_collection(collection)-- Create a collectionupdate_collection(collection_id, collection)-- Update a collectiondelete_collection(collection_id)-- Delete a collectionsearch_collection(collection_id, request)-- Search RecallDB collection records through AssistantHub
list_indices(...)-- List Verbex inverted indicescreate_index(index)-- Create a Verbex inverted indexget_index(index_id)-- Get Verbex index metadataindex_exists(index_id)-- Check whether a Verbex index existsupdate_index(index_id, index)-- Update Verbex index metadatadelete_index(index_id)-- Delete a Verbex indexupdate_index_labels(index_id, labels)-- Replace Verbex index labelsupdate_index_tags(index_id, tags)-- Replace Verbex index tagsupdate_index_custom_metadata(index_id, metadata)-- Replace Verbex index custom metadataget_index_top_terms(index_id, max_results=None)-- Get top terms for a Verbex indexsearch_index(index_id, request)-- Search a Verbex index
list_index_records(index_id, ...)-- List records in a Verbex indexcreate_index_record(index_id, record)-- Create one Verbex index recordcreate_index_records_batch(index_id, records)-- Create Verbex index records in batchcheck_index_records_exist(index_id, record_ids)-- Check multiple Verbex record IDsget_index_record(index_id, record_id)-- Get one Verbex index recordindex_record_exists(index_id, record_id)-- Check whether a Verbex index record existsdelete_index_record(index_id, record_id)-- Delete one Verbex index recorddelete_index_records(index_id, record_ids)-- Delete multiple Verbex index recordsupdate_index_record_labels(index_id, record_id, labels)-- Replace Verbex record labelsupdate_index_record_tags(index_id, record_id, tags)-- Replace Verbex record tagsupdate_index_record_custom_metadata(index_id, record_id, metadata)-- Replace Verbex record custom metadata
list_threads(assistant_id, ...)-- List threadsget_thread(assistant_id, thread_id)-- Get thread historycreate_thread(assistant_id)-- Create a new threaddelete_thread(thread_id)-- Delete a thread
list_embedding_endpoints(...)-- List endpoints (paginated)get_embedding_endpoint(endpoint_id)-- Get a single endpointcreate_embedding_endpoint(endpoint)-- Create an endpointupdate_embedding_endpoint(endpoint_id, endpoint)-- Update an endpointdelete_embedding_endpoint(endpoint_id)-- Delete an endpointcheck_embedding_health()-- Check all endpoint healthcheck_embedding_endpoint_health(endpoint_id)-- Check single endpoint health
list_completion_endpoints(...)-- List endpoints (paginated)get_completion_endpoint(endpoint_id)-- Get a single endpointcreate_completion_endpoint(endpoint)-- Create an endpointupdate_completion_endpoint(endpoint_id, endpoint)-- Update an endpointdelete_completion_endpoint(endpoint_id)-- Delete an endpointcheck_completion_health()-- Check all endpoint healthcheck_completion_endpoint_health(endpoint_id)-- Check single endpoint health
list_models(assistant_id)-- List available modelspull_model(model_name)-- Start pulling a modelget_pull_status()-- Check pull progressdelete_model(model_name)-- Delete a model
list_eval_facts(...)-- List eval facts (paginated)get_eval_fact(fact_id)-- Get a single factcreate_eval_fact(fact)-- Create a factupdate_eval_fact(fact_id, fact)-- Update a factdelete_eval_fact(fact_id)-- Delete a factstart_eval_run(run_request)-- Start an eval runlist_eval_runs(...)-- List eval runs (paginated)get_eval_run(run_id)-- Get a single rundelete_eval_run(run_id)-- Delete a runlist_eval_results(run_id)-- Get run resultsget_eval_run_results(run_id)-- Get run resultsget_eval_result(result_id)-- Get a single resultstream_eval_run(run_id)-- Stream run updates via SSEget_default_judge_prompt()-- Get the default judge prompt
list_request_history(filter=None)-- List request-history entriesget_request_history_summary(filter=None)-- Summarize request-history entriesget_request_history(request_id)-- Get a request-history entryget_request_history_detail(request_id)-- Get detailed request/response payloadsdelete_request_history(request_id)-- Delete a single request-history entrydelete_request_history_bulk(filter=None)-- Delete request-history entries matching a filter
get_assistant_analytics_overview(assistant_id, query=None)-- Summary metrics for an assistantget_assistant_analytics_time_series(assistant_id, query=None)-- Chart-ready time-series metricsget_assistant_analytics_stages(assistant_id, query=None)-- Stage bucket summariesget_assistant_analytics_endpoints(assistant_id, query=None)-- Endpoint/model/provider summariesget_assistant_analytics_slowest(assistant_id, query=None)-- Slowest assistant requestsget_assistant_analytics_feedback(assistant_id, query=None)-- Feedback trend and totals
list_crawl_plans(...)-- List crawl plans (paginated)get_crawl_plan(plan_id)-- Get a single plancreate_crawl_plan(plan)-- Create a planupdate_crawl_plan(plan_id, plan)-- Update a plandelete_crawl_plan(plan_id)-- Delete a planstart_crawl(plan_id)-- Start a crawlstop_crawl(plan_id)-- Stop a crawltest_crawl_connectivity(plan_id)-- Test connectivitytest_crawl_plan_draft_connectivity(plan)-- Test unsaved crawl plan settingsenumerate_crawl_contents(plan_id)-- Enumerate available contents
list_crawl_operations(plan_id, ...)-- List operations (paginated)get_crawl_operation(plan_id, operation_id)-- Get a single operationdelete_crawl_operation(plan_id, operation_id)-- Delete an operationget_crawl_plan_statistics(plan_id)-- Get plan statisticsget_crawl_operation_statistics(plan_id, operation_id)-- Get operation statistics
get_config()-- Get server configurationupdate_config(config)-- Update server configuration
health_check()-- Check server healthwhoami()-- Get authenticated user info
list_tenants(...)-- List tenants (paginated)get_tenant(tenant_id)-- Get a single tenantcreate_tenant(tenant)-- Create a tenantupdate_tenant(tenant_id, tenant)-- Update a tenantdelete_tenant(tenant_id)-- Delete a tenant
list_users(tenant_id, ...)-- List users (paginated)get_user(tenant_id, user_id)-- Get a single usercreate_user(tenant_id, user)-- Create a userupdate_user(tenant_id, user_id, user)-- Update a userdelete_user(tenant_id, user_id)-- Delete a user
list_credentials(tenant_id, ...)-- List credentials (paginated)get_credential(tenant_id, credential_id)-- Get a single credentialcreate_credential(tenant_id, credential)-- Create a credentialupdate_credential(tenant_id, credential_id, credential)-- Update a credentialdelete_credential(tenant_id, credential_id)-- Delete a credential