langgraph-checkpoint-postgres 2.0.18__tar.gz → 2.0.20__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.
Files changed (14) hide show
  1. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/PKG-INFO +6 -6
  2. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/README.md +2 -2
  3. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/checkpoint/postgres/__init__.py +23 -0
  4. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/checkpoint/postgres/aio.py +48 -0
  5. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/checkpoint/postgres/shallow.py +14 -1
  6. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/store/postgres/aio.py +1 -1
  7. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/store/postgres/base.py +1 -1
  8. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/pyproject.toml +2 -2
  9. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/checkpoint/postgres/_ainternal.py +0 -0
  10. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/checkpoint/postgres/_internal.py +0 -0
  11. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/checkpoint/postgres/base.py +0 -0
  12. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/checkpoint/postgres/py.typed +0 -0
  13. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/store/postgres/__init__.py +0 -0
  14. {langgraph_checkpoint_postgres-2.0.18 → langgraph_checkpoint_postgres-2.0.20}/langgraph/store/postgres/py.typed +0 -0
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: langgraph-checkpoint-postgres
3
- Version: 2.0.18
3
+ Version: 2.0.20
4
4
  Summary: Library with a Postgres implementation of LangGraph checkpoint saver.
5
- Home-page: https://www.github.com/langchain-ai/langgraph
6
5
  License: MIT
7
6
  Requires-Python: >=3.9.0,<4.0.0
8
7
  Classifier: License :: OSI Approved :: MIT License
@@ -11,7 +10,8 @@ Classifier: Programming Language :: Python :: 3.9
11
10
  Classifier: Programming Language :: Python :: 3.10
12
11
  Classifier: Programming Language :: Python :: 3.11
13
12
  Classifier: Programming Language :: Python :: 3.12
14
- Requires-Dist: langgraph-checkpoint (>=2.0.15,<3.0.0)
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Requires-Dist: langgraph-checkpoint (>=2.0.21,<3.0.0)
15
15
  Requires-Dist: orjson (>=3.10.1)
16
16
  Requires-Dist: psycopg (>=3.2.0,<4.0.0)
17
17
  Requires-Dist: psycopg-pool (>=3.2.0,<4.0.0)
@@ -45,7 +45,7 @@ with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
45
45
  # call .setup() the first time you're using the checkpointer
46
46
  checkpointer.setup()
47
47
  checkpoint = {
48
- "v": 1,
48
+ "v": 2,
49
49
  "ts": "2024-07-31T20:14:19.804150+00:00",
50
50
  "id": "1ef4f797-8335-6428-8001-8a1503f9b875",
51
51
  "channel_values": {
@@ -87,7 +87,7 @@ from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
87
87
 
88
88
  async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
89
89
  checkpoint = {
90
- "v": 1,
90
+ "v": 2,
91
91
  "ts": "2024-07-31T20:14:19.804150+00:00",
92
92
  "id": "1ef4f797-8335-6428-8001-8a1503f9b875",
93
93
  "channel_values": {
@@ -25,7 +25,7 @@ with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
25
25
  # call .setup() the first time you're using the checkpointer
26
26
  checkpointer.setup()
27
27
  checkpoint = {
28
- "v": 1,
28
+ "v": 2,
29
29
  "ts": "2024-07-31T20:14:19.804150+00:00",
30
30
  "id": "1ef4f797-8335-6428-8001-8a1503f9b875",
31
31
  "channel_values": {
@@ -67,7 +67,7 @@ from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
67
67
 
68
68
  async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
69
69
  checkpoint = {
70
- "v": 1,
70
+ "v": 2,
71
71
  "ts": "2024-07-31T20:14:19.804150+00:00",
72
72
  "id": "1ef4f797-8335-6428-8001-8a1503f9b875",
73
73
  "channel_values": {
@@ -357,6 +357,29 @@ class PostgresSaver(BasePostgresSaver):
357
357
  ),
358
358
  )
359
359
 
360
+ def delete_thread(self, thread_id: str) -> None:
361
+ """Delete all checkpoints and writes associated with a thread ID.
362
+
363
+ Args:
364
+ thread_id (str): The thread ID to delete.
365
+
366
+ Returns:
367
+ None
368
+ """
369
+ with self._cursor(pipeline=True) as cur:
370
+ cur.execute(
371
+ "DELETE FROM checkpoints WHERE thread_id = %s",
372
+ (str(thread_id),),
373
+ )
374
+ cur.execute(
375
+ "DELETE FROM checkpoint_blobs WHERE thread_id = %s",
376
+ (str(thread_id),),
377
+ )
378
+ cur.execute(
379
+ "DELETE FROM checkpoint_writes WHERE thread_id = %s",
380
+ (str(thread_id),),
381
+ )
382
+
360
383
  @contextmanager
361
384
  def _cursor(self, *, pipeline: bool = False) -> Iterator[Cursor[DictRow]]:
362
385
  """Create a database cursor as a context manager.
@@ -314,6 +314,29 @@ class AsyncPostgresSaver(BasePostgresSaver):
314
314
  async with self._cursor(pipeline=True) as cur:
315
315
  await cur.executemany(query, params)
316
316
 
317
+ async def adelete_thread(self, thread_id: str) -> None:
318
+ """Delete all checkpoints and writes associated with a thread ID.
319
+
320
+ Args:
321
+ thread_id (str): The thread ID to delete.
322
+
323
+ Returns:
324
+ None
325
+ """
326
+ async with self._cursor(pipeline=True) as cur:
327
+ await cur.execute(
328
+ "DELETE FROM checkpoints WHERE thread_id = %s",
329
+ (str(thread_id),),
330
+ )
331
+ await cur.execute(
332
+ "DELETE FROM checkpoint_blobs WHERE thread_id = %s",
333
+ (str(thread_id),),
334
+ )
335
+ await cur.execute(
336
+ "DELETE FROM checkpoint_writes WHERE thread_id = %s",
337
+ (str(thread_id),),
338
+ )
339
+
317
340
  @asynccontextmanager
318
341
  async def _cursor(
319
342
  self, *, pipeline: bool = False
@@ -481,5 +504,30 @@ class AsyncPostgresSaver(BasePostgresSaver):
481
504
  self.aput_writes(config, writes, task_id, task_path), self.loop
482
505
  ).result()
483
506
 
507
+ def delete_thread(self, thread_id: str) -> None:
508
+ """Delete all checkpoints and writes associated with a thread ID.
509
+
510
+ Args:
511
+ thread_id (str): The thread ID to delete.
512
+
513
+ Returns:
514
+ None
515
+ """
516
+ try:
517
+ # check if we are in the main thread, only bg threads can block
518
+ # we don't check in other methods to avoid the overhead
519
+ if asyncio.get_running_loop() is self.loop:
520
+ raise asyncio.InvalidStateError(
521
+ "Synchronous calls to AsyncPostgresSaver are only allowed from a "
522
+ "different thread. From the main thread, use the async interface. "
523
+ "For example, use `await checkpointer.aget_tuple(...)` or `await "
524
+ "graph.ainvoke(...)`."
525
+ )
526
+ except RuntimeError:
527
+ pass
528
+ return asyncio.run_coroutine_threadsafe(
529
+ self.adelete_thread(thread_id), self.loop
530
+ ).result()
531
+
484
532
 
485
533
  __all__ = ["AsyncPostgresSaver", "AsyncShallowPostgresSaver", "Conn"]
@@ -1,5 +1,6 @@
1
1
  import asyncio
2
2
  import threading
3
+ import warnings
3
4
  from collections.abc import AsyncIterator, Iterator, Sequence
4
5
  from contextlib import asynccontextmanager, contextmanager
5
6
  from typing import Any, Optional
@@ -150,7 +151,7 @@ def _dump_blobs(
150
151
  checkpoint_ns: str,
151
152
  values: dict[str, Any],
152
153
  versions: ChannelVersions,
153
- ) -> list[tuple[str, str, str, str, str, Optional[bytes]]]:
154
+ ) -> list[tuple[str, str, str, str, Optional[bytes]]]:
154
155
  if not versions:
155
156
  return []
156
157
 
@@ -188,6 +189,12 @@ class ShallowPostgresSaver(BasePostgresSaver):
188
189
  pipe: Optional[Pipeline] = None,
189
190
  serde: Optional[SerializerProtocol] = None,
190
191
  ) -> None:
192
+ warnings.warn(
193
+ "ShallowPostgresSaver is deprecated as of version 2.0.20 and will be removed in 3.0.0. "
194
+ "Use PostgresSaver instead, and invoke the graph with `graph.invoke(..., checkpoint_during=False)`.",
195
+ DeprecationWarning,
196
+ stacklevel=2,
197
+ )
191
198
  super().__init__(serde=serde)
192
199
  if isinstance(conn, ConnectionPool) and pipe is not None:
193
200
  raise ValueError(
@@ -528,6 +535,12 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
528
535
  pipe: Optional[AsyncPipeline] = None,
529
536
  serde: Optional[SerializerProtocol] = None,
530
537
  ) -> None:
538
+ warnings.warn(
539
+ "AsyncShallowPostgresSaver is deprecated as of version 2.0.20 and will be removed in 3.0.0. "
540
+ "Use AsyncPostgresSaver instead, and invoke the graph with `await graph.ainvoke(..., checkpoint_during=False)`.",
541
+ DeprecationWarning,
542
+ stacklevel=2,
543
+ )
531
544
  super().__init__(serde=serde)
532
545
  if isinstance(conn, AsyncConnectionPool) and pipe is not None:
533
546
  raise ValueError(
@@ -78,7 +78,7 @@ class AsyncPostgresStore(AsyncBatchedBaseStore, BasePostgresStore[_ainternal.Con
78
78
  await store.aput(("docs",), "doc3", {"text": "Other guide"}, index=False) # don't index
79
79
 
80
80
  # Search by similarity
81
- results = await store.asearch(("docs",), "programming guides", limit=2)
81
+ results = await store.asearch(("docs",), query="programming guides", limit=2)
82
82
  ```
83
83
 
84
84
  Using connection pooling for better performance:
@@ -684,7 +684,7 @@ class PostgresStore(BaseStore, BasePostgresStore[_pg_internal.Conn]):
684
684
  store.put(("docs",), "doc2", {"text": "Other guide"}, index=False) # don't index
685
685
 
686
686
  # Search by similarity
687
- results = store.search(("docs",), "programming guides", limit=2)
687
+ results = store.search(("docs",), query="programming guides", limit=2)
688
688
  ```
689
689
 
690
690
  Note:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langgraph-checkpoint-postgres"
3
- version = "2.0.18"
3
+ version = "2.0.20"
4
4
  description = "Library with a Postgres implementation of LangGraph checkpoint saver."
5
5
  authors = []
6
6
  license = "MIT"
@@ -10,7 +10,7 @@ packages = [{ include = "langgraph" }]
10
10
 
11
11
  [tool.poetry.dependencies]
12
12
  python = "^3.9.0,<4.0"
13
- langgraph-checkpoint = "^2.0.15"
13
+ langgraph-checkpoint = "^2.0.21"
14
14
  orjson = ">=3.10.1"
15
15
  psycopg = "^3.2.0"
16
16
  psycopg-pool = "^3.2.0"