Commit 01ee941
authored
feat(python-driver): add public API for connection pooling and model dict conversion (#2374)
* feat(python-driver): add public API for connection pooling and model dict conversion
Add two enhancements to the Python driver's public API:
1. Add configure_connection() function that registers AGE agtype adapters
on an existing psycopg connection without creating a new one. This
enables use with external connection pools (e.g. psycopg_pool) and
managed PostgreSQL services where LOAD 'age' may be restricted.
Also explicitly export AgeLoader and ClientCursor as public symbols
in age/__init__.py. (#2369)
2. Add to_dict() methods to Vertex, Edge, and Path model classes for
conversion to plain Python dicts. This enables direct JSON
serialization with json.dumps() without requiring custom conversion
logic. (#2371)
- Vertex.to_dict() returns {id, label, properties}
- Edge.to_dict() returns {id, label, start_id, end_id, properties}
- Path.to_dict() returns a list of to_dict() results
Closes #2369
Closes #2371
* Fix configure_connection: correct parameter semantics, add load_from_plugins
- Replace confusing `skip_load` (double-negative) with `load` (positive
boolean, default False). The default now correctly matches the intent:
no LOAD by default for connection pool / managed PostgreSQL use cases.
- Add `load_from_plugins` parameter for parity with setUpAge().
- Fix docstring to accurately describe parameter behavior.
- Add 6 unit tests for configure_connection covering: default no-load,
explicit load, load_from_plugins, search_path always set, adapter
registration, and graph_name check delegation.
Made-with: Cursor
* Address review feedback for configure_connection and to_dict
- Move TypeInfo.fetch() inside cursor block so search_path change is
visible regardless of transaction isolation mode
- Raise ValueError when load_from_plugins=True but load=False
- Add type annotations to configure_connection signature
- Document shallow-copy semantics in Vertex/Edge to_dict()
- Path.to_dict() uses str() fallback for non-AGObj entities to
guarantee JSON-serializable output
- Add test for AgeNotSet when TypeInfo.fetch returns None
- Add test for load_from_plugins=True without load=True
- Replace fragile string assertions with assert_called_with/assert_any_call
Made-with: Cursor
* Fix Path.to_dict() to preserve JSON-native types, add tests to suite
- Path.to_dict(): leave dict/list/str/int/float/bool/None unchanged
instead of converting to str(); handle entities=None safely
- Add TestModelToDict, TestPublicImports, TestConfigureConnection to
the __main__ suite so they run via direct script execution
Made-with: Cursor
* fix(python-driver): Python 3.9-safe hints and correct $user in search_path
- Use Optional[str] for configure_connection graph_name (PEP 604 unions are
invalid on Python 3.9).
- Import Any/Optional from typing for annotations.
- Quote $user in SET search_path; align unit test expectations.
Made-with: Cursor
* test(python-driver): add configure_connection + to_dict integration test
Existing tests for the new public API are unit-only:
- TestConfigureConnection mocks the psycopg connection, so it never
proves that AgeLoader actually registers against real agtype OIDs.
- TestModelToDict hand-constructs Vertex/Edge/Path via kwargs, so it
never serialises objects produced by the ANTLR parser.
Add a single TestAgeBasic.testConfigureConnection that:
- opens a raw psycopg connection (bypassing age.connect()),
- calls configure_connection(..., load=True) on it,
- runs a Cypher CREATE/RETURN through the configured connection,
- asserts the returned values are real Vertex/Edge instances and that
their to_dict() output is JSON-serialisable with the expected
label/start_id/end_id/properties shape,
- repeats the round-trip for a Path returned by MATCH.
This is the smallest test that proves the configure_connection +
to_dict pipeline works end-to-end against a live AGE database.
Made-with: Cursor1 parent a1b749a commit 01ee941
4 files changed
Lines changed: 341 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
170 | 172 | | |
171 | 173 | | |
172 | 174 | | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
173 | 240 | | |
174 | 241 | | |
175 | 242 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
118 | 118 | | |
119 | 119 | | |
120 | 120 | | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
121 | 135 | | |
122 | 136 | | |
123 | 137 | | |
| |||
146 | 160 | | |
147 | 161 | | |
148 | 162 | | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
149 | 175 | | |
150 | 176 | | |
151 | 177 | | |
| |||
186 | 212 | | |
187 | 213 | | |
188 | 214 | | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
189 | 229 | | |
190 | 230 | | |
191 | 231 | | |
| |||
0 commit comments