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.7.4.tar.gz (207.9 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.7.4-py3-none-any.whl (56.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: realtimex_sdk-1.7.4.tar.gz
  • Upload date:
  • Size: 207.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for realtimex_sdk-1.7.4.tar.gz
Algorithm Hash digest
SHA256 e6350c82ae6004047282ae87051868ddeb7d5a2938afe78ac5c178765e7be056
MD5 eff216dbbe8e3ff2a538a26f03b66d3d
BLAKE2b-256 ac12c3ea97aa3a1992ae218e2967cbd9dfa72adf72019c7ba4903009c86050fe

See more details on using hashes here.

File details

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

File metadata

  • Download URL: realtimex_sdk-1.7.4-py3-none-any.whl
  • Upload date:
  • Size: 56.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for realtimex_sdk-1.7.4-py3-none-any.whl
Algorithm Hash digest
SHA256 7bb0b8eae6d29e3529d60276c6e2c3a57e8a634d7d474cae8dad965681376b2e
MD5 99e3d6819f2217612c2f189dee9256b5
BLAKE2b-256 01f1d42cbe865465d1770253e5eb2d4c9b8bf789691c73cbb8f640542d84edbb

See more details on using hashes here.

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