Python client for SmartMemory Service API
Project description
SmartMemory Python Client
Official Python client for the SmartMemory Service API.
Features
- ✅ Type-safe API with Pydantic models
- ✅ Automatic JWT authentication with token handling
- ✅ Full API coverage (CRUD, ingestion, search, links, temporal, etc.)
- ✅ Comprehensive error handling
- ✅ Clean, manually-maintained code (no code generation complexity)
- ✅ Automatic scoping - tenant/workspace/user derived from JWT token
Installation
pip install smartmemory-client
Development Installation
git clone https://github.com/smartmemory/smart-memory-client.git
cd smart-memory-client
pip install -e ".[dev]"
Quick Start
from smartmemory_client import SmartMemoryClient
# Initialize client with authentication
client = SmartMemoryClient(
base_url="http://localhost:9001",
api_key="your_jwt_token" # Or set SMARTMEMORY_API_KEY env var
)
# Add a memory
item_id = client.add("This is a test memory")
print(f"Added memory: {item_id}")
# Search memories
results = client.search("test", top_k=5)
for memory in results:
print(f"{memory.item_id}: {memory.content}")
# Ingest with full pipeline
result = client.ingest(
content="Complex content to process",
extractor_name="llm",
context={"source": "user", "timestamp": "2025-11-10"}
)
print(f"Ingested: {result['item_id']}")
Authentication
The client requires a JWT token for authentication. You can provide it in two ways:
1. Pass as parameter
client = SmartMemoryClient(
base_url="http://localhost:9001",
api_key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
)
2. Set environment variable
export SMARTMEMORY_API_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
import os
client = SmartMemoryClient(
base_url="http://localhost:9001",
api_key=os.getenv("SMARTMEMORY_API_KEY")
)
Getting a JWT Token
SmartMemory uses Clerk for authentication (PLAT-SSO-IDP-1). /auth/signup and
/auth/login have been removed. Tokens are obtained via the Clerk-hosted login
flow or, for programmatic/service access, via the Clerk session exchange endpoint:
# Exchange a Clerk session token for a SmartMemory JWT + cookies
curl -X POST "http://localhost:9001/auth/clerk/session" \
-H "Authorization: Bearer <clerk_session_token>"
# Response sets sm_access_token cookie and returns {"access_token": "eyJ..."}
# Verify / inspect the token
curl "http://localhost:9001/auth/me" \
-H "Authorization: Bearer <sm_access_token>"
# Response: {"id": "...", "email": "...", "default_team_id": "..."}
For local E2E / integration tests, set SM_E2E_TOKEN and SM_E2E_TEAM_ID env vars
(captured from a real Clerk login or the sm_access_token cookie) and the test
fixtures will inject them automatically.
API Reference
Memory Operations
Add Memory
# Simple add
item_id = client.add("Remember this")
# With metadata
item_id = client.add(
"Important fact",
metadata={"source": "user", "priority": "high"},
use_pipeline=True # Run full extraction pipeline
)
# Fast add (no pipeline)
item_id = client.add("Quick note", use_pipeline=False)
Search Memories
# Simple search
results = client.search("AI concepts", top_k=10)
# Search with SSG for better multi-hop reasoning
results = client.search("AI concepts", top_k=10, use_ssg=True)
# Search specific memory type
results = client.search("conversation", memory_type="episodic")
# Process results
for memory in results:
print(f"{memory.item_id}: {memory.content}")
print(f"Score: {memory.score}")
print(f"Metadata: {memory.metadata}")
Advanced Search (SSG)
# Best for general queries (query_traversal algorithm)
results = client.search_advanced(
query="What are neural networks?",
algorithm="query_traversal",
max_results=15
)
# Best for high precision (triangulation_fulldim algorithm)
results = client.search_advanced(
query="Specific technical fact",
algorithm="triangulation_fulldim",
max_results=10
)
# Process results
for memory in results:
print(f"{memory.item_id}: {memory.content}")
SSG Benefits:
- ✅ Superior multi-hop reasoning across related memories
- ✅ Better contextual retrieval (0.91 precision/recall vs 0.88)
- ✅ Higher faithfulness (facts vs opinions)
- ✅ Improved conversation and knowledge graph traversal
Based on: Eric Lester. (2025). Novel Semantic Similarity Graph Traversal Algorithms for Semantic Retrieval Augmented Generation Systems.
Get Memory
memory = client.get("item_123")
if memory:
print(f"Content: {memory.content}")
print(f"Type: {memory.memory_type}")
print(f"Metadata: {memory.metadata}")
Update Memory
# Update content
client.update("item_123", content="Updated content")
# Update metadata
client.update("item_123", metadata={"updated": True})
# Update both
client.update("item_123", content="New content", metadata={"version": 2})
Delete Memory
if client.delete("item_123"):
print("Memory deleted")
Ingestion
# Ingest with full pipeline
# Note: user_id, tenant_id, workspace_id are automatically derived from JWT token
result = client.ingest(
content="User: Hello\nAssistant: Hi there!",
extractor_name="llm",
context={
"conversation_id": "123",
"timestamp": "2025-11-10",
"source": "chat_interface"
}
)
print(f"Ingested: {result['item_id']}")
print(f"Queued for processing: {result['queued']}")
Links and Relationships
# Create link between memories
client.link("concept_1", "concept_2", link_type="RELATED")
client.link("cause_id", "effect_id", link_type="CAUSES")
# Get neighbors
neighbors = client.get_neighbors("item_123")
for neighbor in neighbors:
print(f"{neighbor['id']}: {neighbor['relation']}")
Code Search
# Semantic search over indexed code entities
results = client.code_search("authentication functions", semantic=True)
for entity in results:
print(f"{entity['name']} ({entity['entity_type']}) — {entity['file_path']}:{entity['line_number']}")
print(f" Score: {entity['score']}")
# Filter by entity type and repo
results = client.code_search(
"payment handler",
semantic=True,
entity_type="function",
repo="my-service"
)
# Non-semantic (Cypher substring match, default)
results = client.code_search("authenticate")
Enrichment
# Enrich a memory
result = client.enrich("item_123", routines=["sentiment", "keywords"])
print(f"Enrichment result: {result}")
Personalization
# Update user preferences
result = client.personalize(
traits={"learning_style": "visual"},
preferences={"language": "en", "complexity": "advanced"}
)
Feedback
# Provide feedback
result = client.provide_feedback(
feedback={
"item_id": "123",
"rating": 5,
"comment": "Very helpful"
},
memory_type="semantic"
)
Reasoning Traces (System 2 Memory)
# Extract reasoning from content
result = client.extract_reasoning('''
Thought: I need to analyze this bug.
Action: Let me search for the function.
Observation: Found the issue in line 42.
Conclusion: The fix is to add a null check.
''')
if result['has_reasoning']:
print(f"Found {result['step_count']} reasoning steps")
# Store a reasoning trace
result = client.store_reasoning_trace(
trace={
"trace_id": "trace_123",
"steps": [
{"type": "thought", "content": "Analyzing the problem"},
{"type": "conclusion", "content": "Found the solution"},
],
"task_context": {"goal": "Fix bug", "domain": "python"},
},
artifact_ids=["code_fix_456"] # Link to resulting artifacts
)
# Query reasoning traces ("why" queries)
result = client.query_reasoning("why did I use async/await?")
for trace in result['traces']:
print(f"Trace {trace['trace_id']}: {trace['content'][:100]}...")
# Get specific reasoning trace
trace = client.get_reasoning_trace("trace_123")
Synthesis Evolution (Opinions & Observations)
# Form opinions from episodic patterns
result = client.synthesize_opinions()
print(f"Status: {result['status']}")
# Create entity summaries from scattered facts
result = client.synthesize_observations()
print(f"Status: {result['status']}")
# Update opinion confidence based on new evidence
result = client.reinforce_opinions()
print(f"Status: {result['status']}")
Health Check
# Check service health
health = client.health_check()
print(health) # {'status': 'healthy'}
Summary Statistics
# Get memory statistics
summary = client.get_summary()
print(f"Total memories: {summary.get('total_count', 0)}")
Usage in Projects
Maya Integration
# maya/requirements.txt
smartmemory-client>=1.0.0
# maya/maya/api/memory_manager.py
import os
from smartmemory_client import SmartMemoryClient
class MemoryManager:
def __init__(self, smartmemory_url):
self.client = SmartMemoryClient(
base_url=smartmemory_url,
api_key=os.getenv("SMARTMEMORY_API_KEY")
)
def ingest_conversation(self, content, metadata):
# user_id, tenant_id, workspace_id automatically from JWT token
return self.client.ingest(
content=content,
extractor_name="llm",
context=metadata
)
def retrieve_relevant_memories(self, query):
return self.client.search(query=query, top_k=5)
Studio Integration
import os
from smartmemory_client import SmartMemoryClient
client = SmartMemoryClient(
base_url=os.getenv("SMARTMEMORY_URL"),
api_key=os.getenv("SMARTMEMORY_API_KEY")
)
# Use client for memory operations
memories = client.search("project requirements", top_k=10)
Error Handling
from smartmemory_client import SmartMemoryClient, SmartMemoryClientError
client = SmartMemoryClient("http://localhost:9001", api_key="token")
try:
item_id = client.add("Test memory")
except SmartMemoryClientError as e:
print(f"Error: {e}")
Configuration
Environment Variables
SMARTMEMORY_API_KEY- JWT token for authenticationSMARTMEMORY_URL- Base URL of the SmartMemory service (optional)
Client Options
client = SmartMemoryClient(
base_url="http://localhost:9001",
api_key="your_jwt_token",
timeout=30.0, # Request timeout in seconds
verify_ssl=True # Verify SSL certificates
)
Development
Setup
git clone https://github.com/smartmemory/smart-memory-client.git
cd smart-memory-client
pip install -e ".[dev]"
Running Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=smartmemory_client --cov-report=html
# Run specific test
pytest tests/test_client.py::test_add_memory
Code Quality
# Format code
black smartmemory_client tests
# Sort imports
isort smartmemory_client tests
# Lint
ruff check smartmemory_client tests
# Type check
mypy smartmemory_client
Versioning
This package follows Semantic Versioning:
- Major (1.0.0 → 2.0.0): Breaking changes
- Minor (1.0.0 → 1.1.0): New features, backward compatible
- Patch (1.0.0 → 1.0.1): Bug fixes
The client version is synced with the SmartMemory Service version.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Reporting Issues
Please report issues on GitHub Issues.
License
MIT License - see LICENSE file for details.
Links
- Documentation: https://docs.smartmemory.dev
- SmartMemory Service: https://github.com/smartmemory/smart-memory-service
- PyPI Package: https://pypi.org/project/smartmemory-client/
- Issues: https://github.com/smartmemory/smart-memory-client/issues
Changelog
See CHANGELOG.md for version history.
Made with ❤️ by the SmartMemory Team
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smartmemory_client-0.5.1.tar.gz.
File metadata
- Download URL: smartmemory_client-0.5.1.tar.gz
- Upload date:
- Size: 56.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5461e5b28c6618ce101cf91ad24a8f214cb0dd950412567b12346a5fd3e87da2
|
|
| MD5 |
7bbfe2877c7e681dc155bdc3d0794847
|
|
| BLAKE2b-256 |
659689635ab8a0b3279260b4c01473bf1d89170243af7eb4090b70aea1dee525
|
File details
Details for the file smartmemory_client-0.5.1-py3-none-any.whl.
File metadata
- Download URL: smartmemory_client-0.5.1-py3-none-any.whl
- Upload date:
- Size: 35.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d959c1cf3c0901952a733df90a3cb0b6563301dd9571068c6adfa7d273b9c5bd
|
|
| MD5 |
904d959534522e8a79e45c1fd5125ba0
|
|
| BLAKE2b-256 |
ad46eea9afa97c9cc982ec5859ab7951c975d419027119a3b4948808a2dd2db9
|