@@ -33,37 +33,50 @@ class VectorDbConfig:
33
33
34
34
35
35
def _get_config_value (key : str , config_raw : dict , saved_config_raw : dict , default : Optional [str ] = None ) -> str :
36
- """Get configuration value with priority: saved.json > ENV > .env > JSON."""
37
- # First check saved configuration (highest priority)
38
- keys = key .lower ().split ('_' )
39
- # Skip the 'gc_qa_rag' prefix for JSON lookup
40
- if len (keys ) >= 4 and keys [0 ] == 'gc' and keys [1 ] == 'qa' and keys [2 ] == 'rag' :
41
- keys = keys [3 :]
36
+ """
37
+ Get configuration value with priority: saved.json > ENV > .env > JSON.
42
38
43
- # Check saved config first
44
- current = saved_config_raw
45
- try :
46
- for k in keys :
47
- current = current [k ]
48
- return str (current )
49
- except (KeyError , TypeError ):
50
- pass
39
+ Key format: GC_QA_RAG.SECTION.FIELD (e.g., GC_QA_RAG.LLM.API_KEY)
40
+ - For JSON: uses dot notation to navigate nested structure
41
+ - For ENV: converts dots to underscores (GC_QA_RAG_LLM_API_KEY)
42
+ """
43
+
44
+ def _get_value_from_json (config_dict : dict , dot_key : str ) -> Optional [str ]:
45
+ """Navigate JSON structure using dot notation."""
46
+ if not config_dict :
47
+ return None
48
+
49
+ # Remove GC_QA_RAG prefix and split by dots
50
+ if dot_key .startswith ("GC_QA_RAG." ):
51
+ path = dot_key [10 :].split ('.' ) # Remove "GC_QA_RAG." prefix
52
+ else :
53
+ path = dot_key .split ('.' )
54
+
55
+ current = config_dict
56
+ try :
57
+ for key_part in path :
58
+ current = current [key_part .lower ()]
59
+ return str (current )
60
+ except (KeyError , TypeError ):
61
+ return None
62
+
63
+ # 1. Check saved config first (highest priority)
64
+ saved_value = _get_value_from_json (saved_config_raw , key )
65
+ if saved_value is not None :
66
+ return saved_value
51
67
52
- # Then check environment variables
53
- env_value = os .getenv (key )
68
+ # 2. Then check environment variables (convert dots to underscores)
69
+ env_key = key .replace ('.' , '_' ).upper ()
70
+ env_value = os .getenv (env_key )
54
71
if env_value is not None :
55
72
return env_value
56
73
57
- # Then check nested JSON structure
58
- current = config_raw
59
- try :
60
- for k in keys :
61
- current = current [k ]
62
- return str (current )
63
- except (KeyError , TypeError ):
64
- pass
74
+ # 3. Then check JSON config
75
+ json_value = _get_value_from_json (config_raw , key )
76
+ if json_value is not None :
77
+ return json_value
65
78
66
- # Return default if provided
79
+ # 4. Return default if provided
67
80
if default is not None :
68
81
return default
69
82
@@ -121,24 +134,24 @@ def from_environment(cls, environment: str) -> "Config":
121
134
return cls (
122
135
environment = environment ,
123
136
das = DasConfig (
124
- base_url_page = _get_config_value ("GC_QA_RAG_DAS_BASE_URL_PAGE " , config_raw , saved_config_raw , "" ),
125
- base_url_thread = _get_config_value ("GC_QA_RAG_DAS_BASE_URL_THREAD " , config_raw , saved_config_raw , "" ),
126
- token = _get_config_value ("GC_QA_RAG_DAS_TOKEN " , config_raw , saved_config_raw , "" ),
137
+ base_url_page = _get_config_value ("GC_QA_RAG.DAS.BASE_URL_PAGE " , config_raw , saved_config_raw , "" ),
138
+ base_url_thread = _get_config_value ("GC_QA_RAG.DAS.BASE_URL_THREAD " , config_raw , saved_config_raw , "" ),
139
+ token = _get_config_value ("GC_QA_RAG.DAS.TOKEN " , config_raw , saved_config_raw , "" ),
127
140
),
128
141
llm = LlmConfig (
129
- api_key = _get_config_value ("GC_QA_RAG_LLM_API_KEY " , config_raw , saved_config_raw ),
130
- api_base = _get_config_value ("GC_QA_RAG_LLM_API_BASE " , config_raw , saved_config_raw , "https://dashscope.aliyuncs.com/compatible-mode/v1" ),
131
- model_name = _get_config_value ("GC_QA_RAG_LLM_MODEL_NAME " , config_raw , saved_config_raw , "qwen-plus" ),
132
- max_rpm = _get_config_int ("GC_QA_RAG_LLM_MAX_RPM " , config_raw , saved_config_raw , 100 ),
142
+ api_key = _get_config_value ("GC_QA_RAG.LLM.API_KEY " , config_raw , saved_config_raw ),
143
+ api_base = _get_config_value ("GC_QA_RAG.LLM.API_BASE " , config_raw , saved_config_raw , "https://dashscope.aliyuncs.com/compatible-mode/v1" ),
144
+ model_name = _get_config_value ("GC_QA_RAG.LLM.MODEL_NAME " , config_raw , saved_config_raw , "qwen-plus" ),
145
+ max_rpm = _get_config_int ("GC_QA_RAG.LLM.MAX_RPM " , config_raw , saved_config_raw , 100 ),
133
146
),
134
147
embedding = EmbeddingConfig (
135
- api_key = _get_config_value ("GC_QA_RAG_EMBEDDING_API_KEY " , config_raw , saved_config_raw )
148
+ api_key = _get_config_value ("GC_QA_RAG.EMBEDDING.API_KEY " , config_raw , saved_config_raw )
136
149
),
137
150
vector_db = VectorDbConfig (
138
- host = _get_config_value ("GC_QA_RAG_VECTOR_DB_HOST " , config_raw , saved_config_raw , "http://host.docker.internal:6333" )
151
+ host = _get_config_value ("GC_QA_RAG.VECTOR_DB.HOST " , config_raw , saved_config_raw , "http://host.docker.internal:6333" )
139
152
),
140
- root_path = _get_config_value ("GC_QA_RAG_ROOT_PATH " , config_raw , saved_config_raw , user_cache_dir ("gc-qa-rag" , ensure_exists = True )),
141
- log_path = _get_config_value ("GC_QA_RAG_LOG_PATH " , config_raw , saved_config_raw , user_log_dir ("gc-qa-rag" , ensure_exists = True )),
153
+ root_path = _get_config_value ("GC_QA_RAG.ROOT_PATH " , config_raw , saved_config_raw , user_cache_dir ("gc-qa-rag" , ensure_exists = True )),
154
+ log_path = _get_config_value ("GC_QA_RAG.LOG_PATH " , config_raw , saved_config_raw , user_log_dir ("gc-qa-rag" , ensure_exists = True )),
142
155
)
143
156
144
157
0 commit comments