Spaces:
Sleeping
Sleeping
| from pydantic_settings import BaseSettings | |
| from pydantic import Field, field_validator, ConfigDict | |
| from typing import List, Any, Optional, Dict | |
| import os | |
| import logging | |
| import sys | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| # Load environment variables from .env file | |
| load_dotenv() | |
| def setup_logging(log_level: str = "INFO", log_file: str = None) -> None: | |
| """Configure logging for the application.""" | |
| log_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" | |
| # Configure root logger | |
| logging.basicConfig( | |
| level=log_level, | |
| format=log_format, | |
| handlers=[logging.StreamHandler(sys.stdout)] | |
| ) | |
| # Add file handler if log file is specified | |
| if log_file: | |
| log_file = Path(log_file) | |
| log_file.parent.mkdir(parents=True, exist_ok=True) | |
| file_handler = logging.FileHandler(log_file) | |
| file_handler.setFormatter(logging.Formatter(log_format)) | |
| logging.getLogger().addHandler(file_handler) | |
| # Set log level for specific loggers | |
| logging.getLogger("httpx").setLevel(logging.WARNING) | |
| logging.getLogger("openai").setLevel(logging.WARNING) | |
| logging.getLogger("urllib3").setLevel(logging.WARNING) | |
| class Settings(BaseSettings): | |
| model_config = ConfigDict( | |
| env_file=".env", | |
| env_file_encoding="utf-8", | |
| extra="allow", | |
| env_nested_delimiter="__" | |
| ) | |
| # App configuration | |
| APP_NAME: str = Field(default="Carehelp") | |
| ENVIRONMENT: str = Field(default="development") | |
| # Logging configuration | |
| LOG_LEVEL: str = Field(default="INFO") | |
| LOG_FILE: Optional[str] = Field(default=None) | |
| def configure_logging(self) -> None: | |
| """Configure logging based on settings.""" | |
| setup_logging( | |
| log_level=self.LOG_LEVEL, | |
| log_file=self.LOG_FILE | |
| ) | |
| PORT: int = Field(default=8000) | |
| # CORS configuration | |
| CORS_ALLOW_ORIGINS: List[str] = Field(default_factory=lambda: ["*"]) | |
| # API Keys | |
| GOOGLE_MAPS_API_KEY: str | None = None | |
| SERPAPI_API_KEY: str | None = None | |
| # Supabase configuration | |
| SUPABASE_URL: str | None = None | |
| SUPABASE_ANON_KEY: str | None = None | |
| SUPABASE_SERVICE_ROLE_KEY: str | None = None | |
| SUPABASE_DB_PASSWORD: str | None = None | |
| # OpenAI configuration | |
| OPENAI_API_KEY: str | None = None | |
| OPENAI_MODEL: str = Field(default="gpt-4") | |
| OPENAI_WHISPER_MODEL: str = Field(default="whisper-1") | |
| OPENAI_WHISPER_FALLBACK_MODEL: str | None = Field(default="gpt-4-transcribe") | |
| OPENAI_WHISPER_MAX_CHUNK_SECS: int = Field(default=120) | |
| # JWT configuration | |
| JWT_SECRET: str = Field(default="change_this_secret") | |
| JWT_ALGORITHM: str = Field(default="HS256") | |
| ACCESS_TOKEN_EXPIRE_MINUTES: int = Field(default=60 * 24 * 30) | |
| # Hugging Face configuration | |
| HF_API_TOKEN: str | None = None | |
| HF_TRANSLATION_MODEL: str = Field(default="facebook/nllb-200-distilled-600M") | |
| # Provider selection and models | |
| # Options: 'hf' (Hugging Face Inference), 'ollama' (local), 'lmstudio' (local OpenAI-compatible) | |
| AI_PROVIDER: str = Field(default="hf") | |
| # Text generation (chat) models | |
| HF_TEXT_MODEL: str = Field(default="meta-llama/Meta-Llama-3-8B-Instruct") | |
| OLLAMA_MODEL: str = Field(default="llama3.1:8b") | |
| OLLAMA_BASE_URL: str = Field(default="http://localhost:11434") | |
| LMSTUDIO_MODEL: str | None = Field(default=None) | |
| LMSTUDIO_BASE_URL: str = Field(default="http://localhost:1234/v1") | |
| # Vision caption model (used to assist image analysis with HF) | |
| HF_VISION_CAPTION_MODEL: str = Field(default="Salesforce/blip-image-captioning-large") | |
| # Optional local vision model for Ollama (e.g., 'llava:latest') | |
| OLLAMA_VISION_MODEL: str = Field(default="llava:latest") | |
| # Automatic Speech Recognition (ASR) | |
| HF_ASR_MODEL: str = Field(default="distil-whisper/distil-large-v3") | |
| # Data paths | |
| PATIENT_DATA_PATH: str = Field(default="../patient_records.json") | |
| # Cameroon data configuration | |
| CAMEROON_DATA_CSV: str = Field(default="../../clinical_summaries.csv") | |
| CAMEROON_EMBEDDINGS_MODEL: str = Field( | |
| default="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2" | |
| ) | |
| CAMEROON_CACHE_DIR: str = Field(default=".cache_cameroon") | |
| CAMEROON_MAX_ROWS: int | None = None # limit for dev/testing | |
| def parse_cors_origins(cls, v: Any) -> Any: | |
| # Accept JSON array, comma-separated string, or single "*" | |
| if isinstance(v, list): | |
| return v | |
| if isinstance(v, str): | |
| s = v.strip() | |
| if s == "": | |
| return ["*"] | |
| if s == "*": | |
| return ["*"] | |
| # comma separated | |
| return [x.strip() for x in s.split(",") if x.strip()] | |
| return v | |
| settings = Settings() | |