Download app.py from ssboost/f2sdfss-2: direct link, hf CLI and curl.
- Browser
- Download file 26.5 kB
-
https://huggingface.co/spaces/ssboost/f2sdfss-2/resolve/main/app.py
- Command line
-
hf download hf://spaces/ssboost/f2sdfss-2/app.py
-
curl -L -o app.py https://huggingface.co/spaces/ssboost/f2sdfss-2/resolve/main/app.py
26.5 kB
| #app.py | |
| import gradio as gr | |
| import pandas as pd | |
| import openpyxl | |
| import datetime | |
| import tempfile | |
| import os | |
| import uuid | |
| import time | |
| from openpyxl.utils.dataframe import dataframe_to_rows | |
| import pytz | |
| import random | |
| import google.generativeai as genai | |
| # ํ๊ฒฝ๋ณ์์์ ์ฝ๋ ๋ถ๋ฌ์ค๊ธฐ | |
| api_manager_code = os.getenv('API_MANAGER_CODE', '') | |
| styles_code = os.getenv('STYLES_CODE', '') | |
| review_analyzer_code = os.getenv('REVIEW_ANALYZER_CODE', '') | |
| # ๋์ ์ผ๋ก ์ฝ๋ ์คํํ์ฌ ํด๋์ค ์ ์ | |
| exec(api_manager_code) | |
| exec(review_analyzer_code) | |
| # ์คํ์ผ ์ ๋ณด ๋ถ๋ฌ์ค๊ธฐ | |
| fontawesome_link = """ | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" /> | |
| """ | |
| # ํ๊ฒฝ๋ณ์์์ CSS ๋ถ๋ฌ์ค๊ธฐ | |
| custom_css = os.getenv('CUSTOM_CSS', ''' | |
| :root { | |
| --primary-color: #FB7F0D; | |
| --secondary-color: #ff9a8b; | |
| --accent-color: #FF6B6B; | |
| --background-color: #FFF3E9; | |
| --card-bg: #ffffff; | |
| --text-color: #334155; | |
| --border-radius: 18px; | |
| --shadow: 0 8px 30px rgba(251, 127, 13, 0.08); | |
| } | |
| body { | |
| font-family: 'Pretendard', 'Noto Sans KR', -apple-system, BlinkMacSystemFont, sans-serif; | |
| background-color: var(--background-color); | |
| color: var(--text-color); | |
| line-height: 1.6; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| .gradio-container { | |
| width: 100%; | |
| margin: 0 auto; | |
| padding: 20px; | |
| background-color: var(--background-color); | |
| } | |
| .custom-header { | |
| background: #FF7F00; | |
| padding: 2rem; | |
| border-radius: 15px; | |
| margin-bottom: 20px; | |
| box-shadow: var(--shadow); | |
| text-align: center; | |
| } | |
| .custom-header h1 { | |
| margin: 0; | |
| font-size: 2.5rem; | |
| font-weight: 700; | |
| color: black; | |
| } | |
| .custom-header p { | |
| margin: 10px 0 0; | |
| font-size: 1.2rem; | |
| color: black; | |
| } | |
| .custom-frame { | |
| background-color: var(--card-bg); | |
| border: 1px solid rgba(0, 0, 0, 0.04); | |
| border-radius: var(--border-radius); | |
| padding: 20px; | |
| margin: 10px 0; | |
| box-shadow: var(--shadow); | |
| } | |
| .custom-button { | |
| border-radius: 30px !important; | |
| background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)) !important; | |
| color: white !important; | |
| font-size: 18px !important; | |
| padding: 10px 20px !important; | |
| border: none; | |
| box-shadow: 0 4px 8px rgba(251, 127, 13, 0.25); | |
| transition: transform 0.3s ease; | |
| } | |
| .custom-button:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 6px 12px rgba(251, 127, 13, 0.3); | |
| } | |
| .custom-title { | |
| font-size: 28px; | |
| font-weight: bold; | |
| margin-bottom: 10px; | |
| color: var(--text-color); | |
| border-bottom: 2px solid var(--primary-color); | |
| padding-bottom: 5px; | |
| } | |
| .gr-tabs-panel { | |
| background-color: var(--background-color) !important; | |
| box-shadow: none !important; | |
| } | |
| .custom-section-group { | |
| background-color: var(--background-color) !important; | |
| box-shadow: none !important; | |
| } | |
| .gr-textbox textarea, | |
| .gr-textbox input { | |
| border-radius: 12px !important; | |
| border: 2px solid rgba(251, 127, 13, 0.2) !important; | |
| font-size: 14px; | |
| transition: border-color 0.3s ease; | |
| } | |
| .gr-textbox textarea:focus, | |
| .gr-textbox input:focus { | |
| border-color: var(--primary-color) !important; | |
| box-shadow: 0 0 0 3px rgba(251, 127, 13, 0.1) !important; | |
| } | |
| .gr-file { | |
| border-radius: var(--border-radius) !important; | |
| border: 2px dashed var(--primary-color) !important; | |
| background-color: rgba(251, 127, 13, 0.05) !important; | |
| transition: all 0.3s ease; | |
| } | |
| .gr-file:hover { | |
| background-color: rgba(251, 127, 13, 0.1) !important; | |
| border-color: var(--secondary-color) !important; | |
| } | |
| @media (max-width: 768px) { | |
| .gradio-container { | |
| padding: 10px; | |
| } | |
| .custom-header h1 { | |
| font-size: 2rem; | |
| } | |
| .custom-title { | |
| font-size: 24px; | |
| } | |
| .custom-frame { | |
| padding: 15px; | |
| margin: 5px 0; | |
| } | |
| .custom-button { | |
| font-size: 16px !important; | |
| padding: 8px 16px !important; | |
| } | |
| } | |
| ''') | |
| class SessionManager: | |
| """์ธ์ ๋ณ ๋ฐ์ดํฐ ๊ด๋ฆฌ""" | |
| def __init__(self): | |
| self.sessions = {} | |
| def create_session(self): | |
| """์๋ก์ด ์ธ์ ์์ฑ""" | |
| session_id = str(uuid.uuid4()) | |
| self.sessions[session_id] = { | |
| 'created_at': time.time(), | |
| 'data': {}, | |
| 'temp_files': [] | |
| } | |
| return session_id | |
| def get_session_data(self, session_id, key, default=None): | |
| """์ธ์ ๋ฐ์ดํฐ ์กฐํ""" | |
| if session_id in self.sessions: | |
| return self.sessions[session_id]['data'].get(key, default) | |
| return default | |
| def set_session_data(self, session_id, key, value): | |
| """์ธ์ ๋ฐ์ดํฐ ์ ์ฅ""" | |
| if session_id in self.sessions: | |
| self.sessions[session_id]['data'][key] = value | |
| def add_temp_file(self, session_id, file_path): | |
| """์ธ์ ์ ์์ ํ์ผ ์ถ๊ฐ""" | |
| if session_id in self.sessions: | |
| self.sessions[session_id]['temp_files'].append(file_path) | |
| def cleanup_session(self, session_id): | |
| """์ธ์ ์ ๋ฆฌ""" | |
| if session_id in self.sessions: | |
| # ์์ ํ์ผ๋ค ์ญ์ | |
| for file_path in self.sessions[session_id]['temp_files']: | |
| try: | |
| if os.path.exists(file_path): | |
| os.remove(file_path) | |
| except Exception as e: | |
| print(f"ํ์ผ ์ญ์ ์ค๋ฅ: {e}") | |
| # ์ธ์ ๋ฐ์ดํฐ ์ญ์ | |
| del self.sessions[session_id] | |
| def cleanup_old_sessions(self, max_age_hours=2): | |
| """์ค๋๋ ์ธ์ ์ ๋ฆฌ (2์๊ฐ ์ด์)""" | |
| current_time = time.time() | |
| old_sessions = [] | |
| for session_id, session_data in self.sessions.items(): | |
| if (current_time - session_data['created_at']) > (max_age_hours * 3600): | |
| old_sessions.append(session_id) | |
| for session_id in old_sessions: | |
| self.cleanup_session(session_id) | |
| # ์ ์ญ ์ธ์ ๋งค๋์ | |
| session_manager = SessionManager() | |
| def create_app(): | |
| """๋ฉ์ธ Gradio ์ ํ๋ฆฌ์ผ์ด์ ์์ฑ""" | |
| demo = gr.Blocks(css=custom_css, theme=gr.themes.Default( | |
| primary_hue="orange", | |
| secondary_hue="orange", | |
| font=[gr.themes.GoogleFont("Noto Sans KR"), "ui-sans-serif", "system-ui"] | |
| )) | |
| with demo: | |
| gr.HTML(fontawesome_link) | |
| # ์ธ์ ID๋ฅผ ์จ๊ฒจ์ง ์ํ๋ก ๊ด๋ฆฌ | |
| session_id_state = gr.State(value="") | |
| # ์ธ์ ์ด๊ธฐํ ํจ์ | |
| def initialize_session(): | |
| session_id = session_manager.create_session() | |
| # ๊ฐ ์ธ์ ๋ง๋ค ์๋ก์ด ๋ถ์๊ธฐ ์ธ์คํด์ค ์์ฑ | |
| api_manager = APIManager() | |
| analyzer = ReviewAnalyzer(api_manager) | |
| session_manager.set_session_data(session_id, 'analyzer', analyzer) | |
| return session_id | |
| # ์ธ์ ๋ณ ๋ถ์๊ธฐ ๊ฐ์ ธ์ค๊ธฐ | |
| def get_session_analyzer(session_id): | |
| if not session_id: | |
| session_id = initialize_session() | |
| analyzer = session_manager.get_session_data(session_id, 'analyzer') | |
| if analyzer is None: | |
| api_manager = APIManager() | |
| analyzer = ReviewAnalyzer(api_manager) | |
| session_manager.set_session_data(session_id, 'analyzer', analyzer) | |
| return analyzer, session_id | |
| # ํญ ๊ตฌ์ฑ | |
| with gr.Tabs() as tabs: | |
| ############################# | |
| # ์์ ๋ถ์ ๋ชจ๋ | |
| ############################# | |
| with gr.TabItem("๐พ ์ค๋งํธ์คํ ์ด ์์ ๋ฆฌ๋ทฐ๋ฐ์ดํฐ ํ์ฉ"): | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ๋ฐ์ดํฐ ์ ๋ ฅ</div>") | |
| file_input = gr.File(label="์๋ณธ ์์ ํ์ผ ์ ๋ก๋", file_types=[".xlsx"]) | |
| year_radio = gr.Radio( | |
| choices=[f"{str(y)[-2:]}๋ " for y in range(2025, 2020, -1)], | |
| label="๋ถ์๋ ๋ ์ ํ", | |
| value="25๋ " | |
| ) | |
| analyze_button = gr.Button("์ต์ ๋ถ์ํ๊ธฐ", elem_classes="custom-button") | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ๋ถ์๋ณด๊ณ ์ ๋ค์ด๋ก๋</div>") | |
| download_final_output = gr.File(label="๋ณด๊ณ ์ ๋ค์ด๋ก๋") | |
| # ๋ฆฌ๋ทฐ๋ถ์ ์น์ | |
| with gr.Column(elem_classes="custom-frame", visible=False) as review_analysis_frame: | |
| gr.HTML("<div class='custom-title'>๐ ๋ฆฌ๋ทฐ๋ถ์</div>") | |
| top20_dropdown = gr.Dropdown( | |
| label="์์ดํ ์ต์ ๋ถ์", | |
| choices=["์ ์ฒด์ต์ ๋ถ์"], | |
| value="์ ์ฒด์ต์ ๋ถ์" | |
| ) | |
| review_button = gr.Button("๋ฆฌ๋ทฐ ๋ถ์ํ๊ธฐ", elem_classes="custom-button") | |
| # ๋ถ์ ๊ฒฐ๊ณผ ์น์ ๋ค | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>โจ ์ฃผ์๊ธ์ ๋ฆฌ๋ทฐ</div>") | |
| positive_output = gr.Textbox(label="๊ธ์ ๋ฆฌ๋ทฐ๋ฆฌ์คํธ (20๊ฐ)", lines=10, value="") | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>โจ ์ฃผ์๋ถ์ ๋ฆฌ๋ทฐ</div>") | |
| negative_output = gr.Textbox(label="๋ถ์ ๋ฆฌ๋ทฐ๋ฆฌ์คํธ (30๊ฐ)", lines=10, value="") | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ข ๊ธ์ ๋ฆฌ๋ทฐ ๋ถ์</div>") | |
| positive_analysis_output = gr.Textbox(label="๊ธ์ ๋ฆฌ๋ทฐ ๋ถ์", lines=8, value="") | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ข ๋ถ์ ๋ฆฌ๋ทฐ ๋ถ์</div>") | |
| negative_analysis_output = gr.Textbox(label="๋ถ์ ๋ฆฌ๋ทฐ ๋ถ์", lines=8, value="") | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ๋์ฆ์์ธ ๋ถ์</div>") | |
| insight_analysis_output = gr.Textbox(label="๋์ฆ์์ธ ๋ถ์", lines=8, value="") | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ง ์ํํ๋งค๋ฐฉํฅ์ฑ</div>") | |
| strategy_analysis_output = gr.Textbox(label="์ํํ๋งค๋ฐฉํฅ์ฑ", lines=8, value="") | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ์์ฑ์ ๋ต</div>") | |
| sourcing_analysis_output = gr.Textbox(label="์์ฑ์ ๋ต", lines=8, value="") | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ผ๏ธ ๋ง์ผํ ์ ๋ต</div>") | |
| detail_page_analysis_output = gr.Textbox(label="๋ง์ผํ ์ ๋ต", lines=8, value="") | |
| # ์ธ์ ๋ณ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํ ์จ๊ฒจ์ง ์ํ | |
| partial_file_state = gr.State(value=None) | |
| # ์ต์ ๋ถ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ | |
| def on_analyze_options(uploaded_file, selected_year, session_id): | |
| analyzer, session_id = get_session_analyzer(session_id) | |
| try: | |
| result = analyzer.analyze_options(uploaded_file, selected_year) | |
| print(f"analyze_options ๊ฒฐ๊ณผ ํ์ : {type(result)}") | |
| print(f"analyze_options ๊ฒฐ๊ณผ ๋ด์ฉ: {result}") | |
| partial_file = None | |
| top20_list = ["์ ์ฒด์ต์ ๋ถ์"] | |
| if result is not None: | |
| if isinstance(result, (list, tuple)) and len(result) >= 2: | |
| partial_file = result[0] | |
| top20_list = result[1] if result[1] else ["์ ์ฒด์ต์ ๋ถ์"] | |
| elif hasattr(result, '__getitem__'): | |
| try: | |
| partial_file = result[0] | |
| top20_list = result[1] if len(result) > 1 else ["์ ์ฒด์ต์ ๋ถ์"] | |
| except (IndexError, KeyError, TypeError): | |
| print("๊ฒฐ๊ณผ ์ธ๋ฑ์ฑ ์คํจ, ๊ธฐ๋ณธ๊ฐ ์ฌ์ฉ") | |
| if not isinstance(top20_list, list): | |
| top20_list = ["์ ์ฒด์ต์ ๋ถ์"] | |
| if len(top20_list) == 0: | |
| top20_list = ["์ ์ฒด์ต์ ๋ถ์"] | |
| if partial_file: | |
| session_manager.add_temp_file(session_id, partial_file) | |
| return ( | |
| partial_file, | |
| gr.update(visible=True if partial_file else False), | |
| gr.update(choices=top20_list, value=top20_list[0]), | |
| session_id | |
| ) | |
| except Exception as e: | |
| print(f"์ต์ ๋ถ์ ์ค๋ฅ: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return None, gr.update(visible=False), gr.update(choices=["์ ์ฒด์ต์ ๋ถ์"], value="์ ์ฒด์ต์ ๋ถ์"), session_id | |
| analyze_button.click( | |
| fn=on_analyze_options, | |
| inputs=[file_input, year_radio, session_id_state], | |
| outputs=[partial_file_state, review_analysis_frame, top20_dropdown, session_id_state] | |
| ) | |
| # ๋ฆฌ๋ทฐ ๋ถ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ | |
| def on_analyze_reviews(partial_file, selected_option, session_id): | |
| analyzer, session_id = get_session_analyzer(session_id) | |
| try: | |
| result = analyzer.analyze_reviews(partial_file, selected_option) | |
| if isinstance(result, tuple) and len(result) >= 9: | |
| results = result | |
| else: | |
| results = (None, "", "", "", "", "", "", "", "") | |
| final_file = results[0] | |
| if final_file: | |
| session_manager.add_temp_file(session_id, final_file) | |
| return results + (session_id,) | |
| except Exception as e: | |
| print(f"๋ฆฌ๋ทฐ ๋ถ์ ์ค๋ฅ: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return (None, "", "", "", "", "", "", "", "", session_id) | |
| review_button.click( | |
| fn=on_analyze_reviews, | |
| inputs=[partial_file_state, top20_dropdown, session_id_state], | |
| outputs=[download_final_output, positive_output, negative_output, | |
| positive_analysis_output, negative_analysis_output, | |
| insight_analysis_output, strategy_analysis_output, | |
| sourcing_analysis_output, detail_page_analysis_output, session_id_state] | |
| ) | |
| ############################# | |
| # ์ง์ ์ ๋ ฅ ๋ถ์ ๋ชจ๋ | |
| ############################# | |
| with gr.TabItem("๐ ์ง์ ์ ๋ ฅํ ์๋ฃํ์ฉ"): | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ๋ฆฌ๋ทฐ ์ง์ ์ ๋ ฅ</div>") | |
| direct_positive_input = gr.Textbox( | |
| label="๊ธ์ ๋ฆฌ๋ทฐ ์ ๋ ฅ", | |
| placeholder="๊ธ์ ๋ฆฌ๋ทฐ๋ฅผ ์ฌ๊ธฐ์ ์ ๋ ฅํ์ธ์.(์ต๋ 8000์)", | |
| lines=10, max_length=8000, value="" | |
| ) | |
| direct_negative_input = gr.Textbox( | |
| label="๋ถ์ ๋ฆฌ๋ทฐ ์ ๋ ฅ", | |
| placeholder="๋ถ์ ๋ฆฌ๋ทฐ๋ฅผ ์ฌ๊ธฐ์ ์ ๋ ฅํ์ธ์.(์ต๋ 8000์)", | |
| lines=10, max_length=8000, value="" | |
| ) | |
| direct_review_button = gr.Button("๋ฆฌ๋ทฐ ๋ถ์ํ๊ธฐ", elem_classes="custom-button") | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ๋ถ์๋ณด๊ณ ์ ๋ค์ด๋ก๋</div>") | |
| direct_download_output = gr.File(label="๋ถ์ ๋ณด๊ณ ์ ๋ค์ด๋ก๋") | |
| # ์ง์ ์ ๋ ฅ ๋ถ์ ๊ฒฐ๊ณผ | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ข ๊ธ์ ๋ฆฌ๋ทฐ๋ถ์</div>") | |
| direct_positive_analysis_output = gr.Textbox( | |
| label="๊ธ์ ๋ฆฌ๋ทฐ๋ถ์", lines=8, value="" | |
| ) | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ข ๋ถ์ ๋ฆฌ๋ทฐ๋ถ์</div>") | |
| direct_negative_analysis_output = gr.Textbox( | |
| label="๋ถ์ ๋ฆฌ๋ทฐ๋ถ์", lines=8, value="" | |
| ) | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ๋์ฆ์์ธ ๋ถ์</div>") | |
| direct_insight_analysis_output = gr.Textbox( | |
| label="๋์ฆ์์ธ ๋ถ์", lines=8, value="" | |
| ) | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ง ์ํํ๋งค๋ฐฉํฅ์ฑ</div>") | |
| direct_strategy_analysis_output = gr.Textbox( | |
| label="์ํํ๋งค๋ฐฉํฅ์ฑ", lines=8, value="" | |
| ) | |
| with gr.Row(): | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ์์ฑ์ ๋ต</div>") | |
| direct_sourcing_analysis_output = gr.Textbox( | |
| label="์์ฑ์ ๋ต", lines=8, value="" | |
| ) | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ผ๏ธ ๋ง์ผํ ์ ๋ต</div>") | |
| direct_detail_page_analysis_output = gr.Textbox( | |
| label="๋ง์ผํ ์ ๋ต", lines=8, value="" | |
| ) | |
| # ์ง์ ์ ๋ ฅ ๋ถ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ | |
| def on_direct_analyze(positive_input, negative_input, session_id): | |
| analyzer, session_id = get_session_analyzer(session_id) | |
| try: | |
| result = analyzer.analyze_direct_reviews(positive_input, negative_input) | |
| if isinstance(result, tuple) and len(result) >= 9: | |
| results = result | |
| else: | |
| results = (None, "", "", "", "", "", "", "", "") | |
| final_file = results[0] | |
| if final_file: | |
| session_manager.add_temp_file(session_id, final_file) | |
| return results + (session_id,) | |
| except Exception as e: | |
| print(f"์ง์ ๋ถ์ ์ค๋ฅ: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return (None, "", "", "", "", "", "", "", "", session_id) | |
| direct_review_button.click( | |
| fn=on_direct_analyze, | |
| inputs=[direct_positive_input, direct_negative_input, session_id_state], | |
| outputs=[direct_download_output, direct_positive_analysis_output, direct_negative_analysis_output, | |
| direct_insight_analysis_output, direct_strategy_analysis_output, | |
| direct_sourcing_analysis_output, direct_detail_page_analysis_output, session_id_state] | |
| ) | |
| # ์์ ์ ์ฉ ์น์ | |
| with gr.Column(elem_classes="custom-frame"): | |
| gr.HTML("<div class='custom-title'>๐ ์์ ์ ์ฉํ๊ธฐ</div>") | |
| with gr.Row(): | |
| example_excel_button = gr.Button("๐ ์์ ๋ถ์ ์์ ์ ์ฉํ๊ธฐ", elem_classes="custom-button") | |
| example_direct_button = gr.Button("๐ ์ง์ ์ ๋ ฅ ์์ ์ ์ฉํ๊ธฐ", elem_classes="custom-button") | |
| clear_all_button = gr.Button("๐๏ธ ์ ์ฒด ์ด๊ธฐํ", elem_classes="custom-button") | |
| # ์์ ์ ์ฉ ์ด๋ฒคํธ | |
| def apply_excel_example(session_id): | |
| analyzer, session_id = get_session_analyzer(session_id) | |
| excel_file, year = analyzer.apply_excel_example() | |
| return excel_file, year, session_id | |
| example_excel_button.click( | |
| fn=apply_excel_example, | |
| inputs=[session_id_state], | |
| outputs=[file_input, year_radio, session_id_state] | |
| ) | |
| def apply_direct_example(session_id): | |
| analyzer, session_id = get_session_analyzer(session_id) | |
| positive_text, negative_text = analyzer.apply_direct_example() | |
| return positive_text, negative_text, session_id | |
| example_direct_button.click( | |
| fn=apply_direct_example, | |
| inputs=[session_id_state], | |
| outputs=[direct_positive_input, direct_negative_input, session_id_state] | |
| ) | |
| # ์ ์ฒด ์ด๊ธฐํ ๊ธฐ๋ฅ | |
| def clear_all_data(session_id): | |
| if session_id: | |
| session_manager.cleanup_session(session_id) | |
| new_session_id = initialize_session() | |
| return ( | |
| None, "25๋ ", gr.update(visible=False), | |
| ["์ ์ฒด์ต์ ๋ถ์"], "์ ์ฒด์ต์ ๋ถ์", None, | |
| "", "", "", "", "", "", "", "", | |
| "", "", None, "", "", "", "", "", "", | |
| new_session_id | |
| ) | |
| clear_all_button.click( | |
| fn=clear_all_data, | |
| inputs=[session_id_state], | |
| outputs=[ | |
| file_input, year_radio, review_analysis_frame, | |
| top20_dropdown, top20_dropdown, | |
| download_final_output, | |
| positive_output, negative_output, | |
| positive_analysis_output, negative_analysis_output, | |
| insight_analysis_output, strategy_analysis_output, | |
| sourcing_analysis_output, detail_page_analysis_output, | |
| direct_positive_input, direct_negative_input, | |
| direct_download_output, | |
| direct_positive_analysis_output, direct_negative_analysis_output, | |
| direct_insight_analysis_output, direct_strategy_analysis_output, | |
| direct_sourcing_analysis_output, direct_detail_page_analysis_output, | |
| session_id_state | |
| ] | |
| ) | |
| # ํ์ด์ง ๋ก๋ ์ ์์ ํ ์ด๊ธฐํ | |
| def init_on_load(): | |
| session_id = initialize_session() | |
| return ( | |
| session_id, None, "25๋ ", gr.update(visible=False), | |
| gr.update(choices=["์ ์ฒด์ต์ ๋ถ์"], value="์ ์ฒด์ต์ ๋ถ์"), None, | |
| "", "", "", "", "", "", "", "", | |
| "", "", None, "", "", "", "", "", "" | |
| ) | |
| demo.load( | |
| fn=init_on_load, | |
| outputs=[ | |
| session_id_state, | |
| file_input, year_radio, review_analysis_frame, top20_dropdown, | |
| download_final_output, | |
| positive_output, negative_output, | |
| positive_analysis_output, negative_analysis_output, | |
| insight_analysis_output, strategy_analysis_output, | |
| sourcing_analysis_output, detail_page_analysis_output, | |
| direct_positive_input, direct_negative_input, | |
| direct_download_output, | |
| direct_positive_analysis_output, direct_negative_analysis_output, | |
| direct_insight_analysis_output, direct_strategy_analysis_output, | |
| direct_sourcing_analysis_output, direct_detail_page_analysis_output | |
| ] | |
| ) | |
| return demo | |
| if __name__ == "__main__": | |
| app = create_app() | |
| # ์ฃผ๊ธฐ์ ์ผ๋ก ์ค๋๋ ์ธ์ ์ ๋ฆฌ | |
| import threading | |
| def cleanup_timer(): | |
| while True: | |
| time.sleep(3600) | |
| session_manager.cleanup_old_sessions() | |
| cleanup_thread = threading.Thread(target=cleanup_timer, daemon=True) | |
| cleanup_thread.start() | |
| app.launch( | |
| share=False, | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| show_error=True, | |
| debug=False | |
| ) |