Spaces:
Sleeping
Sleeping
File size: 3,480 Bytes
c496840 1638b2e c496840 1638b2e 2753128 f927995 2753128 1638b2e 2753128 f927995 1638b2e 2753128 1638b2e f59a149 2753128 1638b2e f927995 1638b2e 2753128 1638b2e 2753128 1638b2e f927995 2753128 1638b2e f927995 1638b2e f927995 1638b2e 2753128 1638b2e f927995 1638b2e 2753128 1638b2e 2753128 1638b2e 2753128 f927995 2753128 1638b2e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | """
Configuration management for the PharmaShield backend using Pydantic Settings.
"""
import json
import logging
from pathlib import Path
from typing import List
from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
def _discover_base_dir() -> Path:
"""
Find the project base directory by looking for bundled seed data.
Local development usually has ``repo_root/data``.
Backend-only serverless deployments use ``backend/data``.
"""
config_path = Path(__file__).resolve()
for candidate in reversed(config_path.parents):
if (candidate / "data" / "seed" / "drugs.json").exists():
return candidate
# Fallback to the backend root if no data bundle is found yet.
return config_path.parent.parent
BASE_DIR = _discover_base_dir()
class Settings(BaseSettings):
"""
Application settings and environment variables.
Defaults are provided where safe; sensitive keys must be provided in .env or environment.
"""
# API Keys & Endpoints
GEMINI_API_KEY: str = ""
QDRANT_URL: str = ""
QDRANT_API_KEY: str = ""
GOOGLE_MAPS_API_KEY: str = ""
# Project Info
FIREBASE_PROJECT_ID: str = ""
BACKEND_URL: str = "http://localhost:8080"
ALLOWED_ORIGINS: List[str] = [
"http://localhost:3000",
"http://localhost:5173",
"http://localhost:8080",
"https://pharmashield.web.app",
]
# Paths
SEED_DATA_DIR: str = str(BASE_DIR / "data" / "seed")
GNN_WEIGHTS_PATH: str = str(BASE_DIR / "ml" / "weights" / "gnn_v1.pt")
ENABLE_GNN: bool = False
DEMO_MODE: bool = True
DEMO_SCENARIOS_PATH: str = str(BASE_DIR / "data" / "seed" / "demo_scenarios.json")
# Model & Database Configurations
QDRANT_COLLECTION: str = "pharmashield_kb"
GEMINI_FLASH_MODEL: str = "gemini-2.0-flash"
GEMINI_PRO_MODEL: str = "gemini-2.5-pro"
EMBEDDING_MODEL: str = "models/gemini-embedding-001"
@field_validator("ALLOWED_ORIGINS", mode="before")
@classmethod
def parse_allowed_origins(cls, value):
if isinstance(value, list):
return value
if isinstance(value, str):
text = value.strip()
if not text:
return []
if text.startswith("["):
try:
parsed = json.loads(text)
except json.JSONDecodeError:
parsed = None
if isinstance(parsed, list):
return [str(item).strip() for item in parsed if str(item).strip()]
return [item.strip() for item in text.split(",") if item.strip()]
return value
model_config = SettingsConfigDict(
env_file=(
BASE_DIR / "backend" / ".env",
BASE_DIR / ".env",
),
env_file_encoding="utf-8",
extra="ignore",
)
try:
settings = Settings()
if not settings.GEMINI_API_KEY or not settings.QDRANT_URL:
missing = []
if not settings.GEMINI_API_KEY:
missing.append("GEMINI_API_KEY")
if not settings.QDRANT_URL:
missing.append("QDRANT_URL")
logging.warning(
"Missing non-critical configuration: %s. Some features may be disabled.",
", ".join(missing),
)
except Exception as e:
if isinstance(e, RuntimeError):
raise e
raise RuntimeError(f"Failed to load application settings: {str(e)}")
|