The Spectron client ships inside the main SurrealDB Python package (surrealdb). Install one package and import Spectron or AsyncSpectron alongside the database driver.
Package naming: On PyPI, the Spectron client ships in the
surrealdbpackage alongside the database driver, so usepip install surrealdb. The bare namespectronbelongs to an unrelated project; do not install it for SurrealDB Spectron.
Installation
pip install surrealdbPython 3.10+ recommended.
Clients
Spectron is synchronous (uses requests). AsyncSpectron is async (uses aiohttp). Both expose the same method names; add await on the async client.
from surrealdb import Spectron, AsyncSpectron
with Spectron(
context="acme-prod",
endpoint="https://api.spectron.example",
api_key="sk-spec-...",
) as memory:
memory.remember("Alice was promoted to CTO.")
hits = memory.recall("What is Alice's role?", k=10)
for hit in hits.hits:
print(hit.score, hit.text)
async with AsyncSpectron(
context="acme-prod",
endpoint="https://api.spectron.example",
api_key="sk-spec-...",
) as memory:
await memory.remember("Alice was promoted to CTO.")
hits = await memory.recall("What is Alice's role?", k=10)Both clients are pinned to one context and call /api/v1/{context}/…. Pass context, endpoint, and api_key explicitly; the SDK does not read environment variables.
Scope
On the wire, scope is a ScopeSet: an ordered array of slash-path strings (for example ["org/acme/user/alice"]). Register paths with spectron scopes create before first use; see Contexts and scope.
The Python client accepts:
A single path:
scope="org/acme/user/alice"A list of paths:
scope=["org/acme/user/alice"]
| Argument | Default | Description |
|---|---|---|
context | required | Context id, e.g. "acme-prod". |
endpoint | required | Spectron host URL, e.g. "https://api.spectron.example". |
api_key | required | Bearer token (Authorization: Bearer …). |
timeout | 30.0 | Per-request timeout in seconds. |
max_retries | 3 | Retries for GETs and idempotent writes. |
Remember (facts)
memory.remember("Alice was promoted to CTO.", infer="full", scope=["org/acme/user/alice"])
memory.remember("Q3 board notes", labels=["topic=board"], memory_category="context")
memory.remember_many(
[
{"role": "user", "content": "I was promoted to CTO."},
{"role": "assistant", "content": "Congratulations!"},
],
extract="whole_conversation",
scope=["org/acme/user/alice"],
)remember and remember_many send an Idempotency-Key header (derived from method, path, body, and a 30-second bucket) so safe retries collapse server-side.
Recall and context
result = memory.recall(
"What is Alice's role?",
k=10,
mode="hybrid",
scope=["org/acme/user/alice"],
)
block = memory.query_context(
"What is Alice's role?",
k=10,
scope=["org/acme/user/alice"],
)Optional filters include labels, lens, scope_view (strict | merged | crossTeam), temporal bounds (as_of, valid_from, …), and geo location.
Documents
upload = memory.documents.upload(
"policy.pdf",
content_type="application/pdf",
title="Returns policy",
scope=["org/acme/team/eng"],
labels=["team=eng"],
)
doc = memory.documents.get(upload.id)
hits = memory.documents.query("refund window", k=5, mode="hybrid")
chunks = memory.documents.chunks(upload.id)
memory.documents.keywords.search("returns policy", k=10)Chat (including streaming)
reply = memory.chat("Summarise what you know about Alice", scope=["user/alice"])
print(reply.reply)
for chunk in memory.chat("Summarise what you know about Alice", stream=True):
if chunk.delta:
print(chunk.delta, end="", flush=True)
if chunk.done:
print("\n[trace]", chunk.trace_id)Other verbs and namespaces
Top-level methods: consolidate, reflect, elaborate, forget, state, whoami, profile, inspect, audit, health.
Grouped resources: memory.documents, memory.sessions, memory.entities, memory.scopes, memory.principals, memory.keys, memory.traces, memory.lifecycle.
→ Full method tables: Python SDK reference
Errors and retries
The SDK raises typed exceptions so you can handle auth, scope, and not-found cases precisely.
from surrealdb import SpectronAPIError, SpectronAuthError, SpectronNotFoundError, SpectronScopeError
try:
hits = memory.recall("what is my name?", scope=["user/alice"])
except SpectronAuthError as exc:
print(exc.status_code, exc.message)
except SpectronScopeError as exc:
print(exc.status_code, exc.message)
except SpectronNotFoundError as exc:
print(exc.status_code, exc.message)
except SpectronAPIError as exc:
print(exc.status_code, exc.message, exc.trace_id, exc.body)| Exception | HTTP | When it occurs |
|---|---|---|
SpectronError | n/a | Base class |
SpectronAPIError | Other non-2xx | Generic API failure; carries status_code, message, trace_id, body |
SpectronAuthError | 401 | Missing or invalid API key |
SpectronScopeError | 403 | Scope floor or principal rejects the call |
SpectronNotFoundError | 404 | Context, session, document, or other resource not found |
Responses of 400, 422, 429, and 5xx that are not mapped to a subclass surface as SpectronAPIError. Inspect status_code and body (RFC 7807 problem details) for validation and rate-limit information. The async client raises the same exceptions.
GET requests and idempotent writes (remember, remember_many) retry automatically on connection errors and 5xx responses: up to max_retries attempts (default 3) with 250 ms, 500 ms, 1000 ms backoff. Other writes and 4xx responses are not retried. Tune or disable on the constructor:
memory = Spectron(..., max_retries=0, timeout=10.0)The default timeout is 30 seconds; streaming chat disables the read timeout while tokens arrive. On a 429, read the problem-detail body and back off before retrying manually. All errors follow RFC 7807 Problem Details.
Response types
Typed dataclasses include RememberResponse, RecallResponse, RecallHit, ChatResponse, Document, Chunk, StateResponse, and others. Import from surrealdb.spectron when you need explicit types:
from surrealdb.spectron import RecallResponse, RecallHitHarness adapters (zero prompt change)
For agent frameworks that should auto-record every turn, Spectron ships Python adapters that build on this SDK:
pip install spectron-integration-crewai # CrewAI
pip install spectron-openai-agents # OpenAI Agents SDK
pip install spectron-strands # Strands Agents
pip install spectron-google-adk # Google ADKCLI alternative
The spectron binary exposes the same operations without the SDK:
spectron remember "Alice was promoted to CTO."
spectron recall "What is Alice's role?" --json