diff options
| author | Dhravya Shah <[email protected]> | 2026-01-18 16:55:32 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-18 16:55:32 -0800 |
| commit | 87b361c26bf5fc16049cd2727825891aa14b8e8b (patch) | |
| tree | c2f9f4f6223a7c1734578b772a16490ba2eb8b96 /packages/docs-test/tests/python | |
| parent | Add Claude Code GitHub Workflow (#681) (diff) | |
| download | supermemory-87b361c26bf5fc16049cd2727825891aa14b8e8b.tar.xz supermemory-87b361c26bf5fc16049cd2727825891aa14b8e8b.zip | |
docs changes (#678)
Co-authored-by: Claude Opus 4.5 <[email protected]>
Diffstat (limited to 'packages/docs-test/tests/python')
| -rw-r--r-- | packages/docs-test/tests/python/quickstart.py | 53 | ||||
| -rw-r--r-- | packages/docs-test/tests/python/sdk.py | 152 | ||||
| -rw-r--r-- | packages/docs-test/tests/python/search.py | 113 | ||||
| -rw-r--r-- | packages/docs-test/tests/python/user_profiles.py | 102 |
4 files changed, 420 insertions, 0 deletions
diff --git a/packages/docs-test/tests/python/quickstart.py b/packages/docs-test/tests/python/quickstart.py new file mode 100644 index 00000000..e0689900 --- /dev/null +++ b/packages/docs-test/tests/python/quickstart.py @@ -0,0 +1,53 @@ +import os +from dotenv import load_dotenv + +load_dotenv() + +from supermemory import Supermemory + +client = Supermemory() +USER_ID = "docs-test-user-py" + +conversation = [ + {"role": "assistant", "content": "Hello, how are you doing?"}, + {"role": "user", "content": "Hello! I am Dhravya. I am 20 years old. I love to code!"}, + {"role": "user", "content": "Can I go to the club?"}, +] + +print("Testing quickstart Python code...\n") + +# Get user profile + relevant memories for context +print("1. Getting user profile...") +profile = client.profile(container_tag=USER_ID, q=conversation[-1]["content"]) + +print(f"Profile response: {profile}") + +def get_memory(r): + if hasattr(r, 'memory'): + return r.memory + return r.get('memory', '') if isinstance(r, dict) else str(r) + +context = f"""Static profile: +{chr(10).join(profile.profile.static)} + +Dynamic profile: +{chr(10).join(profile.profile.dynamic)} + +Relevant memories: +{chr(10).join(get_memory(r) for r in profile.search_results.results)}""" + +print(f"\n2. Built context: {context}") + +# Build messages with memory-enriched context +messages = [{"role": "system", "content": f"User context:\n{context}"}, *conversation] +print("\n3. Messages built successfully") + +# Store conversation for future context +print("\n4. Adding memory...") +add_result = client.add( + content="\n".join(f"{m['role']}: {m['content']}" for m in conversation), + container_tag=USER_ID, +) + +print(f"Add result: {add_result}") +print("\n✅ Quickstart Python test passed!") diff --git a/packages/docs-test/tests/python/sdk.py b/packages/docs-test/tests/python/sdk.py new file mode 100644 index 00000000..a083ede2 --- /dev/null +++ b/packages/docs-test/tests/python/sdk.py @@ -0,0 +1,152 @@ +import os +import time +from pathlib import Path +from dotenv import load_dotenv +import httpx +import supermemory +from supermemory import Supermemory + +load_dotenv() + +client = Supermemory() + + +def test_documents_crud(): + """Test document CRUD operations""" + print("\n=== Document CRUD Operations ===") + + # Create + doc = client.documents.add(content=f"Test content - {time.time()}") + print(f"✓ documents.add: {doc.id}") + + # Read + fetched = client.documents.get(doc.id) + print(f"✓ documents.get: {fetched.id}") + + # Update + updated = client.documents.update(doc.id, content=f"Updated - {time.time()}") + print(f"✓ documents.update: {updated.id}") + + # Wait for processing + time.sleep(10) + + # Delete + client.documents.delete(doc.id) + print("✓ documents.delete") + + +def test_batch_operations(): + """Test batch operations""" + print("\n=== Batch Operations ===") + + batch = client.documents.batch_add( + documents=[ + {"content": f"Batch 1 - {time.time()}"}, + {"content": f"Batch 2 - {time.time()}"}, + ] + ) + print(f"✓ documents.batch_add: {batch}") + + +def test_search(): + """Test search""" + print("\n=== Search ===") + + results = client.search.execute(q="test content") + print(f"✓ search.execute: {len(results.results) if results.results else 0} results") + + +def test_file_uploads(): + """Test file uploads""" + print("\n=== File Uploads ===") + + test_path = Path("/tmp/test-py-upload.txt") + test_path.write_text(f"Test content {time.time()}") + client.documents.upload_file(file=test_path) + print("✓ documents.upload_file with Path") + test_path.unlink() + + +def test_error_handling(): + """Test error handling patterns""" + print("\n=== Error Handling ===") + + try: + client.documents.add(content="Test content") + print("✓ Error handling pattern works") + except supermemory.APIConnectionError: + print("APIConnectionError handled") + except supermemory.RateLimitError: + print("RateLimitError handled") + except supermemory.APIStatusError: + print("APIStatusError handled") + + +def test_client_config(): + """Test client configuration""" + print("\n=== Client Configuration ===") + + # Retries + client2 = Supermemory(max_retries=0) + print("✓ max_retries config") + + # Timeout + client3 = Supermemory(timeout=20.0) + print("✓ timeout config") + + # Granular timeout + client4 = Supermemory(timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0)) + print("✓ granular timeout config") + + # Per-request options + client.with_options(max_retries=5).documents.add(content="Test content") + print("✓ per-request options") + + +def test_raw_response(): + """Test raw response access""" + print("\n=== Raw Response ===") + + response = client.documents.with_raw_response.add(content="Test content") + print(f"✓ with_raw_response: has headers={hasattr(response, 'headers')}") + + memory = response.parse() + print(f"✓ parse(): {memory.id}") + + +def test_streaming_response(): + """Test streaming response""" + print("\n=== Streaming Response ===") + + with client.documents.with_streaming_response.add(content="Test content") as response: + print(f"✓ with_streaming_response: has headers={hasattr(response, 'headers')}") + + +def test_context_manager(): + """Test context manager""" + print("\n=== Context Manager ===") + + with Supermemory() as temp_client: + print("✓ Context manager works") + + +def main(): + print("Python SDK Tests") + print("================") + + test_documents_crud() + test_batch_operations() + test_search() + test_file_uploads() + test_error_handling() + test_client_config() + test_raw_response() + test_streaming_response() + test_context_manager() + + print("\n================") + print("✅ All Python SDK tests passed!") + + +if __name__ == "__main__": + main() diff --git a/packages/docs-test/tests/python/search.py b/packages/docs-test/tests/python/search.py new file mode 100644 index 00000000..820629eb --- /dev/null +++ b/packages/docs-test/tests/python/search.py @@ -0,0 +1,113 @@ +import os +from dotenv import load_dotenv +from supermemory import Supermemory + +load_dotenv() + +client = Supermemory() + + +def test_search_modes(): + """Test different search modes""" + print("=== Search Modes ===") + + # Hybrid search + hybrid = client.search.memories( + q="quarterly goals", + container_tag="user_123", + search_mode="hybrid", + ) + print(f"✓ hybrid search: {len(hybrid.results)} results") + + # Memories only + memories = client.search.memories( + q="user preferences", + container_tag="user_123", + search_mode="memories", + ) + print(f"✓ memories search: {len(memories.results)} results") + + +def test_filtering(): + """Test search filtering""" + print("\n=== Filtering ===") + + # Basic containerTag filter + results = client.search.memories( + q="project updates", + container_tag="user_123", + search_mode="hybrid", + ) + print(f"✓ containerTag filter: {len(results.results)} results") + + # Metadata filtering + filtered = client.search.memories( + q="meeting notes", + container_tag="user_123", + filters={ + "AND": [ + {"key": "type", "value": "meeting"}, + {"key": "year", "value": "2024"}, + ] + }, + ) + print(f"✓ metadata filter: {len(filtered.results)} results") + + +def test_reranking(): + """Test reranking""" + print("\n=== Reranking ===") + + results = client.search.memories( + q="complex technical question", + container_tag="user_123", + rerank=True, + ) + print(f"✓ reranking: {len(results.results)} results") + + +def test_threshold(): + """Test similarity threshold""" + print("\n=== Threshold ===") + + broad = client.search.memories(q="test query", threshold=0.3) + print(f"✓ broad threshold (0.3): {len(broad.results)} results") + + precise = client.search.memories(q="test query", threshold=0.8) + print(f"✓ precise threshold (0.8): {len(precise.results)} results") + + +def test_chatbot_context(): + """Test chatbot context pattern""" + print("\n=== Chatbot Context Pattern ===") + + def get_context(user_id: str, message: str) -> str: + results = client.search.memories( + q=message, + container_tag=user_id, + search_mode="hybrid", + threshold=0.6, + limit=5, + ) + return "\n\n".join(r.memory or r.chunk or "" for r in results.results) + + context = get_context("user_123", "What are the project updates?") + print(f"✓ chatbot context: {len(context)} chars") + + +def main(): + print("Search Tests") + print("============\n") + + test_search_modes() + test_filtering() + test_reranking() + test_threshold() + test_chatbot_context() + + print("\n============") + print("✅ All search tests passed!") + + +if __name__ == "__main__": + main() diff --git a/packages/docs-test/tests/python/user_profiles.py b/packages/docs-test/tests/python/user_profiles.py new file mode 100644 index 00000000..f34c1499 --- /dev/null +++ b/packages/docs-test/tests/python/user_profiles.py @@ -0,0 +1,102 @@ +import os +import time +from dotenv import load_dotenv +from supermemory import Supermemory + +load_dotenv() + +client = Supermemory() +USER_ID = "docs-test-profiles-py" + + +def test_basic_profile(): + """Test basic profile retrieval""" + print("=== Basic Profile ===") + + profile = client.profile( + container_tag=USER_ID, + q="What are my preferences?", + ) + + print(f"✓ Static profile: {len(profile.profile.static)} items") + print(f"✓ Dynamic profile: {len(profile.profile.dynamic)} items") + print(f"✓ Search results: {len(profile.search_results.results)} items") + + +def test_profile_with_memories(): + """Test profile with memory context""" + print("\n=== Profile with Memory Context ===") + + # Add some memories + client.add( + content="User prefers dark mode for all applications", + container_tag=USER_ID, + ) + client.add( + content="User is learning TypeScript and Rust", + container_tag=USER_ID, + ) + + # Wait for indexing + time.sleep(2) + + # Get profile with search + profile = client.profile( + container_tag=USER_ID, + q="What programming languages does the user know?", + ) + + print("✓ Profile retrieved with memories") + print(f" Static: {profile.profile.static[:2]}") + print(f" Dynamic: {profile.profile.dynamic[:2]}") + + +def get_memory(r): + if hasattr(r, 'memory'): + return r.memory + return r.get('memory', '') if isinstance(r, dict) else str(r) + + +def test_building_context(): + """Test building LLM context""" + print("\n=== Building LLM Context ===") + + conversation = [{"role": "user", "content": "What theme should I use for my IDE?"}] + + profile = client.profile( + container_tag=USER_ID, + q=conversation[-1]["content"], + ) + + context = f"""User Profile: +{chr(10).join(profile.profile.static)} + +Recent Context: +{chr(10).join(profile.profile.dynamic)} + +Relevant Memories: +{chr(10).join(get_memory(r) for r in profile.search_results.results)}""" + + print(f"✓ Built context: {len(context)} chars") + + messages = [ + {"role": "system", "content": f"Use this context about the user:\n{context}"}, + *conversation, + ] + print(f"✓ Messages ready for LLM: {len(messages)} messages") + + +def main(): + print("User Profiles Tests") + print("===================\n") + + test_basic_profile() + test_profile_with_memories() + test_building_context() + + print("\n===================") + print("✅ All user profile tests passed!") + + +if __name__ == "__main__": + main() |