Last updated

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.

Python SDK repository

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
            }
        }
    ]
)