Skip to content

Python SDK

beginner

Complete reference for the engramma-cloud Python package — installation, initialization, all methods, async support, error handling, typing, and retry policy.

Installation

pip install engramma-cloud

Requires Python 3.9+.


Initialization

import os
from engramma_cloud import EngrammaClient

client = EngrammaClient(api_key=os.environ['ENGRAMMA_API_KEY'])
ParameterTypeDefaultDescription
api_keystrYour API key (sent as X-API-Key header)
base_urlstrhttps://api.engramma-memory.comAPI base URL
timeoutint30Request timeout in seconds
max_retriesint3Automatic retries on 5xx and 429

Text operations

All text methods are accessed via client.text.

store

Store a single memory pattern. Maps to POST /v1/memory/text/store.

result = client.text.store(
    text='The deployment window is Tuesday 2-4pm UTC',
    metadata={'category': 'ops', 'priority': 'high'}
)
print(result.pattern_id)       # pat_7f3a2b...
print(result.embedding_dim)    # 384
print(result.patterns_used)    # 42
print(result.patterns_limit)   # 10000
ParameterTypeRequiredDescription
textstrYesThe content to store
metadatadictNoKey-value metadata attached to the pattern

Returns: StoreResult with fields success, pattern_id, embedding_dim, patterns_used, patterns_limit.

batch_store

Store multiple memories in a single request (max 50 items). Maps to POST /v1/memory/text/batch-store.

results = client.text.batch_store([
    {'text': 'Alice joined the team on Jan 5'},
    {'text': 'Project deadline is March 15', 'metadata': {'dept': 'engineering'}},
    {'text': 'Budget approved for Q2', 'metadata': {'dept': 'finance'}}
])
print(f'Stored {len(results.pattern_ids)} patterns')
Warning

Maximum 50 items per batch request. Requests exceeding this limit will return a 422 validation error.

retrieve

Retrieve memories matching a natural-language query via embedding similarity. Maps to POST /v1/memory/text/retrieve.

response = client.text.retrieve(
    query='When can we deploy?',
    top_k=5
)
print(f'Latency: {response.latency_ms}ms')
for r in response.results:
    print(f'{r.text} (similarity: {r.similarity}, id: {r.pattern_id})')
ParameterTypeRequiredDescription
querystrYesNatural-language question
top_kintNoMax results (default: 5)

Returns: RetrieveResponse with results (list of {text, metadata, similarity, pattern_id}) and latency_ms.

recall

Context-aware recall using Active Inference. Maps to POST /v1/memory/text/recall.

response = client.text.recall(
    query='What happened before the outage?',
    top_k=10
)
for r in response.results:
    print(f'{r.text} (similarity: {r.similarity})')
ParameterTypeRequiredDescription
querystrYesNatural-language question
top_kintNoMax results (default: 5)

explain

Get a human-readable explanation of how a memory was retrieved. Maps to POST /v1/memory/text/explain.

explanation = client.text.explain(
    query='When can we deploy?',
    lang='en'
)
print(explanation.explanation)
print(explanation.method)      # e.g. 'cosine_similarity'
print(explanation.confidence)  # 0.93
ParameterTypeRequiredDescription
querystrYesThe query to explain
langstrNoLanguage for explanation: 'en' or 'fr' (default: 'en')

Returns: ExplainResult with fields explanation, method, confidence.

forget

Remove memory patterns matching a query or category. Maps to DELETE /v1/memory/text/forget.

client.text.forget(
    query='deployment window',
    category='ops',
    threshold=0.85
)
ParameterTypeRequiredDescription
querystrNoQuery to match patterns for deletion
categorystrNoCategory of patterns to forget
thresholdfloatNoSimilarity threshold for matching (default: 0.85)

embed

Generate an embedding vector for a text. Maps to POST /v1/memory/text/embed.

result = client.text.embed(text='The deployment window is Tuesday')
print(f'Dimension: {result.dim}')       # 384
print(f'Vector: {result.embedding[:5]}')  # first 5 values

Returns: EmbedResult with fields embedding (list of floats) and dim (384).

similarity

Compute similarity between two texts. Maps to POST /v1/memory/text/similarity.

result = client.text.similarity(
    text_a='The server crashed at 3am',
    text_b='There was a 3am outage on the server'
)
print(f'Similarity: {result.similarity}')  # 0.91

predict

Predict related memories from a query. Maps to POST /v1/memory/text/predict.

response = client.text.predict(
    query='What will happen next quarter?',
    top_k=5
)
for r in response.results:
    print(f'{r.text} (similarity: {r.similarity})')

stats

Get memory storage statistics. Maps to GET /v1/memory/text/stats.

stats = client.text.stats()
print(f'Total patterns: {stats.total_patterns}')
print(f'Embedding dim: {stats.embedding_dim}')
print(f'Storage: {stats.storage_bytes} bytes')

Returns: TextStats with fields total_patterns, embedding_dim, storage_bytes.

important

Retrieve protected facts (important memories). Maps to GET /v1/memory/text/important.

facts = client.text.important()
for fact in facts:
    print(f'{fact.text} (id: {fact.pattern_id})')

Consolidation operations

Memory consolidation (sleep/wake cycles) is accessed via client.consolidation.

sleep

Trigger memory consolidation. Maps to POST /v1/memory/consolidation/sleep.

result = client.consolidation.sleep(
    mode='full',
    protect_categories=['critical', 'compliance']
)
print(f'Consolidation started: {result}')
ParameterTypeRequiredDescription
modestrNo'full' or 'light' (default: 'full')
protect_categorieslist[str]NoCategories to protect from consolidation

wake

End the consolidation cycle. Maps to POST /v1/memory/consolidation/wake.

client.consolidation.wake()

status

Check current consolidation status. Maps to GET /v1/memory/consolidation/status.

status = client.consolidation.status()
print(f'State: {status.state}')  # 'awake', 'sleeping', etc.

preview

Preview what consolidation would do without executing. Maps to GET /v1/memory/consolidation/preview.

preview = client.consolidation.preview()
print(f'Merge candidates: {preview.merge_candidates}')
print(f'Patterns affected: {preview.patterns_affected}')

merge_duplicates

Merge duplicate patterns above a similarity threshold. Maps to POST /v1/memory/consolidation/merge-duplicates.

result = client.consolidation.merge_duplicates(threshold=0.85)
print(f'Merged: {result.merged_count} patterns')
ParameterTypeRequiredDescription
thresholdfloatNoSimilarity threshold for merging (default: 0.85)

Regime operations

Access the current memory regime via client.regime.

current

Get the current active regime. Maps to GET /v1/memory/regime.

regime = client.regime.current()
print(f'Current regime: {regime.name}')
print(f'Parameters: {regime.parameters}')

history

Get regime transition history. Maps to GET /v1/memory/regime/history.

history = client.regime.history(last_n=10)
for entry in history:
    print(f'{entry.timestamp}: {entry.from_regime} -> {entry.to_regime}')

Causal operations

Causal inference methods are accessed via client.causal.

strength

Compute causal strength between two texts. Maps to POST /v1/memory/causal/strength.

result = client.causal.strength(
    text_a='Server load increased to 95%',
    text_b='Response times degraded'
)
print(f'Causal strength: {result.strength}')  # 0.82

neighbors

Find causally connected memories. Maps to POST /v1/memory/causal/neighbors.

neighbors = client.causal.neighbors(
    text='The database connection pool was exhausted',
    direction='effects',     # 'causes' or 'effects'
    min_strength=0.6
)
for n in neighbors:
    print(f'{n.text} (strength: {n.strength})')
ParameterTypeRequiredDescription
textstrYesThe reference text
directionstrNo'causes' or 'effects'
min_strengthfloatNoMinimum causal strength to include

Async support

All methods have async equivalents via AsyncEngrammaClient:

import asyncio
from engramma_cloud import AsyncEngrammaClient

async def main():
    client = AsyncEngrammaClient(api_key='nx_live_...')

    # All methods are awaitable
    result = await client.text.store(text='Async memory storage works')
    response = await client.text.retrieve(query='What was stored?')

    # Concurrent operations
    stores = await asyncio.gather(
        client.text.store(text='Fact A'),
        client.text.store(text='Fact B'),
        client.text.store(text='Fact C')
    )
    print(f'Stored {len(stores)} patterns concurrently')

    await client.close()

asyncio.run(main())
Tip

Always call await client.close() when done, or use the async context manager: async with AsyncEngrammaClient(...) as client:


Error handling

The SDK raises typed exceptions for all error cases:

from engramma_cloud.exceptions import (
    EngrammaError,        # Base exception
    AuthenticationError,  # 401 — invalid or expired key
    PermissionError,      # 403 — insufficient scope
    NotFoundError,        # 404 — resource not found
    ValidationError,      # 422 — invalid parameters
    RateLimitError,       # 429 — rate limit exceeded
    ServerError           # 5xx — server-side error
)

try:
    response = client.text.retrieve(query='test')
except RateLimitError as e:
    print(f'Rate limited. Retry after {e.retry_after}s')
except AuthenticationError:
    print('Invalid API key')
except EngrammaError as e:
    print(f'Error {e.status_code}: {e.message}')
ExceptionHTTP StatusWhen
AuthenticationError401Invalid or expired API key
PermissionError403Key lacks required scope
NotFoundError404Resource does not exist
ValidationError422Invalid request parameters
RateLimitError429Too many requests
ServerError5xxInternal server error

Typing

The SDK is fully typed with Pydantic models. All responses return typed objects with IDE autocompletion:

from engramma_cloud.types import (
    StoreResult,
    RetrieveResponse,
    RetrieveResult,
    ExplainResult,
    EmbedResult,
    TextStats
)

# Type hints work everywhere
result: StoreResult = client.text.store(text='typed result')
response: RetrieveResponse = client.text.retrieve(query='query')

# Access typed fields
result.pattern_id       # str
result.embedding_dim    # int
result.patterns_used    # int
result.patterns_limit   # int

for r in response.results:
    r.text        # str
    r.similarity  # float
    r.pattern_id  # str
    r.metadata    # dict | None

Retry policy

The SDK automatically retries failed requests with exponential backoff:

ConditionRetriedBackoff
429 (Rate Limit)YesUses Retry-After header
500, 502, 503, 504YesExponential: 1s, 2s, 4s
Network timeoutYesExponential: 1s, 2s, 4s
4xx (other)No

Configure retry behavior:

client = EngrammaClient(
    api_key='nx_live_...',
    max_retries=5,          # default: 3
    retry_backoff=2.0,      # backoff multiplier (default: 2.0)
    retry_max_wait=30       # max wait between retries in seconds
)

Logging

Enable debug logging to see requests and responses:

import logging
logging.basicConfig(level=logging.DEBUG)

# Or enable only for the SDK
logging.getLogger('engramma_cloud').setLevel(logging.DEBUG)

Next steps