Repository navigation
Conversation
| list(ignored_kwargs.keys()), | ||
| ) | ||
| return SqliteSessionService(db_path=db_path) | ||
| return SqliteSessionService(db_path=uri) |
There was a problem hiding this comment.
passing the raw URI through still breaks once the encoded path and an option show up together: sqlite:///sessions%20%231.db?mode=ro turns into file:sessions #1.db?mode=ro in _parse_db_path, sqlite reads the # as the end of the path, so it quietly creates and opens a new writable db called sessions (the session lookup returns None and mode=ro is gone). re-encoding the path there fixes it, and _sqlite_memory_service._parse_db_path needs the same line:
--- a/src/google/adk/sessions/sqlite_session_service.py
+++ b/src/google/adk/sessions/sqlite_session_service.py
@@ -24,6 +24,7 @@ import os
import sqlite3
from typing import Any
from typing import cast
+from urllib.parse import quote
from urllib.parse import unquote
from urllib.parse import urlparse
@@ -177,7 +178,10 @@ def _parse_db_path(db_path: str) -> tuple[str, str, bool]:
if parsed.query:
# sqlite3 only treats the filename as a URI when it starts with `file:`.
- return normalized_path, f"file:{normalized_path}?{parsed.query}", True
+ # Re-encode the decoded path, or a `#` or `?` in the filename would end
+ # the path early and drop the query options.
+ connect_uri = f"file:{quote(normalized_path)}?{parsed.query}"
+ return normalized_path, connect_uri, True
return normalized_path, normalized_path, FalseThere was a problem hiding this comment.
Done in bb24f03: both _parse_db_path implementations now build the connect URI as file:{quote(normalized_path)}?{query}, so #, ? and a literal % in the decoded filename no longer truncate the path or drop mode=ro. The regressions are extended across reserved characters (#, ?, %23, +&= ü), relative and absolute paths, and no-query / ro / rw modes.
Verified on the branch: the two affected suites (tests/unittests/cli/test_service_registry.py, tests/unittests/memory/test_sqlite_memory_service.py) are 36 failed / 164 passed with the parent source for those two files swapped in, and 200 passed at bb24f03 (Python 3.12). Not run: the full tox matrix and Windows.
|
thanks for applying my fix in bb24f03! could you add a |
Quote the decoded path before building file: URIs in session and memory services. Otherwise # or ? truncates the filename and drops mode=ro, while literal percent escapes select a different database. Extend public-service regressions across reserved characters, relative and absolute paths, and no-query/read-only/read-write modes. The original head fails 36 cases with 54 passing controls; the fix passes all 90. Affected session, registry, factory and SQLite memory suites: 1039 passed, 1 xfailed on Linux/Python 3.12.14. Changed-file pre-commit and targeted mypy pass. Full tox and Windows were not run. Co-authored-by: Aman Agnihotri <amanagnihotri902@gmail.com>
bb24f03 to
a66dda7
Compare
|
Added the |
|
Heads-up: after adding the trailer, |
Link to Issue or Description of Change
Problem: The CLI/Web SQLite session factory extracts only the URI path. A
?mode=rodatabase is opened writable, and an encoded filename can open a different database.Solution: Pass the original URI to
SqliteSessionService, whose existing parser already handles path decoding and SQLite query options. Keep the no-path in-memory case.Testing Plan
Unit Tests:
The two new tests use real SQLite files through the registry. Both fail on main (read-only writes succeed; the encoded path misses the saved session). Registry, service-factory and session tests: 866 passed, 1 xfailed. Pre-commit and targeted mypy pass.
Manual End-to-End (E2E) Tests:
Used
create_session_service_from_optionswith temporary databases: the encoded URI reads the savedcount=1; the plain URI with?mode=roreads it and rejects a write withOperationalError: attempt to write a readonly database.Checklist
Additional context
Full tox matrix
Python 3.11: 23,598 passed; one dependency-version self-check failed because my initial local lock selected OTel 1.45.1. After updating the ignored local lock to the required 1.45.2, that check and the related suites passed (867 passed, 1 xfailed).
Python 3.12: 23,589 passed; one untouched telemetry timing test measured 0.161867s against a 0.10±0.05s bound. The same node then passed independently on both main and this branch with the same dependencies; its test and implementation files are identical between them.
Python 3.13: 23,590 passed, 116 skipped, 12 xfailed, 2 xpassed; tox passed.
Python 3.14: 23,592 passed, 114 skipped, 12 xfailed, 2 xpassed; tox passed.
No tracked dependency or lock files changed.