File size: 3,703 Bytes
dbb6988
 
 
 
c0907f8
a9e2887
dbb6988
 
 
a9e2887
a9dc0f3
 
 
 
 
 
 
 
 
 
a9e2887
dbb6988
 
 
 
 
a9dc0f3
dbb6988
 
 
4e2f406
c56dd72
 
 
 
a9dc0f3
dbb6988
a9dc0f3
 
 
dbb6988
 
a9dc0f3
dbb6988
 
 
a9dc0f3
dbb6988
 
 
a9dc0f3
dbb6988
047ffe2
dbb6988
c025e27
9dcf8cb
 
a9dc0f3
c025e27
06dc89b
eab288c
 
f0e68b1
 
a9dc0f3
 
 
 
06dc89b
dfd32d8
 
3670aeb
dfd32d8
 
 
 
f6c9376
 
 
1df3c30
 
 
 
 
f0e68b1
 
 
c0907f8
f0e68b1
 
 
c0907f8
dbb6988
 
 
a9dc0f3
dbb6988
 
 
 
 
 
 
a9dc0f3
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
from pydantic_settings import BaseSettings
from functools import lru_cache
import os
from dotenv import load_dotenv
from pydantic import field_validator
from loguru import logger

load_dotenv()

# Debug: Check environment variables
logger.info(
    f"[CONFIG] FACEBOOK_APP_SECRET from env: {os.getenv('FACEBOOK_APP_SECRET', 'NOT_SET')[:5]}..."
)
logger.info(
    f"[CONFIG] FACEBOOK_VERIFY_TOKEN from env: {os.getenv('FACEBOOK_VERIFY_TOKEN', 'NOT_SET')[:5]}..."
)
logger.info(
    f"[CONFIG] SUPABASE_URL from env: {os.getenv('SUPABASE_URL', 'NOT_SET')[:5]}..."
)


class Settings(BaseSettings):
    """
    Lưu trữ và quản lý cấu hình ứng dụng từ biến môi trường.
    Các thuộc tính: facebook_verify_token, facebook_app_secret, ...
    """

    # Facebook Configuration
    facebook_verify_token: str = os.getenv("FACEBOOK_VERIFY_TOKEN") or ""
    facebook_app_secret: str = os.getenv("FACEBOOK_APP_SECRET") or ""
    facebook_api_base_url: str = os.getenv("FACEBOOK_API_BASE_URL") or ""
    # Thuộc tính này không còn cần thiết sau khi khôi phục logic lấy token từ Supabase.
    # Việc xóa nó đi giúp mã nguồn sạch sẽ và đúng với logic ban đầu.
    # facebook_page_tokens: Optional[Dict[str, str]] = None


    # Google Sheets Configuration
    google_sheets_credentials_file: str = (
        os.getenv("GOOGLE_SHEETS_CREDENTIALS_FILE") or ""
    )
    google_sheets_token_file: str = os.getenv("GOOGLE_SHEETS_TOKEN_FILE") or ""
    conversation_sheet_id: str = os.getenv("CONVERSATION_SHEET_ID") or ""

    # Supabase Configuration
    supabase_url: str = os.getenv("SUPABASE_URL") or ""
    supabase_key: str = os.getenv("SUPABASE_KEY") or ""

    # Server Configuration
    host: str = os.getenv("HOST", "0.0.0.0") or ""
    port: int = int(os.getenv("PORT", "8000")) or 8000

    # Logging Configuration
    log_level: str = os.getenv("LOG_LEVEL", "DEBUG") or "DEBUG"

    # Search Configuration
    match_count: int = int(os.getenv("MATCH_COUNT", "20")) or 20
    max_docs_to_rerank: int = int(os.getenv("MAX_DOCS_TO_RERANK", "20")) or 20
    rerank_min_score: float = float(os.getenv("RERANK_MIN_SCORE", "7.0"))

    # Gemini Configuration
    # Hỗ trợ nhiều API key và model cho Gemini
    # Định nghĩa biến môi trường: GEMINI_API_KEYS="key1,key2,..."; GEMINI_MODELS="model1,model2,..."
    gemini_api_keys: str = ""
    gemini_models: str = ""
    gemini_base_url: str = (
        os.getenv("GEMINI_BASE_URL", "https://generativelanguage.googleapis.com/v1")
        or ""
    )

    # LLM (chat/completion) provider/model
    llm_provider: str = os.getenv("LLM_PROVIDER", "gemini") or ""
    llm_model: str = os.getenv("LLM_MODEL", "gemini-2.5-flash") or ""
    # Embedding provider/model
    embedding_provider: str = os.getenv("EMBEDDING_PROVIDER", "gemini") or ""
    embedding_model: str = os.getenv("EMBEDDING_MODEL", "models/embedding-001") or ""

    rerank_provider: str = os.getenv("RERANK_PROVIDER", "") or llm_provider
    rerank_model: str = os.getenv("RERANK_MODEL", "") or llm_model

    @field_validator("log_level")
    @classmethod
    def uppercase_log_level(cls, v: str) -> str:
        return v.upper()

    @property
    def gemini_api_keys_list(self):
        return [k.strip() for k in self.gemini_api_keys.split(",") if k.strip()]

    @property
    def gemini_models_list(self):
        return [m.strip() for m in self.gemini_models.split(",") if m.strip()]

    class Config:
        env_file = ".env"


@lru_cache()
def get_settings() -> Settings:
    """
    Lấy instance Settings đã cache (singleton).
    Input: None
    Output: Settings instance.
    """
    return Settings()