pypi-langgraph-sdk

Description
Python SDK for interacting with the LangGraph Platform REST API to build and manage AI assistants and conversational workflows
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/pypi-langgraph-sdk@0.2.0

persistent-storage.md docs/

1
# Persistent Storage
2
3
Cross-thread persistent memory system for storing and retrieving documents, configuration, and application data with namespacing, search capabilities, and flexible data organization.
4
5
## Capabilities
6
7
### Item Storage Operations
8
9
Store, retrieve, update, and delete items in the persistent storage system with flexible key-value organization.
10
11
```python { .api }
12
from collections.abc import Mapping, Sequence
13
from typing import Any, Literal
14
from langgraph_sdk.schema import Item, QueryParamTypes
15
16
# Via client.store
17
async def put_item(
18
namespace: Sequence[str],
19
/,
20
key: str,
21
value: Mapping[str, Any],
22
index: Literal[False] | list[str] | None = None,
23
ttl: int | None = None,
24
headers: Mapping[str, str] | None = None,
25
params: QueryParamTypes | None = None,
26
) -> None:
27
"""
28
Store an item.
29
30
Args:
31
namespace: The namespace to store the item in.
32
key: The unique identifier for the item.
33
value: The value to store.
34
index: Whether to index the item. If a list is provided, only the specified fields will be indexed.
35
ttl: Time-to-live for the item in seconds.
36
headers: Optional custom headers to include with the request.
37
params: Optional query parameters to include with the request.
38
"""
39
40
async def get_item(
41
namespace: Sequence[str],
42
/,
43
key: str,
44
*,
45
refresh_ttl: bool | None = None,
46
headers: Mapping[str, str] | None = None,
47
params: QueryParamTypes | None = None,
48
) -> Item:
49
"""
50
Retrieve a single item.
51
52
Args:
53
namespace: The namespace to retrieve the item from.
54
key: The unique identifier for the item.
55
refresh_ttl: Whether to refresh the item's TTL.
56
headers: Optional custom headers to include with the request.
57
params: Optional query parameters to include with the request.
58
59
Returns:
60
Item: The retrieved item.
61
"""
62
63
async def delete_item(
64
namespace: Sequence[str],
65
/,
66
key: str,
67
headers: Mapping[str, str] | None = None,
68
params: QueryParamTypes | None = None,
69
) -> None:
70
"""
71
Delete an item.
72
73
Args:
74
namespace: The namespace to delete the item from.
75
key: The unique identifier for the item.
76
headers: Optional custom headers to include with the request.
77
params: Optional query parameters to include with the request.
78
"""
79
```
80
81
### Search & Discovery
82
83
Search for items across namespaces with text queries, filtering, and pagination.
84
85
```python { .api }
86
from langgraph_sdk.schema import SearchItemsResponse, ListNamespaceResponse
87
88
async def search_items(
89
namespace_prefix: Sequence[str],
90
/,
91
filter: Mapping[str, Any] | None = None,
92
limit: int = 10,
93
offset: int = 0,
94
query: str | None = None,
95
refresh_ttl: bool | None = None,
96
headers: Mapping[str, str] | None = None,
97
params: QueryParamTypes | None = None,
98
) -> SearchItemsResponse:
99
"""
100
Search for items in the store.
101
102
Args:
103
namespace_prefix: The namespace prefix to search under.
104
filter: Filtering criteria for the search.
105
limit: Maximum number of items to return (default is 10).
106
offset: Number of items to skip before returning results (default is 0).
107
query: Optional query string for full-text search.
108
refresh_ttl: Whether to refresh the TTL of found items.
109
headers: Optional custom headers to include with the request.
110
params: Optional query parameters to include with the request.
111
112
Returns:
113
SearchItemsResponse: The search results.
114
"""
115
116
async def list_namespaces(
117
*,
118
prefix: Sequence[str] | None = None,
119
suffix: Sequence[str] | None = None,
120
max_depth: int | None = None,
121
limit: int = 100,
122
offset: int = 0,
123
headers: Mapping[str, str] | None = None,
124
params: QueryParamTypes | None = None,
125
) -> ListNamespaceResponse:
126
"""
127
List namespaces with optional match conditions.
128
129
Args:
130
prefix: Optional list of strings representing the prefix to filter namespaces.
131
suffix: Optional list of strings representing the suffix to filter namespaces.
132
max_depth: Optional integer specifying the maximum depth of namespaces to return.
133
limit: Maximum number of namespaces to return (default is 100).
134
offset: Number of namespaces to skip before returning results (default is 0).
135
headers: Optional custom headers to include with the request.
136
params: Optional query parameters to include with the request.
137
138
Returns:
139
ListNamespaceResponse: The list of namespaces.
140
"""
141
```
142
143
## Types
144
145
```python { .api }
146
class Item(TypedDict):
147
"""Stored item with metadata."""
148
namespace: list[str]
149
key: str
150
value: dict
151
created_at: str
152
updated_at: str
153
index: dict
154
155
class SearchItem(TypedDict):
156
"""Search result item with relevance score."""
157
namespace: list[str]
158
key: str
159
value: dict
160
created_at: str
161
updated_at: str
162
index: dict
163
score: float
164
165
class SearchItemsResponse(TypedDict):
166
"""Search results with pagination."""
167
items: list[SearchItem]
168
total: int
169
limit: int
170
offset: int
171
172
class ListNamespaceResponse(TypedDict):
173
"""Namespace listing response."""
174
namespaces: list[list[str]]
175
total: int
176
limit: int
177
offset: int
178
```
179
180
## Usage Examples
181
182
### Basic Item Operations
183
184
```python
185
# Store user preferences
186
user_prefs = {
187
"theme": "dark",
188
"language": "en",
189
"notifications": True,
190
"timezone": "America/New_York"
191
}
192
193
await client.store.put_item(
194
value=user_prefs,
195
namespace=["users", "user-123", "preferences"],
196
key="ui_settings"
197
)
198
199
# Retrieve user preferences
200
prefs = await client.store.get_item(
201
namespace=["users", "user-123", "preferences"],
202
key="ui_settings"
203
)
204
205
print(f"User theme: {prefs['value']['theme']}")
206
207
# Update preferences (store overwrites)
208
updated_prefs = prefs["value"].copy()
209
updated_prefs["theme"] = "light"
210
211
await client.store.put_item(
212
value=updated_prefs,
213
namespace=["users", "user-123", "preferences"],
214
key="ui_settings"
215
)
216
```
217
218
### Document Storage
219
220
```python
221
# Store conversation history
222
conversation = {
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
}
230
231
await client.store.put_item(
232
value=conversation,
233
namespace=["conversations", "user-123"],
234
key="conv-2023-12-01",
235
index={
236
"participants": ["user-123", "assistant-456"],
237
"date": "2023-12-01",
238
"message_count": 2
239
}
240
)
241
242
# Store configuration
243
app_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
}
255
256
await client.store.put_item(
257
value=app_config,
258
namespace=["application", "config"],
259
key="production"
260
)
261
```
262
263
### Hierarchical Organization
264
265
```python
266
# Organize data hierarchically
267
namespaces = [
268
# User data
269
["users", "user-123", "profile"],
270
["users", "user-123", "preferences"],
271
["users", "user-123", "sessions"],
272
273
# Application data
274
["application", "config", "production"],
275
["application", "config", "staging"],
276
["application", "templates", "emails"],
277
278
# Analytics data
279
["analytics", "2023", "12", "daily"],
280
["analytics", "2023", "12", "weekly"],
281
]
282
283
# Store items in different namespaces
284
for namespace in namespaces:
285
await client.store.put_item(
286
value={"created": "2023-12-01", "type": namespace[-1]},
287
namespace=namespace,
288
key="metadata"
289
)
290
```
291
292
### Search Operations
293
294
```python
295
# Search user conversations
296
user_conversations = await client.store.search_items(
297
namespace_prefix=["conversations", "user-123"],
298
query="greeting",
299
limit=20
300
)
301
302
print(f"Found {user_conversations['total']} conversations")
303
for item in user_conversations["items"]:
304
print(f" {item['key']}: {item['value']['summary']}")
305
306
# Search with filters
307
recent_conversations = await client.store.search_items(
308
namespace_prefix=["conversations"],
309
filter={"date": "2023-12-01", "message_count": {"$gt": 5}},
310
limit=50
311
)
312
313
# Search application configs
314
configs = await client.store.search_items(
315
namespace_prefix=["application", "config"],
316
query="production OR staging"
317
)
318
```
319
320
### Namespace Management
321
322
```python
323
# List all user namespaces
324
user_namespaces = await client.store.list_namespaces(
325
prefix=["users"],
326
max_depth=3
327
)
328
329
print("User namespaces:")
330
for ns in user_namespaces["namespaces"]:
331
print(f" {'/'.join(ns)}")
332
333
# List application namespaces
334
app_namespaces = await client.store.list_namespaces(
335
prefix=["application"]
336
)
337
338
# Get all top-level namespaces
339
all_namespaces = await client.store.list_namespaces(max_depth=1)
340
```
341
342
### Session & Cache Management
343
344
```python
345
# Store session data
346
session_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
}
352
353
await client.store.put_item(
354
value=session_data,
355
namespace=["sessions", "active"],
356
key="session-abc123",
357
index={"user_id": "user-123", "active": True}
358
)
359
360
# Cache frequently accessed data
361
cache_data = {
362
"computed_result": [1, 2, 3, 4, 5],
363
"computation_time": 0.5,
364
"expires_at": "2023-12-01T11:00:00Z"
365
}
366
367
await client.store.put_item(
368
value=cache_data,
369
namespace=["cache", "computations"],
370
key="fibonacci-100",
371
index={"expires_at": "2023-12-01T11:00:00Z"}
372
)
373
```
374
375
### Thread-Shared Memory
376
377
```python
378
# Store shared state across multiple threads
379
shared_state = {
380
"active_users": ["user-123", "user-456"],
381
"global_config": {"maintenance_mode": False},
382
"counters": {"api_calls": 1000, "errors": 5}
383
}
384
385
await client.store.put_item(
386
value=shared_state,
387
namespace=["global", "runtime"],
388
key="current_state"
389
)
390
391
# Access from any thread
392
current_state = await client.store.get_item(
393
namespace=["global", "runtime"],
394
key="current_state"
395
)
396
397
# Update counters atomically (read-modify-write pattern)
398
state = current_state["value"]
399
state["counters"]["api_calls"] += 1
400
401
await client.store.put_item(
402
value=state,
403
namespace=["global", "runtime"],
404
key="current_state"
405
)
406
```
407
408
### Cleanup Operations
409
410
```python
411
# Find and delete expired items
412
expired_items = await client.store.search_items(
413
namespace_prefix=["cache"],
414
filter={"expires_at": {"$lt": "2023-12-01T10:00:00Z"}}
415
)
416
417
for item in expired_items["items"]:
418
await client.store.delete_item(
419
namespace=item["namespace"],
420
key=item["key"]
421
)
422
423
# Delete user data
424
user_namespaces = await client.store.list_namespaces(
425
prefix=["users", "user-123"]
426
)
427
428
# Delete all items in user namespaces (requires iteration)
429
for namespace in user_namespaces["namespaces"]:
430
# Note: You would need to search and delete individual items
431
# as there's no bulk delete operation shown in the API
432
items = await client.store.search_items(
433
namespace_prefix=namespace,
434
limit=1000
435
)
436
437
for item in items["items"]:
438
await client.store.delete_item(
439
namespace=item["namespace"],
440
key=item["key"]
441
)
442
```