Skip to main content

Official Python SDK for MemoryLayer

Project description

MemoryLayer Python SDK

Official Python SDK for MemoryLayer - The intelligent memory layer for AI applications.

PyPI version License: MIT Python 3.8+

Features

  • 🧠 Memory Management: Store, retrieve, and manage AI memories
  • 🔍 Hybrid Search: Vector + keyword + graph-based retrieval
  • 🕸️ Memory Graph: Visualize and traverse memory relationships
  • 🎯 Smart Retrieval: LLM reranking and query rewriting
  • 📊 Observability: Track performance and quality metrics
  • 🔐 Type-Safe: Full type hints with Pydantic models

Installation

pip install memorylayerai

Quick Start

1. Get Your API Key

Sign up at memorylayer.com and create an API key from your project settings.

2. Initialize the Client

from memorylayer import MemoryLayer

client = MemoryLayer(
    api_key="ml_key_...",
    # Optional: specify custom base URL
    # base_url="https://api.memorylayer.com"
)

3. Create Memories

# Create a single memory
memory = client.memories.create(
    project_id="your-project-id",
    content="The user prefers dark mode in their applications",
    type="preference",
    tags={
        "category": "ui",
        "importance": "high"
    }
)

print(f"Memory created: {memory.id}")

4. Search Memories

# Hybrid search (vector + keyword + graph)
results = client.search.hybrid(
    project_id="your-project-id",
    query="What are the user UI preferences?",
    limit=10,
    # Optional: enable advanced features
    use_reranking=True,      # LLM-based reranking
    use_query_rewriting=True, # Query expansion
    use_graph_traversal=True  # Follow memory relationships
)

for result in results:
    print(f"Score: {result.score}")
    print(f"Content: {result.content}")
    print(f"Type: {result.type}")

Core Features

Memory Management

Create Memory

memory = client.memories.create(
    project_id="project-id",
    content="User completed onboarding on 2024-01-15",
    type="fact",
    tags={
        "event": "onboarding",
        "date": "2024-01-15"
    },
    metadata={
        "source": "mobile-app",
        "version": "2.1.0"
    }
)

List Memories

memories = client.memories.list(
    project_id="project-id",
    types=["fact", "preference"],
    status=["active"],
    page=1,
    page_size=50
)

print(f"Total: {memories.total}")
for memory in memories.items:
    print(memory.content)

Get Memory

memory = client.memories.get("memory-id")
print(memory.content)

Update Memory

updated = client.memories.update(
    "memory-id",
    content="Updated content",
    tags={"updated": "true"}
)

Delete Memory

client.memories.delete("memory-id")

Search & Retrieval

Hybrid Search

Combines vector search, keyword search, and graph traversal:

results = client.search.hybrid(
    project_id="project-id",
    query="What does the user like?",
    limit=10,
    
    # Scoring weights (optional)
    vector_weight=0.5,
    keyword_weight=0.3,
    recency_weight=0.2,
    
    # Advanced features
    use_reranking=True,      # Use LLM to rerank results
    use_query_rewriting=True, # Expand and clarify query
    use_graph_traversal=True, # Follow memory relationships
    graph_depth=2            # How many hops to traverse
)

Vector Search Only

results = client.search.vector(
    project_id="project-id",
    query="user preferences",
    limit=5,
    threshold=0.7  # Minimum similarity score
)

Keyword Search Only

results = client.search.keyword(
    project_id="project-id",
    query="dark mode",
    limit=5
)

Memory Graph

Get Graph Data

graph = client.graph.get(
    project_id="project-id",
    # Optional filters
    memory_types=["fact", "preference"],
    search_query="user preferences",
    date_range={
        "start": "2024-01-01",
        "end": "2024-12-31"
    }
)

print(f"Nodes: {len(graph.nodes)}")
print(f"Edges: {len(graph.edges)}")

# Nodes
for node in graph.nodes:
    print(f"{node.id}: {node.content}")

# Edges (relationships)
for edge in graph.edges:
    print(f"{edge.source} -> {edge.target} ({edge.type})")

Create Edge

edge = client.graph.create_edge(
    project_id="project-id",
    source_memory_id="memory-1",
    target_memory_id="memory-2",
    relationship_type="derives",  # or 'similarity', 'temporal', etc.
    metadata={
        "confidence": 0.95,
        "reason": "User explicitly linked these"
    }
)

Traverse Graph

related = client.graph.traverse(
    project_id="project-id",
    start_memory_ids=["memory-1"],
    depth=2,  # How many hops
    relationship_types=["similarity", "derives"]
)

print(f"Found {len(related)} related memories")

Ingestion

Ingest Document

job = client.ingestion.ingest(
    project_id="project-id",
    content="Long document content...",
    metadata={
        "title": "Product Documentation",
        "source": "docs.example.com"
    },
    # Chunking strategy
    chunking_strategy="semantic",  # or 'fixed-size', 'sentence', 'paragraph'
    chunk_size=512,
    chunk_overlap=50
)

print(f"Job ID: {job.id}")
print(f"Status: {job.status}")

Check Job Status

job = client.ingestion.get_job("job-id")
print(f"Status: {job.status}")
print(f"Progress: {job.progress}%")
print(f"Memories created: {job.memories_created}")

Advanced Features

LLM Reranking

Improve search relevance using LLM-based reranking:

results = client.search.hybrid(
    project_id="project-id",
    query="complex user question",
    limit=20,
    use_reranking=True,
    reranking_model="gpt-4",  # or 'claude-3'
    reranking_top_k=10  # Return top 10 after reranking
)

Query Rewriting

Expand and clarify queries for better results:

results = client.search.hybrid(
    project_id="project-id",
    query="ML preferences",  # Will expand to "machine learning preferences"
    use_query_rewriting=True,
    query_rewriting_strategy="expansion"  # or 'clarification', 'multi-query'
)

Graph Traversal

Follow memory relationships for contextual retrieval:

results = client.search.hybrid(
    project_id="project-id",
    query="user settings",
    use_graph_traversal=True,
    graph_depth=2,  # Follow relationships 2 hops deep
    graph_relationship_types=["similarity", "derives"]
)

Type Safety

The SDK uses Pydantic for full type safety:

from memorylayer import (
    MemoryLayer,
    Memory,
    SearchResult,
    GraphData,
    IngestionJob
)

# All methods return typed objects
client = MemoryLayer(api_key="ml_key_...")

# Type hints and validation
memory: Memory = client.memories.create(
    project_id="project-id",
    content="typed content",
    type="fact"  # Validated against allowed types
)

Async Support

The SDK supports async/await for better performance:

import asyncio
from memorylayer import AsyncMemoryLayer

async def main():
    client = AsyncMemoryLayer(api_key="ml_key_...")
    
    # All methods are async
    memory = await client.memories.create(
        project_id="project-id",
        content="async memory"
    )
    
    results = await client.search.hybrid(
        project_id="project-id",
        query="async search"
    )
    
    print(f"Found {len(results)} results")

asyncio.run(main())

Error Handling

from memorylayer import MemoryLayerError

try:
    memory = client.memories.create(
        project_id="project-id",
        content="test"
    )
except MemoryLayerError as e:
    print(f"API Error: {e.message}")
    print(f"Status: {e.status_code}")
    print(f"Request ID: {e.request_id}")
except Exception as e:
    print(f"Unexpected error: {e}")

Configuration

Custom Base URL

client = MemoryLayer(
    api_key="ml_key_...",
    base_url="https://your-custom-domain.com"
)

Timeout

client = MemoryLayer(
    api_key="ml_key_...",
    timeout=30.0  # 30 seconds
)

Retry Configuration

client = MemoryLayer(
    api_key="ml_key_...",
    max_retries=3,
    retry_delay=1.0  # 1 second
)

Examples

Chatbot with Memory

from memorylayer import MemoryLayer
import os

client = MemoryLayer(api_key=os.getenv("MEMORYLAYER_API_KEY"))
project_id = "your-project-id"

def chat_with_memory(user_message: str, user_id: str) -> str:
    # 1. Search for relevant memories
    memories = client.search.hybrid(
        project_id=project_id,
        query=user_message,
        limit=5,
        use_reranking=True,
        use_graph_traversal=True
    )
    
    # 2. Build context from memories
    context = "\n\n".join([m.content for m in memories])
    
    # 3. Send to LLM with context
    response = call_your_llm(
        system=f"You are a helpful assistant. Use this context about the user:\n\n{context}",
        user=user_message
    )
    
    # 4. Store new memory from conversation
    client.memories.create(
        project_id=project_id,
        content=f'User said: "{user_message}". Assistant responded: "{response}"',
        type="fact",
        tags={"user_id": user_id, "timestamp": datetime.now().isoformat()}
    )
    
    return response

Document Q&A

import time

def ingest_and_query(document_content: str, question: str) -> str:
    # 1. Ingest document
    job = client.ingestion.ingest(
        project_id="your-project-id",
        content=document_content,
        chunking_strategy="semantic",
        chunk_size=512
    )
    
    # 2. Wait for ingestion to complete
    while True:
        status = client.ingestion.get_job(job.id)
        if status.status != "processing":
            break
        time.sleep(1)
    
    # 3. Query the document
    results = client.search.hybrid(
        project_id="your-project-id",
        query=question,
        limit=3,
        use_reranking=True
    )
    
    return "\n\n".join([r.content for r in results])

LangChain Integration

from memorylayer import MemoryLayer
from langchain.memory import BaseMemory
from typing import Any, Dict, List

class MemoryLayerMemory(BaseMemory):
    """LangChain memory backed by MemoryLayer"""
    
    def __init__(self, api_key: str, project_id: str):
        self.client = MemoryLayer(api_key=api_key)
        self.project_id = project_id
    
    @property
    def memory_variables(self) -> List[str]:
        return ["history"]
    
    def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
        # Search for relevant memories
        results = self.client.search.hybrid(
            project_id=self.project_id,
            query=inputs.get("input", ""),
            limit=5,
            use_reranking=True
        )
        
        history = "\n".join([r.content for r in results])
        return {"history": history}
    
    def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None:
        # Save conversation to MemoryLayer
        self.client.memories.create(
            project_id=self.project_id,
            content=f"User: {inputs['input']}\nAssistant: {outputs['output']}",
            type="fact"
        )
    
    def clear(self) -> None:
        pass  # MemoryLayer handles memory lifecycle

# Usage with LangChain
memory = MemoryLayerMemory(
    api_key="ml_key_...",
    project_id="your-project-id"
)

API Reference

Full API documentation available at docs.memorylayer.com

Support

License

MIT License - see LICENSE file for details.

Changelog

v0.2.0 (2024-01-20)

  • ✨ Added Memory Graph API support
  • ✨ Added Hybrid Search with LLM reranking
  • ✨ Added Query Rewriting capabilities
  • ✨ Added Graph Traversal for contextual retrieval
  • ✨ Added async/await support
  • 🐛 Fixed type hints for better IDE support
  • 📚 Comprehensive documentation and examples

v0.1.1 (2024-01-10)

  • 🐛 Bug fixes and stability improvements

v0.1.0 (2024-01-01)

  • 🎉 Initial release
  • ✨ Basic memory CRUD operations
  • ✨ Vector search
  • ✨ Ingestion API

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

memorylayerai-0.5.0.tar.gz (44.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memorylayerai-0.5.0-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file memorylayerai-0.5.0.tar.gz.

File metadata

  • Download URL: memorylayerai-0.5.0.tar.gz
  • Upload date:
  • Size: 44.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for memorylayerai-0.5.0.tar.gz
Algorithm Hash digest
SHA256 e26a010bb70723f89d7a34c006e3d0f33b830aabb0255a3bdd763119b41682bb
MD5 77af5c19b357dc017e6509da80f6b230
BLAKE2b-256 dc508356cab64b8fdf3a782a2a7a58802c9881849303f53b2285593a04d49385

See more details on using hashes here.

File details

Details for the file memorylayerai-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: memorylayerai-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for memorylayerai-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0f1efcb683513dfa8050f6791590a7743f00d0705ef0922469c3b45f9e250247
MD5 bedfc3ecae2a4c86386959ae2dccfcf7
BLAKE2b-256 ddc6fa9ccb5e6bf2ca79c87878ffce83b232cc04b618adf1d71a7e6c3c373a81

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page