Spaces:
Sleeping
Sleeping
Download backend/firestore_client.py from Success-dev/receipter-pro: direct link, hf CLI and curl.
- Browser
- Download file 2.59 kB
-
https://huggingface.co/spaces/Success-dev/receipter-pro/resolve/main/backend/firestore_client.py
- Command line
-
hf download hf://spaces/Success-dev/receipter-pro/backend/firestore_client.py
-
curl -L -o firestore_client.py https://huggingface.co/spaces/Success-dev/receipter-pro/resolve/main/backend/firestore_client.py
2.59 kB
| """ | |
| The single seam between the org/role model (and everything else that stores operational | |
| metadata) and its actual backing store. Every caller uses get_doc/set_doc/update_doc/ | |
| delete_doc/query_prefix from THIS module, never backend.local_store or the real Firestore | |
| client directly. | |
| LOCAL_MODE governs which backing store this module uses — real Firestore (a real GCP | |
| project + service-account credential now exist, see backend/firebase_app.py) when false, | |
| the local SQLite shim when true (the default in tests — see tests/conftest.py, which forces | |
| LOCAL_MODE=true regardless of .env so the suite never touches real Firestore). | |
| Firestore's own Python client accepts the same slash-delimited path strings our path scheme | |
| already uses (`db.document("orgs/abc123")`, `db.collection("orgs/abc123/mailboxes")`) — no | |
| translation layer needed between our path convention and Firestore's. | |
| """ | |
| from __future__ import annotations | |
| from firebase_admin import firestore | |
| from backend import local_store | |
| from backend.firebase_app import get_app | |
| from backend.local_mode import LOCAL_MODE | |
| def _db(): | |
| get_app() | |
| return firestore.client() | |
| def get_doc(path: str) -> dict | None: | |
| if LOCAL_MODE: | |
| return local_store.get_doc(path) | |
| snap = _db().document(path).get() | |
| return snap.to_dict() if snap.exists else None | |
| def set_doc(path: str, data: dict) -> None: | |
| if LOCAL_MODE: | |
| local_store.set_doc(path, data) | |
| return | |
| _db().document(path).set(data) | |
| def update_doc(path: str, partial: dict) -> dict: | |
| """Shared across both backends: read-modify-write via this module's own get_doc/ | |
| set_doc, so the merge semantics (raise if the doc doesn't exist) stay identical | |
| regardless of which store is active — no need to duplicate the logic per backend.""" | |
| existing = get_doc(path) | |
| if existing is None: | |
| raise KeyError(f"No document at {path!r} to update") | |
| existing.update(partial) | |
| set_doc(path, existing) | |
| return existing | |
| def delete_doc(path: str) -> None: | |
| if LOCAL_MODE: | |
| local_store.delete_doc(path) | |
| return | |
| _db().document(path).delete() | |
| def query_prefix(prefix: str) -> dict[str, dict]: | |
| """All documents under a collection path (e.g. "orgs/abc123/mailboxes/"), keyed by | |
| their full path — matches local_store.query_prefix's contract exactly.""" | |
| if LOCAL_MODE: | |
| return local_store.query_prefix(prefix) | |
| collection_path = prefix.rstrip("/") | |
| docs = _db().collection(collection_path).stream() | |
| return {f"{collection_path}/{doc.id}": doc.to_dict() for doc in docs} | |