Skip to main content

Python SDK for building Local Apps that integrate with RealtimeX

Project description

RealtimeX Local App SDK - Python

Python SDK for building Local Apps that integrate with RealtimeX.

Installation

pip install realtimex-sdk

Prerequisites

Before using this SDK, ensure your Supabase database is set up via the Main App:

  1. Open RealtimeXSettingsLocal Apps
  2. Create or configure your Local App
  3. Select Compatible ModeLogin to SupabaseAuto-Setup Schema

Note: Schema setup is handled entirely by the Main App.

Quick Start

import asyncio
from realtimex_sdk import RealtimeXSDK, SDKConfig

async def main():
    # Development Mode: Use API key
    sdk = RealtimeXSDK(config=SDKConfig(
        api_key="sk-abc123..."
    ))
    
    # OR Production Mode: Declare permissions
    sdk = RealtimeXSDK(config=SDKConfig(
        permissions=['activities.write', 'webhook.trigger']
    ))
    
    # Insert activity
    activity = await sdk.activities.insert({
        "type": "new_lead",
        "email": "user@example.com"
    })
    
    # Trigger agent (auto-run)
    result = await sdk.webhook.trigger_agent(
        raw_data=activity,
        auto_run=True,
        agent_name="lead-processor",
        workspace_slug="sales",
        thread_slug="general"
    )
    print(f"Task created: {result['task_uuid']}")
    
    # Or create calendar event for manual review
    result = await sdk.webhook.trigger_agent(
        raw_data=activity,
        auto_run=False
    )

asyncio.run(main())

Configuration (Optional)

Override auto-detected values if needed:

from realtimex_sdk import RealtimeXSDK, SDKConfig

sdk = RealtimeXSDK(config=SDKConfig(
    url="http://custom-host:3001",  # Default: localhost:3001
    api_key="sk-abc123...",         # Development mode
    app_id="registered-id"          # Production mode (override)
))

Environment Variables

When your app is started by the Main App, these are auto-set:

Variable Description
RTX_APP_ID Your app's unique ID
RTX_APP_NAME Your app's display name

API Reference

Activities CRUD

# Insert
activity = await sdk.activities.insert({"type": "order", "amount": 100})

# List
pending = await sdk.activities.list(status="pending", limit=50)

# Get
item = await sdk.activities.get("activity-uuid")

# Update
await sdk.activities.update("activity-uuid", {"status": "processed"})

# Delete
await sdk.activities.delete("activity-uuid")

LLM Module

Access AI capabilities through the RealtimeX proxy:

from realtimex_sdk import RealtimeXSDK, SDKConfig, ChatMessage, ChatOptions, VectorRecord

sdk = RealtimeXSDK(config=SDKConfig(
    permissions=['llm.chat', 'llm.embed', 'llm.providers', 'vectors.write', 'vectors.read']
))

List Providers & Models

# Get only configured Chat providers (recommended)
chat_res = await sdk.llm.chat_providers()
# chat_res.providers: List of chat providers with models

# Get only configured Embedding providers (recommended)
embed_res = await sdk.llm.embed_providers()
# embed_res.providers: List of embedding providers with models

Chat Completion

# Sync Chat
response = await sdk.llm.chat(
    messages=[
        ChatMessage(role="system", content="You are a helpful assistant."),
        ChatMessage(role="user", content="What is RealtimeX?")
    ],
    options=ChatOptions(
        model="gpt-4o",           # Optional: specific model
        provider="openai",        # Optional: specific provider
        temperature=0.7,          # Optional: 0.0-2.0
        max_tokens=1000           # Optional: max response tokens
    )
)
print(response.content)

# Multimodal Chat (text + file/image blocks)
multimodal = await sdk.llm.chat(
    messages=[
        ChatMessage(
            role="user",
            content=[
                {"type": "text", "text": "Summarize the attached document"},
                {"type": "input_file", "file_url": "https://example.com/report.pdf"},
                {"type": "input_image", "image_url": "https://example.com/chart.png"},
            ],
        )
    ]
)
print(multimodal.content)

# Streaming Chat
async for chunk in sdk.llm.chat_stream(messages, options=options):
    print(chunk.text, end="", flush=True)

Generate Embeddings

embed_result = await sdk.llm.embed(
    input=["Hello world", "Goodbye"],
    provider="openai",                    # Optional
    model="text-embedding-3-small"        # Optional
)
embeddings = embed_result.embeddings      # List[List[float]]
dimensions = embed_result.dimensions      # int (e.g., 1536)

Vector Store Operations

# Upsert vectors with metadata
await sdk.llm.vectors.upsert(
    vectors=[
        VectorRecord(
            id="chunk-1",
            vector=embeddings[0],
            metadata={
                "text": "Hello world",      # Original text (for retrieval)
                "documentId": "doc-1",       # Logical grouping
                "customField": "any value"   # Any custom metadata
            }
        )
    ],
    workspace_id="ws-123"                   # Optional: physical namespace isolation
)

# Query similar vectors
query_result = await sdk.llm.vectors.query(
    vector=embeddings[0],
    top_k=5,                                # Number of results
    workspace_id="ws-123",                  # Optional: search in specific workspace
    document_id="doc-1"                     # Optional: filter by document
)
# returns: VectorQueryResponse with results[]

# List all workspaces for this app
res = await sdk.llm.vectors.list_workspaces()
# returns: VectorListWorkspacesResponse with workspaces=['ws-123', 'default', ...]

# Delete all vectors in a workspace
await sdk.llm.vectors.delete(
    delete_all=True,
    workspace_id="ws-123"
)

High-Level Helpers

These combine multiple operations for common RAG patterns:

# embed_and_store: Text → Embed → Store (one call)
await sdk.llm.embed_and_store(
    texts=["Document text 1", "Document text 2"],  # texts to embed
    document_id="doc-123",                          # Optional: logical grouping
    workspace_id="ws-456",                          # Optional: physical isolation
    provider="openai",                              # Optional: embedding provider
    model="text-embedding-3-small"                  # Optional: embedding model
)

# search: Query → Embed → Search (one call)
results = await sdk.llm.search(
    query="What is RealtimeX?",                     # search query (text, not vector)
    top_k=5,                                        # Number of results
    workspace_id="ws-123",                          # Optional: search in workspace
    document_id="doc-1",                            # Optional: filter by document
    provider="openai",                              # Optional: embedding provider
    model="text-embedding-3-small"                  # Optional: embedding model
)
# returns: List[dict] with id, score, metadata

Note on Isolation:

  • workspace_id: Creates physical namespace (sdk_{appId}_{wsId}) - data completely isolated
  • document_id: Stored as metadata, filtered after search (post-filter)

Public APIs

# Get available agents in a workspace
agents = await sdk.api.get_agents()

# Get all workspaces
workspaces = await sdk.api.get_workspaces()

# Get threads in a workspace
threads = await sdk.api.get_threads("sales")

# Get task status
task = await sdk.api.get_task("task-uuid")

Contract Discovery

contract = await sdk.contract.get_local_app_v1()
print(contract.get("version"))  # local-app-contract/v1
print(contract.get("supported_events"))
print(contract.get("callback", {}).get("signature_header"))  # x-rtx-contract-signature

Worker Callback Lifecycle

Use this when worker context includes task_uuid, attempt_id, and callback URL metadata.

sdk.task.configure_contract(
    callback_secret=os.environ.get("RTX_CONTRACT_CALLBACK_SECRET"),
    sign_callbacks_by_default=True,
)

await sdk.task.claim(
    task_uuid,
    callback_url=callback_url,
    machine_id=machine_id,
    attempt_id=attempt_id,
    user_email=user_email,
)

await sdk.task.start(
    task_uuid,
    machine_id=machine_id,
    callback_url=callback_url,
    attempt_id=attempt_id,
)

await sdk.task.progress(
    task_uuid,
    {"percent": 50, "message": "Halfway done"},
    callback_url=callback_url,
    machine_id=machine_id,
    attempt_id=attempt_id,
)

await sdk.task.complete(
    task_uuid,
    {"summary": "Done"},
    callback_url=callback_url,
    machine_id=machine_id,
    attempt_id=attempt_id,
)

TaskModule automatically includes event_id, canonical event, and optional signature header for idempotent/signed callbacks.

Contract Compatibility Check

Run the cross-language harness (Main App endpoint + TypeScript SDK + Python SDK):

RTX_API_KEY=sk-... RTX_CONTRACT_VERIFY_BASE_URL=http://127.0.0.1:3001 node scripts/verify-contract-compat.mjs

Error Handling

The SDK provides specific exception classes for handling LLM-related issues:

from realtimex_sdk import LLMPermissionError, LLMProviderError

try:
    async for chunk in sdk.llm.chat_stream(messages):
        print(chunk.text, end="")
except LLMPermissionError as e:
    # Permission not granted: 'llm.chat' etc.
    print(f"Permission required: {e.permission}")
except LLMProviderError as e:
    # Provider errors: rate limit, timeout, model unavailable, etc.
    print(f"Provider error: {e} (code: {e.code})")
    # Common codes: LLM_STREAM_ERROR, RATE_LIMIT, PROVIDER_UNAVAILABLE
Exception Class Common Codes Description
LLMPermissionError PERMISSION_REQUIRED Missing or denied permission
LLMProviderError LLM_STREAM_ERROR, RATE_LIMIT, PROVIDER_UNAVAILABLE AI provider issues

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

realtimex_sdk-1.4.0.tar.gz (135.2 kB view details)

Uploaded Source

Built Distribution

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

realtimex_sdk-1.4.0-py3-none-any.whl (34.9 kB view details)

Uploaded Python 3

File details

Details for the file realtimex_sdk-1.4.0.tar.gz.

File metadata

  • Download URL: realtimex_sdk-1.4.0.tar.gz
  • Upload date:
  • Size: 135.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for realtimex_sdk-1.4.0.tar.gz
Algorithm Hash digest
SHA256 5f09616eb1e602bf272815b1048e4daec8cf59880f2d72b296cfb3e91e7b2f33
MD5 a4a671aa411bf5b3fe15115e37b75536
BLAKE2b-256 31384825f7b34e2644c4d30f753012454a006c68aba927325a897bbcce0fd69d

See more details on using hashes here.

Provenance

The following attestation bundles were made for realtimex_sdk-1.4.0.tar.gz:

Publisher: pypi-publish.yml on therealtimex/realtimex-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file realtimex_sdk-1.4.0-py3-none-any.whl.

File metadata

  • Download URL: realtimex_sdk-1.4.0-py3-none-any.whl
  • Upload date:
  • Size: 34.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for realtimex_sdk-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eee1d267a3b3bfab31bad7f4d8d2a6297b16f45dace40f807676bc552aab80b0
MD5 7110988ef07c15e272ae8a00e69325a0
BLAKE2b-256 8913d9f9baac96ef6a74a06e4dba0e1c4f1551ce06ac88ea7f31601261c55cc3

See more details on using hashes here.

Provenance

The following attestation bundles were made for realtimex_sdk-1.4.0-py3-none-any.whl:

Publisher: pypi-publish.yml on therealtimex/realtimex-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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