- **기본 정보 불러오기**
- 이 섹션에서는 프로그램 실행에 필요한 주요 라이브러리들을 불러옵니다.
- **pandas**: CSV, DataFrame 등의 데이터 처리를 위한 라이브러리입니다.
- **streamlit**: 간단한 코드로 웹 애플리케이션을 만들 수 있는 라이브러리로, UI 구성에 사용됩니다.
- **matplotlib**: 파이썬의 대표적인 시각화 라이브러리로, 그래프, 차트 등을 그릴 때 사용합니다
- **openai**: OpenAI의 API를 사용해 ChatGPT 모델에 질의를 보내고 코드를 생성하는 데 사용합니다.
- **기능 구현 함수**
아래는 핵심 함수들의 예시 코드입니다.
- API 호출, 사용자 질의 생성, 응답 후처리 등 핵심 기능을 담당하는 함수들을 모아둔 부분입니다.
1. **`run_request`**: OpenAI ChatCompletion API를 호출하여, 사용자 질의(question_to_ask)에 대한 코드를 생성합니다.
2. **`make_prompt`**: 사용자 질문과 데이터셋 정보를 합쳐 OpenAI 모델에게 전달할 ‘프롬프트’를 만듭니다.
- **메인 코드**
- 프로그램의 전체적인 실행 흐름을 제어하는 부분입니다.
- 페이지 레이아웃 설정, 사이드바, 사용자 입력과 버튼을 구성하고, 결과(그래프)를 출력합니다.
사이드바를 사용하여 업로드된 CSV 파일을 추가하거나, 미리 지정된 여러 CSV 데이터셋 중 하나를 선택할 수 있습니다.
또한 OpenAI API Key를 입력받고, 모델(gpt-4o, gpt-4o-mini) 중 하나를 선택하도록 라디오 버튼을 배치합니다.
with st.sidebar:
# 사용할 데이터셋 선택
dataset_container = st.empty()
# CSV 파일 업로드 기능
try:
uploaded_file = st.file_uploader(":computer: Load a CSV file:", type="csv")
index_no = 0
if uploaded_file:
# 업로드된 CSV를 데이터프레임으로 읽어서 datasets에 추가
file_name = uploaded_file.name[:-4].capitalize()
datasets[file_name] = pd.read_csv(uploaded_file)
# 방금 업로드한 데이터셋이 기본적으로 선택되도록 인덱스 설정
index_no = len(datasets) - 1
except Exception as e:
st.error("파일을 불러오지 못했습니다. 유효한 CSV 파일을 선택해 주세요.")
print("File failed to load.\n" + str(e))
# 데이터셋 선택 라디오 버튼
chosen_dataset = dataset_container.radio(
":bar_chart: Choose your data:", datasets.keys(), index=index_no
)
# 모델 선택
st.write(":brain: Choose your model(s):")
model = st.radio(label="", options=["gpt-4o", "gpt-4o-mini"])
세션 상태에 datasets가 없다면, 특정 CSV 파일을 미리 로드하고 datasets 딕셔너리에 저장해둡니다.
업로드된 CSV가 있다면 이를 새로 읽어와 datasets에 추가합니다.
# 세션 상태에 datasets가 없으면 미리 지정된 CSV 파일들을 로드합니다.
if "datasets" not in st.session_state:
datasets = {}
# 사전에 불러둘 데이터셋
datasets["Movies"] = pd.read_csv("movies.csv")
datasets["Housing"] = pd.read_csv("housing.csv")
datasets["Cars"] = pd.read_csv("cars.csv")
datasets["Colleges"] = pd.read_csv("colleges.csv")
datasets["Customers & Products"] = pd.read_csv(
"customers_and_products_contacts.csv"
)
datasets["Department Store"] = pd.read_csv("department_store.csv")
datasets["Energy Production"] = pd.read_csv("energy_production.csv")
st.session_state["datasets"] = datasets
else:
# 이미 세션 상태에 로드된 데이터셋 사용
datasets = st.session_state["datasets"
st.text_input를 통해 사용자로부터 API Key를 안전하게 입력받습니다.
# OpenAI Key 입력
openai_key = st.text_input(
label=":key: OpenAI Key:",
help="Required for ChatGPT-4o, ChatGPT-4o-mini",
type="password",
)
st.text_area를 통해 시각화와 관련한 질문을 받습니다.
예: “매출이 시간에 따라 어떻게 변하는지 그래프를 그리고 싶어요.”
# 사용자에게 시각화를 묻는 텍스트 입력
question = st.text_area(":eyes: What would you like to visualise?", height=110)
go_btn = st.button("Go...")
여러 개의 CSV 파일을 불러왔으므로, Streamlit의 st.tabs 기능을 사용해 각 데이터셋을 탭으로 분리하고, 표 형태로 내용을 확인할 수 있도록 합니다.
tab_list = st.tabs(datasets.keys())
for dataset_num, tab in enumerate(tab_list):
with tab:
dataset_name = list(datasets.keys())[dataset_num]
st.subheader(dataset_name)
st.dataframe(datasets[dataset_name], hide_index=True)
make_prompt를 통해 선택된 데이터셋과 사용자의 질문을 합쳐 하나의 “코드를 생성해줘”라는 요청 문구를 만듭니다.run_request로 ChatGPT에게 코드 생성을 요청합니다.read_csv 부분은 제거한 뒤 최종 코드만 받아옵니다.기존에 준비해둔 base_code(import, fig, ax 설정, df=...)와 ChatGPT가 생성한 코드를 합쳐 final_code를 구성합니다.
코드 실행 전 plt.clf() 등을 통해 현재 figure를 초기화하고, 생성된 코드를 exec로 실행합니다.
실행 후 plt.gcf()(현재 figure 객체)를 가져와 대시보드에 표시합니다.
st.pyplot(fig)로 Streamlit 대시보드에 그래프를 표시합니다.
if go_btn and openai_key:
# 1) 프롬프트 생성
question_to_ask = make_prompt(
datasets[chosen_dataset],
'datasets["' + chosen_dataset + '"]',
question
)
# 2) OpenAI API 호출
answer = run_request(
question_to_ask,
model,
key=openai_key,
)
# 3) 기본 패키지 코드 + GPT 응답 코드 합치기
pimer_code = (
"import pandas as pd\nimport matplotlib.pyplot as plt\n"
"fig,ax = plt.subplots(1,1,figsize=(10,4))\n"
"ax.spines['top'].set_visible(False)\nax.spines['right'].set_visible(False)\n"
"df=" + 'datasets["' + chosen_dataset + '"]' + ".copy()\n"
)
final_code = pimer_code + answer
# 이전 figure 초기화
plt.clf()
# 코드 실행
exec(final_code)
# 현재 figure 객체 획득
fig = plt.gcf()
st.pyplot(fig)