Skip to content

feat(state): add MongoBackend and URI-based backend factory#11

Open
himewel wants to merge 2 commits into
mainfrom
feat/mongodb-state-backend
Open

feat(state): add MongoBackend and URI-based backend factory#11
himewel wants to merge 2 commits into
mainfrom
feat/mongodb-state-backend

Conversation

@himewel
Copy link
Copy Markdown
Owner

@himewel himewel commented May 18, 2026

Summary

  • Add MongoBackend in q2google/state/mongo.py storing sessions across three MongoDB collections (sessions, items, batches) that mirror the JsonFileBackend directory layout, enabling per-collection visibility into what is running
  • Introduce build_backend(cfg) factory in q2google/state/__init__.py that selects the backend from a single Q2GOOGLE_STATE_URI env var — URI scheme routes to the right implementation; future backends need zero config changes
  • pymongo is an optional extra (pip install q2google[mongo]); import q2google.state never fails without it — lazy import inside the factory raises a clear error only when a mongodb:// URI is actually requested

Changes

  • q2google/state/mongo.py — new MongoBackend with load / save, lazy index creation, and session_id injected into item/batch documents for per-collection queries
  • q2google/state/__init__.pybuild_backend(cfg) factory + MongoBackend re-export
  • q2google/config.pystate_uri: str | None field (Q2GOOGLE_STATE_URI); state_dir unchanged
  • q2google/cli/_runner.py — accepts state_backend: SyncStateBackend instead of state_dir: Path
  • q2google/cli/_app.py — uses build_backend(cfg); explicit --state-dir flag still overrides to filesystem
  • pyproject.toml[mongo] optional extra (pymongo>=4), mongomock>=4 in [dev]
  • tests/conftest.py — parametrized backend fixture (json + mongo via mongomock); mongo variant auto-skips when dependencies are absent
  • tests/test_state_backends.py — 5 protocol-compliance tests running for all backends (10 cases total)
  • tests/test_sync.py — trimmed to filesystem-specific tests (legacy format, directory layout)
  • docs/backends.md — new guide covering Filesystem, MongoDB, and Custom backends with collection schemas and install instructions
  • docs/configuration.md, docs/getting-started.md, docs/ARCHITECTURE.md, docs/api/state.md, mkdocs.yml — updated to reference new backend

Test plan

  • pip install q2google installs without pymongo — filesystem backend works as before
  • pip install q2google[mongo] installs pymongo — Q2GOOGLE_STATE_URI=mongodb://... activates MongoBackend
  • uv run pytest tests/ -vv — all 14 tests pass (12 backend-parametrized + 2 filesystem-specific)
  • Setting an unknown URI scheme raises ValueError with a helpful message
  • Setting mongodb:// URI without pymongo raises ImportError pointing to pip install q2google[mongo]

Made with Cursor

Add a MongoDB storage backend for session state using three collections
(sessions, items, batches) that mirror the JsonFileBackend directory layout.
Introduce a URI-based build_backend() factory so future backends can be
added with zero config changes — the URI scheme selects the implementation.

- Add q2google/state/mongo.py with MongoBackend (pymongo optional extra)
- Add build_backend(cfg) factory to q2google/state/__init__.py with lazy
  MongoBackend import and clear error when pymongo is not installed
- Add Q2GOOGLE_STATE_URI setting to Q2GoogleSettings; state_dir unchanged
- Refactor _runner.py to accept SyncStateBackend instead of state_dir Path
- Update _app.py to use build_backend(); --state-dir flag still overrides
- Add parametrized backend fixture in tests/conftest.py (json + mongo via
  mongomock); extract protocol-compliance tests to test_state_backends.py
- Add docs/backends.md guide; update configuration.md, getting-started.md,
  ARCHITECTURE.md, api/state.md, and mkdocs.yml nav

Co-authored-by: Cursor <[email protected]>
@github-actions github-actions Bot added feature and removed feature labels May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant