- Spec files
pypi-langgraph-sdk
Describes: pkg:pypi/langgraph-sdk@0.2.x
- Description
- Python SDK for interacting with the LangGraph Platform REST API to build and manage AI assistants and conversational workflows
- Author
- tessl
- Last updated
persistent-storage.md docs/
1# Persistent Storage23Cross-thread persistent memory system for storing and retrieving documents, configuration, and application data with namespacing, search capabilities, and flexible data organization.45## Capabilities67### Item Storage Operations89Store, retrieve, update, and delete items in the persistent storage system with flexible key-value organization.1011```python { .api }12from collections.abc import Mapping, Sequence13from typing import Any, Literal14from langgraph_sdk.schema import Item, QueryParamTypes1516# Via client.store17async def put_item(18namespace: Sequence[str],19/,20key: str,21value: Mapping[str, Any],22index: Literal[False] | list[str] | None = None,23ttl: int | None = None,24headers: Mapping[str, str] | None = None,25params: QueryParamTypes | None = None,26) -> None:27"""28Store an item.2930Args:31namespace: The namespace to store the item in.32key: The unique identifier for the item.33value: The value to store.34index: Whether to index the item. If a list is provided, only the specified fields will be indexed.35ttl: Time-to-live for the item in seconds.36headers: Optional custom headers to include with the request.37params: Optional query parameters to include with the request.38"""3940async def get_item(41namespace: Sequence[str],42/,43key: str,44*,45refresh_ttl: bool | None = None,46headers: Mapping[str, str] | None = None,47params: QueryParamTypes | None = None,48) -> Item:49"""50Retrieve a single item.5152Args:53namespace: The namespace to retrieve the item from.54key: The unique identifier for the item.55refresh_ttl: Whether to refresh the item's TTL.56headers: Optional custom headers to include with the request.57params: Optional query parameters to include with the request.5859Returns:60Item: The retrieved item.61"""6263async def delete_item(64namespace: Sequence[str],65/,66key: str,67headers: Mapping[str, str] | None = None,68params: QueryParamTypes | None = None,69) -> None:70"""71Delete an item.7273Args:74namespace: The namespace to delete the item from.75key: The unique identifier for the item.76headers: Optional custom headers to include with the request.77params: Optional query parameters to include with the request.78"""79```8081### Search & Discovery8283Search for items across namespaces with text queries, filtering, and pagination.8485```python { .api }86from langgraph_sdk.schema import SearchItemsResponse, ListNamespaceResponse8788async def search_items(89namespace_prefix: Sequence[str],90/,91filter: Mapping[str, Any] | None = None,92limit: int = 10,93offset: int = 0,94query: str | None = None,95refresh_ttl: bool | None = None,96headers: Mapping[str, str] | None = None,97params: QueryParamTypes | None = None,98) -> SearchItemsResponse:99"""100Search for items in the store.101102Args:103namespace_prefix: The namespace prefix to search under.104filter: Filtering criteria for the search.105limit: Maximum number of items to return (default is 10).106offset: Number of items to skip before returning results (default is 0).107query: Optional query string for full-text search.108refresh_ttl: Whether to refresh the TTL of found items.109headers: Optional custom headers to include with the request.110params: Optional query parameters to include with the request.111112Returns:113SearchItemsResponse: The search results.114"""115116async def list_namespaces(117*,118prefix: Sequence[str] | None = None,119suffix: Sequence[str] | None = None,120max_depth: int | None = None,121limit: int = 100,122offset: int = 0,123headers: Mapping[str, str] | None = None,124params: QueryParamTypes | None = None,125) -> ListNamespaceResponse:126"""127List namespaces with optional match conditions.128129Args:130prefix: Optional list of strings representing the prefix to filter namespaces.131suffix: Optional list of strings representing the suffix to filter namespaces.132max_depth: Optional integer specifying the maximum depth of namespaces to return.133limit: Maximum number of namespaces to return (default is 100).134offset: Number of namespaces to skip before returning results (default is 0).135headers: Optional custom headers to include with the request.136params: Optional query parameters to include with the request.137138Returns:139ListNamespaceResponse: The list of namespaces.140"""141```142143## Types144145```python { .api }146class Item(TypedDict):147"""Stored item with metadata."""148namespace: list[str]149key: str150value: dict151created_at: str152updated_at: str153index: dict154155class SearchItem(TypedDict):156"""Search result item with relevance score."""157namespace: list[str]158key: str159value: dict160created_at: str161updated_at: str162index: dict163score: float164165class SearchItemsResponse(TypedDict):166"""Search results with pagination."""167items: list[SearchItem]168total: int169limit: int170offset: int171172class ListNamespaceResponse(TypedDict):173"""Namespace listing response."""174namespaces: list[list[str]]175total: int176limit: int177offset: int178```179180## Usage Examples181182### Basic Item Operations183184```python185# Store user preferences186user_prefs = {187"theme": "dark",188"language": "en",189"notifications": True,190"timezone": "America/New_York"191}192193await client.store.put_item(194value=user_prefs,195namespace=["users", "user-123", "preferences"],196key="ui_settings"197)198199# Retrieve user preferences200prefs = await client.store.get_item(201namespace=["users", "user-123", "preferences"],202key="ui_settings"203)204205print(f"User theme: {prefs['value']['theme']}")206207# Update preferences (store overwrites)208updated_prefs = prefs["value"].copy()209updated_prefs["theme"] = "light"210211await client.store.put_item(212value=updated_prefs,213namespace=["users", "user-123", "preferences"],214key="ui_settings"215)216```217218### Document Storage219220```python221# Store conversation history222conversation = {223"messages": [224{"role": "human", "content": "Hello", "timestamp": "2023-12-01T10:00:00Z"},225{"role": "assistant", "content": "Hi there!", "timestamp": "2023-12-01T10:00:01Z"}226],227"summary": "Greeting exchange",228"participants": ["user-123", "assistant-456"]229}230231await client.store.put_item(232value=conversation,233namespace=["conversations", "user-123"],234key="conv-2023-12-01",235index={236"participants": ["user-123", "assistant-456"],237"date": "2023-12-01",238"message_count": 2239}240)241242# Store configuration243app_config = {244"api_endpoints": {245"auth": "https://auth.api.com",246"data": "https://data.api.com"247},248"features": {249"analytics": True,250"caching": True,251"rate_limiting": {"rpm": 1000}252},253"version": "1.2.0"254}255256await client.store.put_item(257value=app_config,258namespace=["application", "config"],259key="production"260)261```262263### Hierarchical Organization264265```python266# Organize data hierarchically267namespaces = [268# User data269["users", "user-123", "profile"],270["users", "user-123", "preferences"],271["users", "user-123", "sessions"],272273# Application data274["application", "config", "production"],275["application", "config", "staging"],276["application", "templates", "emails"],277278# Analytics data279["analytics", "2023", "12", "daily"],280["analytics", "2023", "12", "weekly"],281]282283# Store items in different namespaces284for namespace in namespaces:285await client.store.put_item(286value={"created": "2023-12-01", "type": namespace[-1]},287namespace=namespace,288key="metadata"289)290```291292### Search Operations293294```python295# Search user conversations296user_conversations = await client.store.search_items(297namespace_prefix=["conversations", "user-123"],298query="greeting",299limit=20300)301302print(f"Found {user_conversations['total']} conversations")303for item in user_conversations["items"]:304print(f" {item['key']}: {item['value']['summary']}")305306# Search with filters307recent_conversations = await client.store.search_items(308namespace_prefix=["conversations"],309filter={"date": "2023-12-01", "message_count": {"$gt": 5}},310limit=50311)312313# Search application configs314configs = await client.store.search_items(315namespace_prefix=["application", "config"],316query="production OR staging"317)318```319320### Namespace Management321322```python323# List all user namespaces324user_namespaces = await client.store.list_namespaces(325prefix=["users"],326max_depth=3327)328329print("User namespaces:")330for ns in user_namespaces["namespaces"]:331print(f" {'/'.join(ns)}")332333# List application namespaces334app_namespaces = await client.store.list_namespaces(335prefix=["application"]336)337338# Get all top-level namespaces339all_namespaces = await client.store.list_namespaces(max_depth=1)340```341342### Session & Cache Management343344```python345# Store session data346session_data = {347"user_id": "user-123",348"login_time": "2023-12-01T10:00:00Z",349"permissions": ["read", "write"],350"temporary_data": {"cart_items": [], "form_state": {}}351}352353await client.store.put_item(354value=session_data,355namespace=["sessions", "active"],356key="session-abc123",357index={"user_id": "user-123", "active": True}358)359360# Cache frequently accessed data361cache_data = {362"computed_result": [1, 2, 3, 4, 5],363"computation_time": 0.5,364"expires_at": "2023-12-01T11:00:00Z"365}366367await client.store.put_item(368value=cache_data,369namespace=["cache", "computations"],370key="fibonacci-100",371index={"expires_at": "2023-12-01T11:00:00Z"}372)373```374375### Thread-Shared Memory376377```python378# Store shared state across multiple threads379shared_state = {380"active_users": ["user-123", "user-456"],381"global_config": {"maintenance_mode": False},382"counters": {"api_calls": 1000, "errors": 5}383}384385await client.store.put_item(386value=shared_state,387namespace=["global", "runtime"],388key="current_state"389)390391# Access from any thread392current_state = await client.store.get_item(393namespace=["global", "runtime"],394key="current_state"395)396397# Update counters atomically (read-modify-write pattern)398state = current_state["value"]399state["counters"]["api_calls"] += 1400401await client.store.put_item(402value=state,403namespace=["global", "runtime"],404key="current_state"405)406```407408### Cleanup Operations409410```python411# Find and delete expired items412expired_items = await client.store.search_items(413namespace_prefix=["cache"],414filter={"expires_at": {"$lt": "2023-12-01T10:00:00Z"}}415)416417for item in expired_items["items"]:418await client.store.delete_item(419namespace=item["namespace"],420key=item["key"]421)422423# Delete user data424user_namespaces = await client.store.list_namespaces(425prefix=["users", "user-123"]426)427428# Delete all items in user namespaces (requires iteration)429for namespace in user_namespaces["namespaces"]:430# Note: You would need to search and delete individual items431# as there's no bulk delete operation shown in the API432items = await client.store.search_items(433namespace_prefix=namespace,434limit=1000435)436437for item in items["items"]:438await client.store.delete_item(439namespace=item["namespace"],440key=item["key"]441)442```