|
| 1 | +import os |
| 2 | +from dataclasses import dataclass |
| 3 | + |
| 4 | + |
| 5 | +def _env(name: str, default: str | None = None) -> str | None: |
| 6 | + v = os.getenv(name) |
| 7 | + if v is None or v == "": |
| 8 | + return default |
| 9 | + return v |
| 10 | + |
| 11 | + |
| 12 | +@dataclass(frozen=True) |
| 13 | +class Settings: |
| 14 | + # GCP / Vertex |
| 15 | + gcp_project: str | None = _env("GCP_PROJECT") or _env("GOOGLE_CLOUD_PROJECT") |
| 16 | + gcp_location: str = _env("GCP_LOCATION", "us-central1") or "us-central1" |
| 17 | + |
| 18 | + # BigQuery |
| 19 | + bq_project: str | None = _env("BQ_PROJECT") # optional; defaults to gcp_project |
| 20 | + bq_dataset: str = _env("BQ_DATASET", "vertex_rag_demo") or "vertex_rag_demo" |
| 21 | + bq_notes_table: str = _env("BQ_NOTES_TABLE", "demo_Notes") or "demo_Notes" |
| 22 | + bq_embeddings_table: str = _env("BQ_EMBEDDINGS_TABLE", "demo_NoteEmbeddings") or "demo_NoteEmbeddings" |
| 23 | + |
| 24 | + # Column names (override if your schema differs) |
| 25 | + notes_id_col: str = _env("NOTES_ID_COL", "note_id") or "note_id" |
| 26 | + notes_content_col: str = _env("NOTES_CONTENT_COL", "content") or "content" |
| 27 | + notes_source_col: str = _env("NOTES_SOURCE_COL", "source") or "source" |
| 28 | + notes_created_col: str = _env("NOTES_CREATED_COL", "created_at") or "created_at" |
| 29 | + |
| 30 | + emb_id_col: str = _env("EMB_ID_COL", "note_id") or "note_id" |
| 31 | + emb_vector_col: str = _env("EMB_VECTOR_COL", "embedding") or "embedding" # ARRAY<FLOAT64> |
| 32 | + emb_model_col: str = _env("EMB_MODEL_COL", "model") or "model" |
| 33 | + emb_updated_col: str = _env("EMB_UPDATED_COL", "updated_at") or "updated_at" |
| 34 | + |
| 35 | + # RAG settings |
| 36 | + rag_top_k: int = int(_env("RAG_TOP_K", "3") or "3") |
| 37 | + snippet_chars: int = int(_env("RAG_SNIPPET_CHARS", "800") or "800") |
| 38 | + |
| 39 | + # LLM + Embeddings |
| 40 | + gemini_model: str = _env("GEMINI_MODEL", "gemini-2.5-flash-lite") or "gemini-2.5-flash-lite" |
| 41 | + embedding_model: str = _env("EMBEDDING_MODEL", "text-embedding-004") or "text-embedding-004" |
| 42 | + |
| 43 | + # Optional: cap how many notes to load into memory cache |
| 44 | + bq_max_notes: int = int(_env("BQ_MAX_NOTES", "5000") or "5000") |
| 45 | + |
| 46 | + @property |
| 47 | + def effective_bq_project(self) -> str | None: |
| 48 | + return self.bq_project or self.gcp_project |
| 49 | + |
| 50 | + def require_project(self) -> str: |
| 51 | + if not self.gcp_project: |
| 52 | + raise RuntimeError("GCP_PROJECT / GOOGLE_CLOUD_PROJECT not set.") |
| 53 | + return self.gcp_project |
0 commit comments