langgraph-checkpoint-cloudflare-d1 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- langgraph_checkpoint_cloudflare_d1-0.1.0/PKG-INFO +215 -0
- langgraph_checkpoint_cloudflare_d1-0.1.0/README.md +194 -0
- langgraph_checkpoint_cloudflare_d1-0.1.0/langgraph_checkpoint_cloudflare_d1/__init__.py +698 -0
- langgraph_checkpoint_cloudflare_d1-0.1.0/langgraph_checkpoint_cloudflare_d1/aio.py +757 -0
- langgraph_checkpoint_cloudflare_d1-0.1.0/langgraph_checkpoint_cloudflare_d1/models.py +64 -0
- langgraph_checkpoint_cloudflare_d1-0.1.0/langgraph_checkpoint_cloudflare_d1/py.typed +0 -0
- langgraph_checkpoint_cloudflare_d1-0.1.0/langgraph_checkpoint_cloudflare_d1/utils.py +76 -0
- langgraph_checkpoint_cloudflare_d1-0.1.0/pyproject.toml +41 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: langgraph-checkpoint-cloudflare-d1
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LangGraph Checkpoint implementation for Cloudflare D1
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.9,<4.0
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Requires-Dist: httpx (>=0.24.1)
|
|
15
|
+
Requires-Dist: langchain-core (>=0.1.16)
|
|
16
|
+
Requires-Dist: langgraph (>=0.0.18)
|
|
17
|
+
Requires-Dist: pydantic (>=1.10.0,<3.0.0)
|
|
18
|
+
Requires-Dist: requests (>=2.31.0)
|
|
19
|
+
Project-URL: Repository, https://github.com/cloudflare/langchain-cloudflare
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Usage
|
|
23
|
+
|
|
24
|
+
This package provides both synchronous and asynchronous interfaces for saving and retrieving LangGraph checkpoints in Cloudflare D1.
|
|
25
|
+
|
|
26
|
+
# Synchronous
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from langgraph_checkpoint_cloudflare_d1 import CloudflareD1Saver
|
|
30
|
+
|
|
31
|
+
# Cloudflare credentials
|
|
32
|
+
account_id = "your-cloudflare-account-id"
|
|
33
|
+
database_id = "your-d1-database-id"
|
|
34
|
+
api_token = "your-cloudflare-api-token"
|
|
35
|
+
|
|
36
|
+
# Configuration for checkpoint operations
|
|
37
|
+
write_config = {"configurable": {"thread_id": "1", "checkpoint_ns": ""}}
|
|
38
|
+
read_config = {"configurable": {"thread_id": "1"}}
|
|
39
|
+
|
|
40
|
+
# Initialize the saver with proper credentials
|
|
41
|
+
with CloudflareD1Saver(
|
|
42
|
+
account_id=account_id,
|
|
43
|
+
database_id=database_id,
|
|
44
|
+
api_token=api_token
|
|
45
|
+
) as checkpointer:
|
|
46
|
+
# Setup the database tables (idempotent operation)
|
|
47
|
+
checkpointer.setup()
|
|
48
|
+
|
|
49
|
+
# Sample checkpoint data
|
|
50
|
+
checkpoint = {
|
|
51
|
+
"v": 2,
|
|
52
|
+
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
53
|
+
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
54
|
+
"channel_values": {
|
|
55
|
+
"my_key": "meow",
|
|
56
|
+
"node": "node"
|
|
57
|
+
},
|
|
58
|
+
"channel_versions": {
|
|
59
|
+
"__start__": 2,
|
|
60
|
+
"my_key": 3,
|
|
61
|
+
"start:node": 3,
|
|
62
|
+
"node": 3
|
|
63
|
+
},
|
|
64
|
+
"versions_seen": {
|
|
65
|
+
"__input__": {},
|
|
66
|
+
"__start__": {
|
|
67
|
+
"__start__": 1
|
|
68
|
+
},
|
|
69
|
+
"node": {
|
|
70
|
+
"start:node": 2
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"pending_sends": [],
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Store checkpoint
|
|
77
|
+
checkpointer.put(write_config, checkpoint, {}, {})
|
|
78
|
+
|
|
79
|
+
# Load checkpoint
|
|
80
|
+
loaded_checkpoint = checkpointer.get_tuple(read_config)
|
|
81
|
+
|
|
82
|
+
# List checkpoints
|
|
83
|
+
checkpoints = list(checkpointer.list(read_config))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
You can also use a connection string to initialize the saver:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from langgraph_checkpoint_cloudflare_d1 import CloudflareD1Saver
|
|
90
|
+
|
|
91
|
+
# Connection string format: "account_id:database_id:api_token"
|
|
92
|
+
conn_string = "your-account-id:your-database-id:your-api-token"
|
|
93
|
+
|
|
94
|
+
# Use the saver with a connection string
|
|
95
|
+
with CloudflareD1Saver.from_conn_string(conn_string) as checkpointer:
|
|
96
|
+
# Your code here
|
|
97
|
+
checkpointer.setup()
|
|
98
|
+
# ...
|
|
99
|
+
|
|
100
|
+
# Async
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from langgraph_checkpoint_cloudflare_d1 import AsyncCloudflareD1Saver
|
|
104
|
+
import asyncio
|
|
105
|
+
|
|
106
|
+
async def main():
|
|
107
|
+
# Cloudflare credentials
|
|
108
|
+
account_id = "your-cloudflare-account-id"
|
|
109
|
+
database_id = "your-d1-database-id"
|
|
110
|
+
api_token = "your-cloudflare-api-token"
|
|
111
|
+
|
|
112
|
+
# Configuration for checkpoint operations
|
|
113
|
+
write_config = {"configurable": {"thread_id": "1", "checkpoint_ns": ""}}
|
|
114
|
+
read_config = {"configurable": {"thread_id": "1"}}
|
|
115
|
+
|
|
116
|
+
# Initialize the async saver with proper credentials
|
|
117
|
+
async with AsyncCloudflareD1Saver(
|
|
118
|
+
account_id=account_id,
|
|
119
|
+
database_id=database_id,
|
|
120
|
+
api_token=api_token
|
|
121
|
+
) as checkpointer:
|
|
122
|
+
# Sample checkpoint data
|
|
123
|
+
checkpoint = {
|
|
124
|
+
"v": 2,
|
|
125
|
+
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
126
|
+
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
127
|
+
"channel_values": {
|
|
128
|
+
"my_key": "meow",
|
|
129
|
+
"node": "node"
|
|
130
|
+
},
|
|
131
|
+
"channel_versions": {
|
|
132
|
+
"__start__": 2,
|
|
133
|
+
"my_key": 3,
|
|
134
|
+
"start:node": 3,
|
|
135
|
+
"node": 3
|
|
136
|
+
},
|
|
137
|
+
"versions_seen": {
|
|
138
|
+
"__input__": {},
|
|
139
|
+
"__start__": {
|
|
140
|
+
"__start__": 1
|
|
141
|
+
},
|
|
142
|
+
"node": {
|
|
143
|
+
"start:node": 2
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"pending_sends": [],
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# Setup happens automatically but can be called explicitly
|
|
150
|
+
await checkpointer.setup()
|
|
151
|
+
|
|
152
|
+
# Store checkpoint
|
|
153
|
+
await checkpointer.put(write_config, checkpoint, {}, {})
|
|
154
|
+
|
|
155
|
+
# Load checkpoint
|
|
156
|
+
loaded_checkpoint = await checkpointer.get_tuple(read_config)
|
|
157
|
+
|
|
158
|
+
# List checkpoints
|
|
159
|
+
checkpoints = [cp async for cp in checkpointer.list(read_config)]
|
|
160
|
+
|
|
161
|
+
# For local execution
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
asyncio.run(main())
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
You can also use a connection string to initialize the async saver:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from langgraph_checkpoint_cloudflare_d1 import AsyncCloudflareD1Saver
|
|
170
|
+
import asyncio
|
|
171
|
+
|
|
172
|
+
async def main():
|
|
173
|
+
# Connection string format: "account_id:database_id:api_token"
|
|
174
|
+
conn_string = "your-account-id:your-database-id:your-api-token"
|
|
175
|
+
|
|
176
|
+
# Use the async saver with a connection string
|
|
177
|
+
async with await AsyncCloudflareD1Saver.from_conn_string(conn_string) as checkpointer:
|
|
178
|
+
# Your code here
|
|
179
|
+
# Setup is automatic when using context manager
|
|
180
|
+
# ...
|
|
181
|
+
|
|
182
|
+
# For local execution
|
|
183
|
+
if __name__ == "__main__":
|
|
184
|
+
asyncio.run(main())
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Integration with LangGraph
|
|
188
|
+
|
|
189
|
+
To use this checkpoint saver with LangGraph, you can pass it when compiling your graph:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
from langgraph.graph import StateGraph
|
|
193
|
+
from langgraph_checkpoint_cloudflare_d1 import CloudflareD1Saver
|
|
194
|
+
|
|
195
|
+
# Create a simple graph
|
|
196
|
+
builder = StateGraph(int)
|
|
197
|
+
builder.add_node("add_one", lambda x: x + 1)
|
|
198
|
+
builder.set_entry_point("add_one")
|
|
199
|
+
builder.set_finish_point("add_one")
|
|
200
|
+
|
|
201
|
+
# Create the checkpoint saver
|
|
202
|
+
checkpointer = CloudflareD1Saver(
|
|
203
|
+
account_id="your-account-id",
|
|
204
|
+
database_id="your-database-id",
|
|
205
|
+
api_token="your-api-token"
|
|
206
|
+
)
|
|
207
|
+
checkpointer.setup() # Create necessary tables
|
|
208
|
+
|
|
209
|
+
# Compile the graph with the checkpointer
|
|
210
|
+
graph = builder.compile(checkpointer=checkpointer)
|
|
211
|
+
|
|
212
|
+
# Use the graph with checkpointing
|
|
213
|
+
config = {"configurable": {"thread_id": "my-thread-1"}}
|
|
214
|
+
result = graph.invoke(3, config)
|
|
215
|
+
```
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Usage
|
|
2
|
+
|
|
3
|
+
This package provides both synchronous and asynchronous interfaces for saving and retrieving LangGraph checkpoints in Cloudflare D1.
|
|
4
|
+
|
|
5
|
+
# Synchronous
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from langgraph_checkpoint_cloudflare_d1 import CloudflareD1Saver
|
|
9
|
+
|
|
10
|
+
# Cloudflare credentials
|
|
11
|
+
account_id = "your-cloudflare-account-id"
|
|
12
|
+
database_id = "your-d1-database-id"
|
|
13
|
+
api_token = "your-cloudflare-api-token"
|
|
14
|
+
|
|
15
|
+
# Configuration for checkpoint operations
|
|
16
|
+
write_config = {"configurable": {"thread_id": "1", "checkpoint_ns": ""}}
|
|
17
|
+
read_config = {"configurable": {"thread_id": "1"}}
|
|
18
|
+
|
|
19
|
+
# Initialize the saver with proper credentials
|
|
20
|
+
with CloudflareD1Saver(
|
|
21
|
+
account_id=account_id,
|
|
22
|
+
database_id=database_id,
|
|
23
|
+
api_token=api_token
|
|
24
|
+
) as checkpointer:
|
|
25
|
+
# Setup the database tables (idempotent operation)
|
|
26
|
+
checkpointer.setup()
|
|
27
|
+
|
|
28
|
+
# Sample checkpoint data
|
|
29
|
+
checkpoint = {
|
|
30
|
+
"v": 2,
|
|
31
|
+
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
32
|
+
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
33
|
+
"channel_values": {
|
|
34
|
+
"my_key": "meow",
|
|
35
|
+
"node": "node"
|
|
36
|
+
},
|
|
37
|
+
"channel_versions": {
|
|
38
|
+
"__start__": 2,
|
|
39
|
+
"my_key": 3,
|
|
40
|
+
"start:node": 3,
|
|
41
|
+
"node": 3
|
|
42
|
+
},
|
|
43
|
+
"versions_seen": {
|
|
44
|
+
"__input__": {},
|
|
45
|
+
"__start__": {
|
|
46
|
+
"__start__": 1
|
|
47
|
+
},
|
|
48
|
+
"node": {
|
|
49
|
+
"start:node": 2
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"pending_sends": [],
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Store checkpoint
|
|
56
|
+
checkpointer.put(write_config, checkpoint, {}, {})
|
|
57
|
+
|
|
58
|
+
# Load checkpoint
|
|
59
|
+
loaded_checkpoint = checkpointer.get_tuple(read_config)
|
|
60
|
+
|
|
61
|
+
# List checkpoints
|
|
62
|
+
checkpoints = list(checkpointer.list(read_config))
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
You can also use a connection string to initialize the saver:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from langgraph_checkpoint_cloudflare_d1 import CloudflareD1Saver
|
|
69
|
+
|
|
70
|
+
# Connection string format: "account_id:database_id:api_token"
|
|
71
|
+
conn_string = "your-account-id:your-database-id:your-api-token"
|
|
72
|
+
|
|
73
|
+
# Use the saver with a connection string
|
|
74
|
+
with CloudflareD1Saver.from_conn_string(conn_string) as checkpointer:
|
|
75
|
+
# Your code here
|
|
76
|
+
checkpointer.setup()
|
|
77
|
+
# ...
|
|
78
|
+
|
|
79
|
+
# Async
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from langgraph_checkpoint_cloudflare_d1 import AsyncCloudflareD1Saver
|
|
83
|
+
import asyncio
|
|
84
|
+
|
|
85
|
+
async def main():
|
|
86
|
+
# Cloudflare credentials
|
|
87
|
+
account_id = "your-cloudflare-account-id"
|
|
88
|
+
database_id = "your-d1-database-id"
|
|
89
|
+
api_token = "your-cloudflare-api-token"
|
|
90
|
+
|
|
91
|
+
# Configuration for checkpoint operations
|
|
92
|
+
write_config = {"configurable": {"thread_id": "1", "checkpoint_ns": ""}}
|
|
93
|
+
read_config = {"configurable": {"thread_id": "1"}}
|
|
94
|
+
|
|
95
|
+
# Initialize the async saver with proper credentials
|
|
96
|
+
async with AsyncCloudflareD1Saver(
|
|
97
|
+
account_id=account_id,
|
|
98
|
+
database_id=database_id,
|
|
99
|
+
api_token=api_token
|
|
100
|
+
) as checkpointer:
|
|
101
|
+
# Sample checkpoint data
|
|
102
|
+
checkpoint = {
|
|
103
|
+
"v": 2,
|
|
104
|
+
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
105
|
+
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
106
|
+
"channel_values": {
|
|
107
|
+
"my_key": "meow",
|
|
108
|
+
"node": "node"
|
|
109
|
+
},
|
|
110
|
+
"channel_versions": {
|
|
111
|
+
"__start__": 2,
|
|
112
|
+
"my_key": 3,
|
|
113
|
+
"start:node": 3,
|
|
114
|
+
"node": 3
|
|
115
|
+
},
|
|
116
|
+
"versions_seen": {
|
|
117
|
+
"__input__": {},
|
|
118
|
+
"__start__": {
|
|
119
|
+
"__start__": 1
|
|
120
|
+
},
|
|
121
|
+
"node": {
|
|
122
|
+
"start:node": 2
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"pending_sends": [],
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# Setup happens automatically but can be called explicitly
|
|
129
|
+
await checkpointer.setup()
|
|
130
|
+
|
|
131
|
+
# Store checkpoint
|
|
132
|
+
await checkpointer.put(write_config, checkpoint, {}, {})
|
|
133
|
+
|
|
134
|
+
# Load checkpoint
|
|
135
|
+
loaded_checkpoint = await checkpointer.get_tuple(read_config)
|
|
136
|
+
|
|
137
|
+
# List checkpoints
|
|
138
|
+
checkpoints = [cp async for cp in checkpointer.list(read_config)]
|
|
139
|
+
|
|
140
|
+
# For local execution
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
asyncio.run(main())
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
You can also use a connection string to initialize the async saver:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from langgraph_checkpoint_cloudflare_d1 import AsyncCloudflareD1Saver
|
|
149
|
+
import asyncio
|
|
150
|
+
|
|
151
|
+
async def main():
|
|
152
|
+
# Connection string format: "account_id:database_id:api_token"
|
|
153
|
+
conn_string = "your-account-id:your-database-id:your-api-token"
|
|
154
|
+
|
|
155
|
+
# Use the async saver with a connection string
|
|
156
|
+
async with await AsyncCloudflareD1Saver.from_conn_string(conn_string) as checkpointer:
|
|
157
|
+
# Your code here
|
|
158
|
+
# Setup is automatic when using context manager
|
|
159
|
+
# ...
|
|
160
|
+
|
|
161
|
+
# For local execution
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
asyncio.run(main())
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Integration with LangGraph
|
|
167
|
+
|
|
168
|
+
To use this checkpoint saver with LangGraph, you can pass it when compiling your graph:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from langgraph.graph import StateGraph
|
|
172
|
+
from langgraph_checkpoint_cloudflare_d1 import CloudflareD1Saver
|
|
173
|
+
|
|
174
|
+
# Create a simple graph
|
|
175
|
+
builder = StateGraph(int)
|
|
176
|
+
builder.add_node("add_one", lambda x: x + 1)
|
|
177
|
+
builder.set_entry_point("add_one")
|
|
178
|
+
builder.set_finish_point("add_one")
|
|
179
|
+
|
|
180
|
+
# Create the checkpoint saver
|
|
181
|
+
checkpointer = CloudflareD1Saver(
|
|
182
|
+
account_id="your-account-id",
|
|
183
|
+
database_id="your-database-id",
|
|
184
|
+
api_token="your-api-token"
|
|
185
|
+
)
|
|
186
|
+
checkpointer.setup() # Create necessary tables
|
|
187
|
+
|
|
188
|
+
# Compile the graph with the checkpointer
|
|
189
|
+
graph = builder.compile(checkpointer=checkpointer)
|
|
190
|
+
|
|
191
|
+
# Use the graph with checkpointing
|
|
192
|
+
config = {"configurable": {"thread_id": "my-thread-1"}}
|
|
193
|
+
result = graph.invoke(3, config)
|
|
194
|
+
```
|