langgraph-checkpoint-postgres 2.0.21__tar.gz → 2.0.22__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 (26) hide show
  1. langgraph_checkpoint_postgres-2.0.22/.gitignore +184 -0
  2. langgraph_checkpoint_postgres-2.0.22/Makefile +66 -0
  3. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/PKG-INFO +24 -20
  4. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/README.md +16 -4
  5. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/checkpoint/postgres/__init__.py +120 -86
  6. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/checkpoint/postgres/aio.py +140 -110
  7. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/checkpoint/postgres/base.py +37 -40
  8. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/checkpoint/postgres/shallow.py +80 -62
  9. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/store/postgres/aio.py +23 -23
  10. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/store/postgres/base.py +44 -49
  11. langgraph_checkpoint_postgres-2.0.22/pyproject.toml +75 -0
  12. langgraph_checkpoint_postgres-2.0.22/tests/__init__.py +0 -0
  13. langgraph_checkpoint_postgres-2.0.22/tests/compose-postgres.yml +17 -0
  14. langgraph_checkpoint_postgres-2.0.22/tests/conftest.py +44 -0
  15. langgraph_checkpoint_postgres-2.0.22/tests/embed_test_utils.py +55 -0
  16. langgraph_checkpoint_postgres-2.0.22/tests/test_async.py +347 -0
  17. langgraph_checkpoint_postgres-2.0.22/tests/test_async_store.py +693 -0
  18. langgraph_checkpoint_postgres-2.0.22/tests/test_store.py +863 -0
  19. langgraph_checkpoint_postgres-2.0.22/tests/test_sync.py +335 -0
  20. langgraph_checkpoint_postgres-2.0.22/uv.lock +1225 -0
  21. langgraph_checkpoint_postgres-2.0.21/pyproject.toml +0 -69
  22. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/checkpoint/postgres/_ainternal.py +0 -0
  23. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/checkpoint/postgres/_internal.py +0 -0
  24. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/checkpoint/postgres/py.typed +0 -0
  25. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/store/postgres/__init__.py +0 -0
  26. {langgraph_checkpoint_postgres-2.0.21 → langgraph_checkpoint_postgres-2.0.22}/langgraph/store/postgres/py.typed +0 -0
@@ -0,0 +1,184 @@
1
+ .vs/
2
+ .vscode/
3
+ .idea/
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+
9
+ # C extensions
10
+ *.so
11
+
12
+ # Distribution / packaging
13
+ .Python
14
+ build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ wheels/
26
+ pip-wheel-metadata/
27
+ share/python-wheels/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+ MANIFEST
32
+
33
+ # PyInstaller
34
+ # Usually these files are written by a python script from a template
35
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
36
+ *.manifest
37
+ *.spec
38
+
39
+ # Installer logs
40
+ pip-log.txt
41
+ pip-delete-this-directory.txt
42
+
43
+ # Unit test / coverage reports
44
+ htmlcov/
45
+ .tox/
46
+ .nox/
47
+ .coverage
48
+ .coverage.*
49
+ .cache
50
+ nosetests.xml
51
+ coverage.xml
52
+ *.cover
53
+ *.py,cover
54
+ .hypothesis/
55
+ .pytest_cache/
56
+
57
+ # Translations
58
+ *.mo
59
+ *.pot
60
+
61
+ # Django stuff:
62
+ *.log
63
+ local_settings.py
64
+ db.sqlite3
65
+ db.sqlite3-journal
66
+
67
+ # Flask stuff:
68
+ instance/
69
+ .webassets-cache
70
+
71
+ # Scrapy stuff:
72
+ .scrapy
73
+
74
+ # Sphinx documentation
75
+ docs/_build/
76
+ docs/docs/_build/
77
+
78
+ # PyBuilder
79
+ target/
80
+
81
+ # Jupyter Notebook
82
+ .ipynb_checkpoints
83
+ notebooks/
84
+
85
+ # IPython
86
+ profile_default/
87
+ ipython_config.py
88
+
89
+ # pyenv
90
+ .python-version
91
+
92
+ # pipenv
93
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
95
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
96
+ # install all needed dependencies.
97
+ #Pipfile.lock
98
+
99
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
100
+ __pypackages__/
101
+
102
+ # Celery stuff
103
+ celerybeat-schedule
104
+ celerybeat.pid
105
+
106
+ # SageMath parsed files
107
+ *.sage.py
108
+
109
+ # Environments
110
+ .env
111
+ .envrc
112
+ .venv
113
+ .venvs
114
+ env/
115
+ venv/
116
+ ENV/
117
+ env.bak/
118
+ venv.bak/
119
+
120
+ # Spyder project settings
121
+ .spyderproject
122
+ .spyproject
123
+
124
+ # Rope project settings
125
+ .ropeproject
126
+
127
+ # mkdocs documentation
128
+ /site
129
+
130
+ # mypy
131
+ .mypy_cache/
132
+ .dmypy.json
133
+ dmypy.json
134
+
135
+ # Pyre type checker
136
+ .pyre/
137
+
138
+ # macOS display setting files
139
+ .DS_Store
140
+
141
+ # Wandb directory
142
+ wandb/
143
+
144
+ # asdf tool versions
145
+ .tool-versions
146
+ /.ruff_cache/
147
+
148
+ *.pkl
149
+ *.bin
150
+
151
+ # integration test artifacts
152
+ data_map*
153
+ \[('_type', 'fake'), ('stop', None)]
154
+
155
+ # Replit files
156
+ *replit*
157
+
158
+ node_modules
159
+ docs/.yarn/
160
+ docs/node_modules/
161
+ docs/.docusaurus/
162
+ docs/.cache-loader/
163
+ docs/_dist
164
+ docs/api_reference/api_reference.rst
165
+ docs/api_reference/experimental_api_reference.rst
166
+ docs/api_reference/_build
167
+ docs/api_reference/*/
168
+ !docs/api_reference/_static/
169
+ !docs/api_reference/templates/
170
+ !docs/api_reference/themes/
171
+ docs/docs_skeleton/build
172
+ docs/docs_skeleton/node_modules
173
+ docs/docs_skeleton/yarn.lock
174
+
175
+ # Any new jupyter notebooks
176
+ # not intended for the repo
177
+ Untitled*.ipynb
178
+
179
+ Chinook.db
180
+
181
+ .vercel
182
+ .turbo
183
+ .editorconfig
184
+ .scratch
@@ -0,0 +1,66 @@
1
+ .PHONY: test test_watch lint format
2
+
3
+ ######################
4
+ # TESTING AND COVERAGE
5
+ ######################
6
+
7
+ start-postgres:
8
+ POSTGRES_VERSION=${POSTGRES_VERSION:-16} docker compose -f tests/compose-postgres.yml up -V --force-recreate --wait || ( \
9
+ echo "Failed to start PostgreSQL, printing logs..."; \
10
+ docker compose -f tests/compose-postgres.yml logs; \
11
+ exit 1 \
12
+ )
13
+
14
+ stop-postgres:
15
+ docker compose -f tests/compose-postgres.yml down
16
+
17
+ POSTGRES_VERSIONS ?= 15 16
18
+ test_pg_version:
19
+ @echo "Testing PostgreSQL $(POSTGRES_VERSION)"
20
+ @POSTGRES_VERSION=$(POSTGRES_VERSION) make start-postgres
21
+ @uv run pytest $(TEST)
22
+ @EXIT_CODE=$$?; \
23
+ make stop-postgres; \
24
+ echo "Finished testing PostgreSQL $(POSTGRES_VERSION); Exit code: $$EXIT_CODE"; \
25
+ exit $$EXIT_CODE
26
+
27
+ test:
28
+ @for version in $(POSTGRES_VERSIONS); do \
29
+ if ! make test_pg_version POSTGRES_VERSION=$$version; then \
30
+ echo "Test failed for PostgreSQL $$version"; \
31
+ exit 1; \
32
+ fi; \
33
+ done
34
+ @echo "All PostgreSQL versions tested successfully"
35
+
36
+ TEST ?= .
37
+ test_watch:
38
+ POSTGRES_VERSION=${POSTGRES_VERSION:-16} make start-postgres; \
39
+ uv run ptw $(TEST); \
40
+ EXIT_CODE=$$?; \
41
+ make stop-postgres; \
42
+ exit $$EXIT_CODE
43
+
44
+ ######################
45
+ # LINTING AND FORMATTING
46
+ ######################
47
+
48
+ # Define a variable for Python and notebook files.
49
+ PYTHON_FILES=.
50
+ MYPY_CACHE=.mypy_cache
51
+ lint format: PYTHON_FILES=.
52
+ lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --relative --diff-filter=d main . | grep -E '\.py$$|\.ipynb$$')
53
+ lint_package: PYTHON_FILES=langgraph
54
+ lint_tests: PYTHON_FILES=tests
55
+ lint_tests: MYPY_CACHE=.mypy_cache_test
56
+
57
+ lint lint_diff lint_package lint_tests:
58
+ uv run ruff check .
59
+ [ "$(PYTHON_FILES)" = "" ] || uv run ruff format $(PYTHON_FILES) --diff
60
+ [ "$(PYTHON_FILES)" = "" ] || uv run ruff check --select I $(PYTHON_FILES)
61
+ [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE)
62
+ [ "$(PYTHON_FILES)" = "" ] || uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE)
63
+
64
+ format format_diff:
65
+ uv run ruff format $(PYTHON_FILES)
66
+ uv run ruff check --select I --fix $(PYTHON_FILES)
@@ -1,21 +1,14 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: langgraph-checkpoint-postgres
3
- Version: 2.0.21
3
+ Version: 2.0.22
4
4
  Summary: Library with a Postgres implementation of LangGraph checkpoint saver.
5
- License: MIT
6
- Requires-Python: >=3.9.0,<4.0.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: langgraph-checkpoint (>=2.0.21,<3.0.0)
15
- Requires-Dist: orjson (>=3.10.1)
16
- Requires-Dist: psycopg (>=3.2.0,<4.0.0)
17
- Requires-Dist: psycopg-pool (>=3.2.0,<4.0.0)
18
5
  Project-URL: Repository, https://www.github.com/langchain-ai/langgraph
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.9
8
+ Requires-Dist: langgraph-checkpoint<3.0.0,>=2.0.21
9
+ Requires-Dist: orjson>=3.10.1
10
+ Requires-Dist: psycopg-pool>=3.2.0
11
+ Requires-Dist: psycopg>=3.2.0
19
12
  Description-Content-Type: text/markdown
20
13
 
21
14
  # LangGraph Checkpoint Postgres
@@ -33,6 +26,20 @@ By default `langgraph-checkpoint-postgres` installs `psycopg` (Psycopg 3) withou
33
26
 
34
27
  > [!IMPORTANT]
35
28
  > When manually creating Postgres connections and passing them to `PostgresSaver` or `AsyncPostgresSaver`, make sure to include `autocommit=True` and `row_factory=dict_row` (`from psycopg.rows import dict_row`). See a full example in this [how-to guide](https://langchain-ai.github.io/langgraph/how-tos/persistence_postgres/).
29
+ >
30
+ > **Why these parameters are required:**
31
+ > - `autocommit=True`: Required for the `.setup()` method to properly commit the checkpoint tables to the database. Without this, table creation may not be persisted.
32
+ > - `row_factory=dict_row`: Required because the PostgresSaver implementation accesses database rows using dictionary-style syntax (e.g., `row["column_name"]`). The default `tuple_row` factory returns tuples that only support index-based access (e.g., `row[0]`), which will cause `TypeError` exceptions when the checkpointer tries to access columns by name.
33
+ >
34
+ > **Example of incorrect usage:**
35
+ > ```python
36
+ > # ❌ This will fail with TypeError during checkpointer operations
37
+ > with psycopg.connect(DB_URI) as conn: # Missing autocommit=True and row_factory=dict_row
38
+ > checkpointer = PostgresSaver(conn)
39
+ > checkpointer.setup() # May not persist tables properly
40
+ > # Any operation that reads from database will fail with:
41
+ > # TypeError: tuple indices must be integers or slices, not str
42
+ > ```
36
43
 
37
44
  ```python
38
45
  from langgraph.checkpoint.postgres import PostgresSaver
@@ -45,7 +52,7 @@ with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
45
52
  # call .setup() the first time you're using the checkpointer
46
53
  checkpointer.setup()
47
54
  checkpoint = {
48
- "v": 2,
55
+ "v": 4,
49
56
  "ts": "2024-07-31T20:14:19.804150+00:00",
50
57
  "id": "1ef4f797-8335-6428-8001-8a1503f9b875",
51
58
  "channel_values": {
@@ -67,7 +74,6 @@ with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
67
74
  "start:node": 2
68
75
  }
69
76
  },
70
- "pending_sends": [],
71
77
  }
72
78
 
73
79
  # store checkpoint
@@ -87,7 +93,7 @@ from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
87
93
 
88
94
  async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
89
95
  checkpoint = {
90
- "v": 2,
96
+ "v": 4,
91
97
  "ts": "2024-07-31T20:14:19.804150+00:00",
92
98
  "id": "1ef4f797-8335-6428-8001-8a1503f9b875",
93
99
  "channel_values": {
@@ -109,7 +115,6 @@ async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
109
115
  "start:node": 2
110
116
  }
111
117
  },
112
- "pending_sends": [],
113
118
  }
114
119
 
115
120
  # store checkpoint
@@ -121,4 +126,3 @@ async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
121
126
  # list checkpoints
122
127
  [c async for c in checkpointer.alist(read_config)]
123
128
  ```
124
-
@@ -13,6 +13,20 @@ By default `langgraph-checkpoint-postgres` installs `psycopg` (Psycopg 3) withou
13
13
 
14
14
  > [!IMPORTANT]
15
15
  > When manually creating Postgres connections and passing them to `PostgresSaver` or `AsyncPostgresSaver`, make sure to include `autocommit=True` and `row_factory=dict_row` (`from psycopg.rows import dict_row`). See a full example in this [how-to guide](https://langchain-ai.github.io/langgraph/how-tos/persistence_postgres/).
16
+ >
17
+ > **Why these parameters are required:**
18
+ > - `autocommit=True`: Required for the `.setup()` method to properly commit the checkpoint tables to the database. Without this, table creation may not be persisted.
19
+ > - `row_factory=dict_row`: Required because the PostgresSaver implementation accesses database rows using dictionary-style syntax (e.g., `row["column_name"]`). The default `tuple_row` factory returns tuples that only support index-based access (e.g., `row[0]`), which will cause `TypeError` exceptions when the checkpointer tries to access columns by name.
20
+ >
21
+ > **Example of incorrect usage:**
22
+ > ```python
23
+ > # ❌ This will fail with TypeError during checkpointer operations
24
+ > with psycopg.connect(DB_URI) as conn: # Missing autocommit=True and row_factory=dict_row
25
+ > checkpointer = PostgresSaver(conn)
26
+ > checkpointer.setup() # May not persist tables properly
27
+ > # Any operation that reads from database will fail with:
28
+ > # TypeError: tuple indices must be integers or slices, not str
29
+ > ```
16
30
 
17
31
  ```python
18
32
  from langgraph.checkpoint.postgres import PostgresSaver
@@ -25,7 +39,7 @@ with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
25
39
  # call .setup() the first time you're using the checkpointer
26
40
  checkpointer.setup()
27
41
  checkpoint = {
28
- "v": 2,
42
+ "v": 4,
29
43
  "ts": "2024-07-31T20:14:19.804150+00:00",
30
44
  "id": "1ef4f797-8335-6428-8001-8a1503f9b875",
31
45
  "channel_values": {
@@ -47,7 +61,6 @@ with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
47
61
  "start:node": 2
48
62
  }
49
63
  },
50
- "pending_sends": [],
51
64
  }
52
65
 
53
66
  # store checkpoint
@@ -67,7 +80,7 @@ from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
67
80
 
68
81
  async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
69
82
  checkpoint = {
70
- "v": 2,
83
+ "v": 4,
71
84
  "ts": "2024-07-31T20:14:19.804150+00:00",
72
85
  "id": "1ef4f797-8335-6428-8001-8a1503f9b875",
73
86
  "channel_values": {
@@ -89,7 +102,6 @@ async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
89
102
  "start:node": 2
90
103
  }
91
104
  },
92
- "pending_sends": [],
93
105
  }
94
106
 
95
107
  # store checkpoint