Spaces:
Sleeping
Sleeping
| # storage.py (Hugging Face Dataset ๋ฒ์ ) | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๋ฐ์ดํฐ ์ ์ฅ โ SQLite๋ ๊ตฌ๊ธ์ํธ๋ ์ฐ์ง ์๊ณ '์ด์ค ์์ ๋ง'์ผ๋ก ์ ์ฅํ๋ค. | |
| # | |
| # ์์ ๋ง 1) HF Dataset ์ ๋ก๋ : ์๊ตฌ ์ ์ฅ + ์ฌ๋ฌ ์ฐธ์ฌ์ ํตํฉ (๊ตฌ๊ธ์ํธ ๋์ฒด) | |
| # ์์ ๋ง 2) ๋ฉ๋ชจ๋ฆฌ(session_state): ์ฌ์ด๋๋ฐ์์ ์ฆ์ CSV ๋ค์ด๋ก๋ (๋ฐฑ์ ) | |
| # | |
| # ์ HF Dataset์ธ๊ฐ: | |
| # - ๊ตฌ๊ธ ๋ฐฉ์(์๋น์ค๊ณ์ ยทJSON ํคยท์ํธ ๊ณต์ )์ด ์ด๋ณด์์๊ฒ ๋๋ฌด ๋ณต์กํ๋ค. | |
| # - ์ด๋ฏธ HF Spaces์ ๋ฐฐํฌํ๋ฏ๋ก, ๊ฐ์ HF ์์์ 'ํ ํฐ 1๊ฐ'๋ง ๋ ๋ง๋ค๋ฉด ๋. | |
| # - Dataset ์ ์ฅ์๋ Space์ ๋ฌ๋ฆฌ ์ฌ์์์ ์ํฅ๋ฐ์ง ์๋ git ์ ์ฅ์๋ผ | |
| # ๋ฐ์ดํฐ๊ฐ ์๊ตฌ ๋ณด์กด๋๋ค(Space๊ฐ ์ฌ๋ฆฝ/์ฌ๋น๋๋ผ๋ ์์ ). | |
| # | |
| # ์๋ ๋ฐฉ์: | |
| # - ๋ชจ๋ ๊ธฐ๋ก์ ์ผ๋จ ๋ฉ๋ชจ๋ฆฌ ๋ฆฌ์คํธ(rows_*)์ ์์ธ๋ค(์์ ๋ง 2). | |
| # - '์ฐธ์ฌ์ ์๋ฃ' ์์ ์๋ง, ๊ทธ๋๊น์ง ๋ชจ์ธ ์ ์ฒด CSV๋ฅผ Dataset์ ๋ฎ์ด์ด๋ค(์์ ๋ง 1). | |
| # โ ๋งค ๋ฉ์์ง๋ง๋ค ์ฌ๋ฆฌ๋ฉด ๋๋ฌด ์ฆ์ผ๋ฏ๋ก, ์๋ฃ ์ ํ ๋ฒ๋ง ํต์งธ๋ก ์ฌ๋ฆฐ๋ค. | |
| # - ๋จ, ๋ฉ๋ชจ๋ฆฌ๋ 'ํ์ฌ ๋ธ๋ผ์ฐ์ ์ธ์ '๋ง ๋ด๋๋ค. ์ฌ๋ฌ ์ฐธ์ฌ์๋ฅผ ํ ํ์ผ๋ก | |
| # ํฉ์น๊ธฐ ์ํด, ์ ๋ก๋ ์ ์ Dataset์ ๊ธฐ์กด CSV๋ฅผ ๋ด๋ ค๋ฐ์ '๋จธ์ง(merge)'ํ๋ค. | |
| # | |
| # ์ค์ (1ํ): README/๊ฐ์ 7์ฅ ์ฐธ์กฐ. | |
| # 1) HF์์ ๋น Dataset ์์ฑ (์: yourname/career-chatbot-data, Private ๊ถ์ฅ) | |
| # 2) write ๊ถํ ํ ํฐ ๋ฐ๊ธ โ Space secret์ HF_TOKEN์ผ๋ก ๋ฑ๋ก | |
| # 3) ์๋ DATASET_REPO๋ฅผ ๋ณธ์ธ ๊ฒ์ผ๋ก ๊ต์ฒด | |
| # HF_TOKEN์ด ์์ผ๋ฉด ์ ๋ก๋๋ ์กฐ์ฉํ ๊ฑด๋๋ฐ๊ณ ์ฌ์ด๋๋ฐ ๋ค์ด๋ก๋๋ง ๋์ํ๋ค | |
| # (๋ก์ปฌ ๊ฐ๋ฐ ์ ํธ๋ฆฌ). | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| import os | |
| import io | |
| from datetime import datetime, timezone | |
| import pandas as pd | |
| # huggingface_hub์ Dataset ์ ๋ก๋๋ฅผ ์ธ ๋๋ง ํ์. ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋๋ก๋ง ๋์. | |
| try: | |
| from huggingface_hub import HfApi, hf_hub_download | |
| _HAS_HF = True | |
| except ImportError: | |
| _HAS_HF = False | |
| # โผโผโผ ๋ณธ์ธ์ด ๋ง๋ Dataset ์ ์ฅ์ ์ด๋ฆ์ผ๋ก ๊ต์ฒด โผโผโผ | |
| DATASET_REPO = "jonghhhh/career-chatbot-data" | |
| # โฒโฒโฒ (HF์์ New Dataset์ผ๋ก ๋ง๋ 'yourname/์ ์ฅ์์ด๋ฆ') โฒโฒโฒ | |
| HF_TOKEN = os.getenv("HUGGINGFACE_TOKEN_WRITE") # Space secret ๋๋ .env์ ๋ฃ์ write ํ ํฐ | |
| # Dataset ์์ ์ ์ฅ๋ 3๊ฐ CSV ํ์ผ ์ด๋ฆ | |
| FILES = { | |
| "participants": "participants.csv", | |
| "messages": "messages.csv", | |
| "surveys": "surveys.csv", | |
| } | |
| def now_iso(): | |
| """UTC ISO 8601 ํ์์คํฌํ (์: 2026-05-27T12:34:56+00:00).""" | |
| return datetime.now(timezone.utc).isoformat() | |
| # โโ ๋ฉ๋ชจ๋ฆฌ(์์ ๋ง 2): ๋ชจ๋ ๊ธฐ๋ก์ ์ธ์ ๋ฆฌ์คํธ์ ๋์ โโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def init_state(state): | |
| """์ธ์ ์์ ์ ๋์ ๋ฆฌ์คํธ 3๊ฐ๋ฅผ ์ค๋น(์ด๋ฏธ ์์ผ๋ฉด ๊ทธ๋๋ก).""" | |
| state.setdefault("rows_participants", []) | |
| state.setdefault("rows_messages", []) | |
| state.setdefault("rows_surveys", []) | |
| def add_participant(state, pid, condition): | |
| """์ฐธ์ฌ์ ๋ฐฐ์ ๊ธฐ๋ก(๋ฉ๋ชจ๋ฆฌ์๋ง ์ถ๊ฐ. ์ ๋ก๋๋ ์๋ฃ ์ ์ผ๊ด).""" | |
| state["rows_participants"].append( | |
| {"participant_id": pid, "condition": condition, | |
| "assigned_at": now_iso(), "completed": 0}) | |
| def add_message(state, pid, condition, turn, role, content, latency_ms=""): | |
| """๋ํ ํ ํด ๊ธฐ๋ก(๋ฉ๋ชจ๋ฆฌ).""" | |
| state["rows_messages"].append( | |
| {"participant_id": pid, "condition": condition, "turn": turn, | |
| "role": role, "content": content, "latency_ms": latency_ms, | |
| "created_at": now_iso()}) | |
| def add_survey(state, pid, condition, phase, question_id, answer): | |
| """์ค๋ฌธ ํ ๋ฌธํญ ๊ธฐ๋ก(๋ฉ๋ชจ๋ฆฌ).""" | |
| state["rows_surveys"].append( | |
| {"participant_id": pid, "condition": condition, "phase": phase, | |
| "question_id": question_id, "answer": str(answer), | |
| "created_at": now_iso()}) | |
| # โโ HF Dataset(์์ ๋ง 1): ๊ธฐ์กด ๋ฐ์ดํฐ์ ๋จธ์ง ํ ์ ๋ก๋ โโโโโโโโโโโโโโโโโโโโโโโ | |
| def _download_existing(api, filename): | |
| """Dataset์ ์ด๋ฏธ ์๋ CSV๋ฅผ DataFrame์ผ๋ก ์ฝ์ด์จ๋ค. ์์ผ๋ฉด ๋น DF.""" | |
| try: | |
| path = hf_hub_download( | |
| repo_id=DATASET_REPO, filename=filename, | |
| repo_type="dataset", token=HF_TOKEN, | |
| ) | |
| return pd.read_csv(path) | |
| except Exception: | |
| # ํ์ผ์ด ์์ง ์๊ฑฐ๋(์ฒซ ์ ๋ก๋) ๋คํธ์ํฌ ๋ฌธ์ โ ๋น DF๋ก ์์ | |
| return pd.DataFrame() | |
| def _upload_csv(api, df, filename): | |
| """DataFrame์ CSV ๋ฐ์ดํธ๋ก ๋ง๋ค์ด Dataset์ ๋ฎ์ด์ฐ๊ธฐ ์ ๋ก๋.""" | |
| buf = io.BytesIO(df.to_csv(index=False).encode("utf-8-sig")) | |
| api.upload_file( | |
| path_or_fileobj=buf, # ํ์ผ ๊ฒฝ๋ก ๋์ ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ๋ฅผ ์ง์ ์ฌ๋ฆผ | |
| path_in_repo=filename, | |
| repo_id=DATASET_REPO, | |
| repo_type="dataset", | |
| token=HF_TOKEN, | |
| commit_message=f"update {filename} @ {now_iso()}", | |
| ) | |
| def push_to_dataset(state): | |
| """ํ์ฌ ์ธ์ ์ ๋์ ๋ถ์ Dataset์ ๊ธฐ์กด ๋ฐ์ดํฐ์ ํฉ์ณ ์ ๋ก๋. | |
| ์คํจํด๋ ์ฐธ์ฌ์ ํ๋ฆ์ ๋ง์ง ์๋๋ก ์กฐ์ฉํ ํต๊ณผ(๋ฉ๋ชจ๋ฆฌ ๋ฐฑ์ ์ด ๋จ์ ์์). | |
| ๋ฐํ: (์ฑ๊ณต์ฌ๋ถ, ๋ฉ์์ง).""" | |
| if not _HAS_HF or not HF_TOKEN: | |
| return False, "HF_TOKEN ์์ โ ์ ๋ก๋ ๊ฑด๋๋(๋ค์ด๋ก๋ ๋ฐฑ์ ๋ง ์ฌ์ฉ)" | |
| try: | |
| api = HfApi() | |
| # ์ธ ์ข ๋ฅ(participants/messages/surveys) ๊ฐ๊ฐ: ๊ธฐ์กด + ์ด๋ฒ ์ธ์ โ ํฉ์ณ์ ์ ๋ก๋ | |
| for key, fname in FILES.items(): | |
| new_df = pd.DataFrame(state[f"rows_{key}"]) | |
| if new_df.empty: | |
| continue | |
| old_df = _download_existing(api, fname) | |
| merged = pd.concat([old_df, new_df], ignore_index=True) | |
| # ํน์ ๊ฐ์ ์ธ์ ์ ๋ ๋ฒ ์ฌ๋ ค ์๊ธฐ๋ ์์ ์ค๋ณต ํ ์ ๊ฑฐ | |
| merged = merged.drop_duplicates() | |
| _upload_csv(api, merged, fname) | |
| return True, "Dataset ์ ๋ก๋ ์๋ฃ" | |
| except Exception as e: | |
| return False, f"์ ๋ก๋ ์คํจ(๋ฌด์ํ๊ณ ์งํ): {e}" | |
| # โโ ์ฌ์ด๋๋ฐ ๋ค์ด๋ก๋์ฉ: ๋์ ๋ถ โ CSV ๋ฐ์ดํธ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def to_csv_bytes(rows): | |
| """๋์ ๋ฆฌ์คํธ โ UTF-8-SIG CSV(์์ ์์ ํ๊ธ ์ ๊นจ์ง). ๋น๋ฉด ๋น bytes.""" | |
| if not rows: | |
| return b"" | |
| return pd.DataFrame(rows).to_csv(index=False).encode("utf-8-sig") | |