Python SDK
The Papr Python SDK provides a Pythonic interface for interacting with the Papr Memory API, with full type hints and modern Python features.
Installation
Install the SDK using pip:
pip install papr-memory
Requirements
- HTTPS: The endpoint requires HTTPS protocol. HTTP connections will fail.
- Environment Variable: Set
PAPR_MEMORY_API_KEY
in your environment before running. - X-Client-Type Header: This is automatically included by the SDK but can be customized if needed.
- Authentication: Only use one auth method (X-API-Key takes precedence over Bearer token).
Quick Start
from papr_memory import Papr
import os
# Initialize the client
client = Papr(
x_api_key=os.environ.get("PAPR_MEMORY_API_KEY") # Updated parameter name
)
# Add a memory
memory = client.memory.add(
content="Important meeting notes from today's discussion",
type="text",
metadata={
"topics": ["meetings", "notes"],
"createdAt": "2024-01-01T12:00:00Z"
}
)
# Search memories with agentic graph enabled
results = client.memory.search(
query="meeting notes from today",
enable_agentic_graph=True, # Recommended for better results
rank_results=False
)
# Add memories in batch
memories = client.memory.add_batch(
memories=[
{
"content": "First memory",
"type": "text",
"metadata": {"topics": ["topic1"]}
},
{
"content": "Second memory",
"type": "text",
"metadata": {"topics": ["topic2"]}
}
]
)
Authentication Methods
The SDK supports three authentication methods:
# API Key Authentication (recommended for most scenarios)
client = Papr(x_api_key="your-api-key") # Updated parameter name
# Bearer Token Authentication (for OAuth flows)
client = Papr(bearer_token="your-oauth-token")
# Session Token Authentication (for browser-based apps)
client = Papr(session_token="your-session-token")
Key SDK Features
- Full type hints support
- Automatic retries with exponential backoff
- Comprehensive error handling
- Async support
- Extensive documentation and examples
Main API Operations
# Memory Operations
client.memory.add(content="Memory content", type="text")
client.memory.get("memory_id")
client.memory.update("memory_id", content="Updated content")
client.memory.delete("memory_id")
client.memory.search(query="Search query", enable_agentic_graph=True)
client.memory.add_batch(memories=[...])
# User Operations
client.user.create(external_id="user123")
client.user.get("user_id")
client.user.update("user_id", email="updated@example.com")
client.user.delete("user_id")
client.user.list()
client.user.create_batch(users=[...])
# Feedback Operations
client.feedback.submit(
search_id="search_id",
feedback_data={
"feedback_type": "thumbs_up",
"feedback_source": "inline"
}
)
client.feedback.get_by_id("feedback_id")
client.feedback.submit_batch(feedback_items=[...])
Documentation
For complete documentation, examples, and API reference, visit our Python SDK repository.
Error Handling
The SDK provides typed exceptions for different error cases:
from papr_memory import Papr, APIError, NetworkError
client = Papr(x_api_key="your-api-key") # Updated parameter name
try:
client.memory.add(
content="Test memory",
type="text"
)
except APIError as e:
# Handle API errors (400, 401, 403, etc.)
print(f"API error {e.status_code}: {e.message}")
except NetworkError as e:
# Handle network errors
print(f"Network error: {e}")
Advanced Usage
Async Support
from papr_memory import AsyncPapr
async with AsyncPapr(x_api_key="your-api-key") as client: # Updated parameter name
memory = await client.memory.add(
content="Async memory creation",
type="text"
)
Batch Operations
memories = client.memory.add_batch(
memories=[
{
"content": "Memory 1",
"type": "text",
"metadata": {"topics": ["topic1"]}
},
{
"content": "Memory 2",
"type": "text",
"metadata": {"topics": ["topic2"]}
}
],
batch_size=10 # Optional: number of items to process in parallel
)
Search with Agentic Graph
# HIGHLY RECOMMENDED: Enable agentic graph for intelligent context-aware search
results = client.memory.search(
query="Find discussions about API performance issues from last month",
enable_agentic_graph=True, # Enables intelligent entity relationship navigation
max_memories=20, # Recommended for comprehensive memory coverage
max_nodes=15 # Recommended for comprehensive graph entity relationships
)
# Access both memories and graph nodes
for memory in results.data.memories:
print(f"Memory: {memory.content}")
# Work with graph nodes if available
for node in results.data.nodes:
print(f"Node: {node.label} - {node.properties.get('name', node.properties.get('id'))}")
Submitting Feedback
# Submit feedback for a search result
feedback_response = client.feedback.submit(
search_id="search_123",
feedback_data={
"feedback_type": "thumbs_up",
"feedback_source": "inline",
"feedback_text": "This result was exactly what I needed"
}
)
# Submit batch feedback
batch_response = client.feedback.submit_batch(
feedback_items=[
{
"search_id": "search_123",
"feedback_data": {
"feedback_type": "thumbs_up",
"feedback_source": "inline"
}
},
{
"search_id": "search_456",
"feedback_data": {
"feedback_type": "memory_relevance",
"feedback_source": "memory_citation",
"feedback_score": 0.9
}
}
]
)