Skip to content

Commit a6e9cc1

Browse files
committed
LLM/Embeddings/DB 프로파일(시크릿 포함) JSON 저장·사이드바 적용 + DB 섹션 CRUD 확장
1 parent b31de27 commit a6e9cc1

File tree

8 files changed

+1021
-73
lines changed

8 files changed

+1021
-73
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import os
2+
import streamlit as st
3+
4+
from interface.core.config import get_db_connections_registry, update_db_settings
5+
6+
7+
def render_sidebar_db_selector() -> None:
8+
st.sidebar.markdown("### DB 연결")
9+
10+
registry = get_db_connections_registry()
11+
names = [c.name for c in registry.connections]
12+
if not names:
13+
st.sidebar.warning("등록된 DB 프로파일이 없습니다. 설정 > DB에서 추가하세요.")
14+
return
15+
16+
# 기본 선택: 세션 또는 ENV의 DB_TYPE과 일치하는 첫 프로파일
17+
current_type = (
18+
st.session_state.get("DB_TYPE") or os.getenv("DB_TYPE") or ""
19+
).lower()
20+
default_index = 0
21+
if current_type:
22+
for idx, c in enumerate(registry.connections):
23+
if c.type == current_type:
24+
default_index = idx
25+
break
26+
27+
sel_name = st.sidebar.selectbox(
28+
"프로파일", options=names, index=default_index, key="sidebar_db_profile"
29+
)
30+
selected = next((c for c in registry.connections if c.name == sel_name), None)
31+
if selected is None:
32+
st.sidebar.error("선택한 프로파일을 찾을 수 없습니다.")
33+
return
34+
35+
if st.sidebar.button("적용", key="sidebar_apply_db"):
36+
try:
37+
values = {
38+
"host": selected.host,
39+
"port": selected.port,
40+
"user": selected.user,
41+
"password": selected.password,
42+
"database": selected.database,
43+
"extra": selected.extra,
44+
}
45+
update_db_settings(db_type=selected.type, values=values, secrets={})
46+
st.sidebar.success(f"DB 적용됨: {selected.name}")
47+
except Exception as e:
48+
st.sidebar.error(f"적용 실패: {e}")
Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,81 @@
11
import os
22
import streamlit as st
33

4-
from interface.core.config import update_embedding_settings
5-
from interface.app_pages.settings_sections.llm_section import LLM_PROVIDERS
4+
from interface.core.config import (
5+
update_embedding_settings,
6+
get_embedding_registry,
7+
)
68

79

810
def render_sidebar_embedding_selector() -> None:
911
st.sidebar.markdown("### Embeddings 선택")
1012

11-
default_emb = (
12-
(
13-
st.session_state.get("EMBEDDING_PROVIDER")
14-
or os.getenv("EMBEDDING_PROVIDER")
15-
or "openai"
13+
e_reg = get_embedding_registry()
14+
if not e_reg.profiles:
15+
st.sidebar.info(
16+
"저장된 Embeddings 프로파일이 없습니다. 설정 > LLM에서 저장하세요."
1617
)
18+
# fallback: 간단 공급자 선택 유지
19+
default_emb = (
20+
(
21+
st.session_state.get("EMBEDDING_PROVIDER")
22+
or os.getenv("EMBEDDING_PROVIDER")
23+
or "openai"
24+
)
25+
).lower()
26+
selected = st.sidebar.selectbox(
27+
"Embeddings 공급자",
28+
options=["openai", "azure", "bedrock", "gemini", "ollama", "huggingface"],
29+
index=(
30+
["openai", "azure", "bedrock", "gemini", "ollama", "huggingface"].index(
31+
default_emb
32+
)
33+
if default_emb
34+
in {"openai", "azure", "bedrock", "gemini", "ollama", "huggingface"}
35+
else 0
36+
),
37+
key="sidebar_embedding_provider_fallback",
38+
)
39+
if selected != default_emb:
40+
try:
41+
update_embedding_settings(provider=selected, values={})
42+
st.sidebar.success(
43+
f"Embeddings 공급자가 '{selected}'로 변경되었습니다."
44+
)
45+
except Exception as e:
46+
st.sidebar.error(f"Embeddings 공급자 변경 실패: {e}")
47+
return
48+
49+
e_names = [p.name for p in e_reg.profiles]
50+
current_emb_provider = (
51+
st.session_state.get("EMBEDDING_PROVIDER")
52+
or os.getenv("EMBEDDING_PROVIDER")
53+
or ""
1754
).lower()
18-
try:
19-
default_idx = LLM_PROVIDERS.index(default_emb)
20-
except ValueError:
21-
default_idx = 0
22-
23-
selected = st.sidebar.selectbox(
24-
"Embeddings 공급자",
25-
options=LLM_PROVIDERS,
26-
index=default_idx,
27-
key="sidebar_embedding_provider",
55+
e_default_index = 0
56+
if current_emb_provider:
57+
for idx, p in enumerate(e_reg.profiles):
58+
if p.provider == current_emb_provider:
59+
e_default_index = idx
60+
break
61+
62+
e_sel_name = st.sidebar.selectbox(
63+
"Embeddings 프로파일",
64+
options=e_names,
65+
index=e_default_index,
66+
key="sidebar_embedding_profile",
2867
)
2968

30-
if selected != default_emb:
69+
e_selected = next((p for p in e_reg.profiles if p.name == e_sel_name), None)
70+
if e_selected is None:
71+
st.sidebar.error("선택한 Embeddings 프로파일을 찾을 수 없습니다.")
72+
return
73+
74+
if st.sidebar.button("Embeddings 적용", key="sidebar_apply_embedding_profile"):
3175
try:
32-
update_embedding_settings(provider=selected, values={})
33-
st.sidebar.success(f"Embeddings 공급자가 '{selected}'로 변경되었습니다.")
76+
update_embedding_settings(
77+
provider=e_selected.provider, values=e_selected.fields
78+
)
79+
st.sidebar.success(f"Embeddings 프로파일 적용됨: {e_selected.name}")
3480
except Exception as e:
35-
st.sidebar.error(f"Embeddings 공급자 변경 실패: {e}")
81+
st.sidebar.error(f"Embeddings 프로파일 적용 실패: {e}")
Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,77 @@
11
import os
22
import streamlit as st
33

4-
from interface.core.config import update_llm_settings
5-
from interface.app_pages.settings_sections.llm_section import LLM_PROVIDERS
4+
from interface.core.config import (
5+
update_llm_settings,
6+
get_llm_registry,
7+
)
68

79

810
def render_sidebar_llm_selector() -> None:
911
st.sidebar.markdown("### LLM 선택")
1012

11-
default_llm = (
12-
(st.session_state.get("LLM_PROVIDER") or os.getenv("LLM_PROVIDER") or "openai")
13+
reg = get_llm_registry()
14+
if not reg.profiles:
15+
st.sidebar.info(
16+
"저장된 LLM 프로파일이 없습니다. 설정 > LLM에서 프로파일을 저장하세요."
17+
)
18+
# 기존 방식 fallback
19+
default_llm = (
20+
(
21+
st.session_state.get("LLM_PROVIDER")
22+
or os.getenv("LLM_PROVIDER")
23+
or "openai"
24+
)
25+
).lower()
26+
selected_provider = st.sidebar.selectbox(
27+
"LLM 공급자",
28+
options=["openai", "azure", "bedrock", "gemini", "ollama", "huggingface"],
29+
index=(
30+
["openai", "azure", "bedrock", "gemini", "ollama", "huggingface"].index(
31+
default_llm
32+
)
33+
if default_llm
34+
in {"openai", "azure", "bedrock", "gemini", "ollama", "huggingface"}
35+
else 0
36+
),
37+
key="sidebar_llm_provider_fallback",
38+
)
39+
if selected_provider != default_llm:
40+
try:
41+
update_llm_settings(provider=selected_provider, values={})
42+
st.sidebar.success(
43+
f"LLM 공급자가 '{selected_provider}'로 변경되었습니다."
44+
)
45+
except Exception as e:
46+
st.sidebar.error(f"LLM 공급자 변경 실패: {e}")
47+
return
48+
49+
names = [p.name for p in reg.profiles]
50+
# 기본 선택: 세션의 LLM_PROVIDER와 같은 provider를 가진 첫 프로파일
51+
current_provider = (
52+
st.session_state.get("LLM_PROVIDER") or os.getenv("LLM_PROVIDER") or ""
1353
).lower()
14-
try:
15-
default_idx = LLM_PROVIDERS.index(default_llm)
16-
except ValueError:
17-
default_idx = 0
18-
19-
selected = st.sidebar.selectbox(
20-
"LLM 공급자",
21-
options=LLM_PROVIDERS,
22-
index=default_idx,
23-
key="sidebar_llm_provider",
54+
default_index = 0
55+
if current_provider:
56+
for idx, p in enumerate(reg.profiles):
57+
if p.provider == current_provider:
58+
default_index = idx
59+
break
60+
61+
sel_name = st.sidebar.selectbox(
62+
"LLM 프로파일", options=names, index=default_index, key="sidebar_llm_profile"
2463
)
64+
selected = next((p for p in reg.profiles if p.name == sel_name), None)
65+
if selected is None:
66+
st.sidebar.error("선택한 LLM 프로파일을 찾을 수 없습니다.")
67+
return
2568

26-
if selected != default_llm:
69+
if st.sidebar.button("적용", key="sidebar_apply_llm_profile"):
2770
try:
28-
update_llm_settings(provider=selected, values={})
29-
st.sidebar.success(f"LLM 공급자가 '{selected}'로 변경되었습니다.")
71+
# provider 설정 + 프로파일의 비민감 필드만 적용
72+
update_llm_settings(provider=selected.provider, values=selected.fields)
73+
st.sidebar.success(f"LLM 프로파일 적용됨: {selected.name}")
3074
except Exception as e:
31-
st.sidebar.error(f"LLM 공급자 변경 실패: {e}")
75+
st.sidebar.error(f"LLM 프로파일 적용 실패: {e}")
76+
77+
# Embeddings 관련 UI는 embedding_selector.py에서 처리

interface/app_pages/lang2sql.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from interface.app_pages.components.embedding_selector import (
2929
render_sidebar_embedding_selector,
3030
)
31+
from interface.app_pages.components.db_selector import render_sidebar_db_selector
3132

3233
TITLE = "Lang2SQL"
3334
DEFAULT_QUERY = "고객 데이터를 기반으로 유니크한 유저 수를 카운트하는 쿼리"
@@ -50,6 +51,7 @@
5051
render_sidebar_data_source_selector(config)
5152
render_sidebar_llm_selector()
5253
render_sidebar_embedding_selector()
54+
render_sidebar_db_selector()
5355

5456
st.sidebar.markdown("### 워크플로우 선택")
5557
use_enriched = st.sidebar.checkbox(

interface/app_pages/settings.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
render_data_source_section,
1010
)
1111
from interface.app_pages.settings_sections.llm_section import render_llm_section
12+
from interface.app_pages.settings_sections.db_section import render_db_section
1213

1314

1415
st.title("⚙️ 설정")
@@ -24,7 +25,7 @@
2425
render_llm_section(config)
2526

2627
with tabs[2]:
27-
st.info("DB 연결 설정은 곧 제공됩니다.")
28+
render_db_section()
2829

2930
with tabs[3]:
3031
st.info("디바이스 설정은 곧 제공됩니다.")

0 commit comments

Comments
 (0)