Python SDK
beginnerComplete reference for the engramma-cloud Python package — installation, initialization, all methods, async support, error handling, typing, and retry policy.
Installation
pip install engramma-cloudRequires Python 3.9+.
Initialization
import os
from engramma_cloud import EngrammaClient
client = EngrammaClient(api_key=os.environ['ENGRAMMA_API_KEY'])| Parameter | Type | Default | Description |
|---|---|---|---|
api_key | str | — | Your API key (sent as X-API-Key header) |
base_url | str | https://api.engramma-memory.com | API base URL |
timeout | int | 30 | Request timeout in seconds |
max_retries | int | 3 | Automatic 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| Parameter | Type | Required | Description |
|---|---|---|---|
text | str | Yes | The content to store |
metadata | dict | No | Key-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')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})')| Parameter | Type | Required | Description |
|---|---|---|---|
query | str | Yes | Natural-language question |
top_k | int | No | Max 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})')| Parameter | Type | Required | Description |
|---|---|---|---|
query | str | Yes | Natural-language question |
top_k | int | No | Max 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| Parameter | Type | Required | Description |
|---|---|---|---|
query | str | Yes | The query to explain |
lang | str | No | Language 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
)| Parameter | Type | Required | Description |
|---|---|---|---|
query | str | No | Query to match patterns for deletion |
category | str | No | Category of patterns to forget |
threshold | float | No | Similarity 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 valuesReturns: 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.91predict
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}')| Parameter | Type | Required | Description |
|---|---|---|---|
mode | str | No | 'full' or 'light' (default: 'full') |
protect_categories | list[str] | No | Categories 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')| Parameter | Type | Required | Description |
|---|---|---|---|
threshold | float | No | Similarity 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.82neighbors
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})')| Parameter | Type | Required | Description |
|---|---|---|---|
text | str | Yes | The reference text |
direction | str | No | 'causes' or 'effects' |
min_strength | float | No | Minimum 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())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}')| Exception | HTTP Status | When |
|---|---|---|
AuthenticationError | 401 | Invalid or expired API key |
PermissionError | 403 | Key lacks required scope |
NotFoundError | 404 | Resource does not exist |
ValidationError | 422 | Invalid request parameters |
RateLimitError | 429 | Too many requests |
ServerError | 5xx | Internal 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 | NoneRetry policy
The SDK automatically retries failed requests with exponential backoff:
| Condition | Retried | Backoff |
|---|---|---|
| 429 (Rate Limit) | Yes | Uses Retry-After header |
| 500, 502, 503, 504 | Yes | Exponential: 1s, 2s, 4s |
| Network timeout | Yes | Exponential: 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
- JavaScript SDK — TypeScript-first client for browser and Node.js
- Go SDK — Struct-based client with context propagation
- API Reference Overview — Full endpoint documentation
- Your First Memory — Quick start tutorial