portfolio / web_client.py
eric2digit's picture
Upload folder using huggingface_hub
bf3714e verified
import argparse
import csv
import gradio as gr
import json
import os
import pandas as pd
import requests
from datetime import datetime
from io import StringIO
region_choices = ['us', 'ko']
user_portfolio_output_path = "used_user.csv"
json_example_output_path = "output_example.json"
json_new_output_path = "output.json"
report_example_output_path = "report_example.txt"
report_new_output_path = "report.txt"
def make_user_csv(csv_text, top_n):
""" ์‚ฌ์šฉ์ž ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ top_n๋งŒ user_portfolio_output_path์— ์ €์žฅ"""
df = load_portfolio_to_df(csv_text)
df['๋งค์ž…์ฃผ๊ฐ€'] = df['๋งค์ž…์ฃผ๊ฐ€'].astype(float)
df['๋ณด์œ ์ฃผ์‹์ˆ˜'] = df['๋ณด์œ ์ฃผ์‹์ˆ˜'].astype(float)
df['๋งค์ž…๊ธˆ์•ก'] = df['๋งค์ž…์ฃผ๊ฐ€'] * df['๋ณด์œ ์ฃผ์‹์ˆ˜']
df_sorted = df.sort_values(by='๋งค์ž…๊ธˆ์•ก', ascending=False)
df_top = df_sorted.head(top_n)
df_top = df_top[['์ข…๋ชฉ์ฝ”๋“œ', '์ข…๋ชฉ๋ช…', '๋งค์ž…์ฃผ๊ฐ€', '๋ณด์œ ์ฃผ์‹์ˆ˜']]
df_top.to_csv(user_portfolio_output_path, index=False, encoding='utf-8-sig')
return df_top # ๋ฐ˜ํ™˜๊ฐ’ DataFrame
def load_portfolio_to_df(csv_text):
"""csv_text๋ฅผ pandas DataFrame์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜"""
if isinstance(csv_text, str) and os.path.exists(csv_text):
return pd.read_csv(csv_text, dtype=str)
if isinstance(csv_text, str):
try:
return pd.read_csv(StringIO(csv_text), dtype=str)
except Exception as e:
raise ValueError(f"CSV ๋ฌธ์ž์—ด์„ DataFrame์œผ๋กœ ๋ณ€ํ™˜ ์‹คํŒจ: {e}")
if isinstance(csv_text, pd.DataFrame):
return csv_text.copy()
raise ValueError("csv_text๋Š” CSV ํŒŒ์ผ ๊ฒฝ๋กœ, CSV ๋ฌธ์ž์—ด ๋˜๋Š” DataFrame์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.")
def parse_csv(csv_text):
"""CSV ํ…์ŠคํŠธ โ†’ ์ข…๋ชฉ์ฝ”๋“œ ๋ฆฌ์ŠคํŠธ"""
try:
df = pd.read_csv(StringIO(csv_text))
except Exception:
return {"error": "csv_parse_failed", "detail": "CSV ํ˜•์‹์ด ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค."}
if "์ข…๋ชฉ์ฝ”๋“œ" not in df.columns:
return {"error": "missing_column", "detail": "'์ข…๋ชฉ์ฝ”๋“œ' ์ปฌ๋Ÿผ์ด ์—†์Šต๋‹ˆ๋‹ค."}
stock_list = df["์ข…๋ชฉ์ฝ”๋“œ"].astype(str).tolist()
return stock_list
def request_post(base_url: str, service: str, req_body: dict):
try:
url = f'{base_url}/{service}'
res = requests.post(
url=url,
json=req_body
)
res.raise_for_status()
except Exception as e:
print(f'[ERROR] {service} / ์—๋Ÿฌ ๋ฐœ์ƒ: {str(e)}')
res_body = res.json()
if res_body['success']:
return res_body['data']
def remove_duplicates(data_list):
"""stock ํ‚ค๊ฐ’ ๊ธฐ์ค€์œผ๋กœ ์ค‘๋ณต ์ œ๊ฑฐ"""
seen = set()
unique_list = []
for item in data_list:
stock_name = item.get('stock')
if stock_name and stock_name not in seen:
seen.add(stock_name)
unique_list.append(item)
return unique_list
def fetch_example_data():
"""json_example_output_path ๊ฒฝ๋กœ์˜ JSON ํŒŒ์ผ์„ ์ฝ์–ด dict ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜"""
if not os.path.exists(json_example_output_path):
print(f"[ERROR] ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: {json_example_output_path}")
return None
try:
user_name = "์ด์„œ์ค€"
region = 'us'
user_csv = """์ข…๋ชฉ์ฝ”๋“œ,์ข…๋ชฉ๋ช…,๋งค์ž…์ฃผ๊ฐ€,๋ณด์œ ์ฃผ์‹์ˆ˜
NVDA,NVIDIA Corporation,159.69,167
AMZN,"Amazon.com, Inc.",211.58,140
MSFT,Microsoft Corporation,527.99,131
AAPL,Apple Inc.,258.45,116
GOOGL,Alphabet Inc.,262.59,97
"""
processed_csv = make_user_csv(user_csv, top_n=5)
processed_csv.to_csv(user_portfolio_output_path, index=False, encoding="utf-8")
with open(user_portfolio_output_path, "r", encoding="utf-8") as f:
csv_data = f.read()
with open(json_example_output_path, "r", encoding="utf-8") as f:
json_data = json.load(f)
return user_name, region, csv_data, json_data
except Exception as e:
print(f"[ERROR] process_user_data ์˜ค๋ฅ˜: {e}")
return "", [], "", {}
def update_user_with_stock_price(json_data, res_data):
"""
res_data ๋กœ ๋ฐ›์€ stock_price ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ
json_data["user"] ํ•ญ๋ชฉ์— ํ˜„์žฌ์ฃผ๊ฐ€, ์ˆ˜์ต๋ฅ , ํ˜„์žฌ์ž์‚ฐ์„ ์—…๋ฐ์ดํŠธ
"""
def normalize(code):
return str(code).strip().upper()
# user ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ
user_list = json_data.get("user", [])
if not isinstance(user_list, list):
print("[WARN] user ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€ list ์•„๋‹˜ โ†’ ์—…๋ฐ์ดํŠธ ๋ถˆ๊ฐ€")
return
# ์ข…๋ชฉ ๊ฐ€๊ฒฉ dict(normalized)
stock_price_map = {normalize(k): v for k, v in res_data.items()}
# user ๊ฐ ํ•ญ๋ชฉ ์—…๋ฐ์ดํŠธ
for user_item in user_list:
raw_code = user_item.get("์ข…๋ชฉ์ฝ”๋“œ")
if not raw_code:
continue
code = normalize(raw_code)
# stock_price ์— ํ•ด๋‹น ์ข…๋ชฉ์ด ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ
prices = stock_price_map.get(code)
if not prices:
print(f"[WARN] {code} ์ข…๋ชฉ์˜ ์ฃผ๊ฐ€ ๋ฐ์ดํ„ฐ ์—†์Œ โ†’ user ์ถ”๊ฐ€์ •๋ณด ์Šคํ‚ต")
continue
# ์ตœ์‹  ์ข…๊ฐ€ (list ๋งˆ์ง€๋ง‰)
last_row = prices[-1]
try:
current_price = float(last_row.get("Close"))
buy_price = float(user_item.get("๋งค์ž…์ฃผ๊ฐ€"))
qty = float(user_item.get("๋ณด์œ ์ฃผ์‹์ˆ˜"))
except Exception:
print(f"[WARN] {code} ๊ฐ’ ๋ณ€ํ™˜ ์˜ค๋ฅ˜ โ†’ user ์ถ”๊ฐ€์ •๋ณด ์Šคํ‚ต")
continue
# ์ˆ˜์ต๋ฅ  ๊ณ„์‚ฐ
profit_rate = round(((current_price - buy_price) / buy_price) * 100, 2)
current_asset = round(current_price * qty, 2)
# ์—…๋ฐ์ดํŠธ
user_item["ํ˜„์žฌ์ฃผ๊ฐ€"] = str(current_price)
user_item["์ˆ˜์ต๋ฅ "] = f"{profit_rate}%"
user_item["ํ˜„์žฌ์ž์‚ฐ"] = str(current_asset)
# ์ €์žฅ
json_data["user"] = user_list
return json_data
def fetch_new_data(region, csv_text, server_url):
"""API ์‹คํ–‰: ์œ ์‚ฌ ํˆฌ์ž์ž ๋ฐ์ดํ„ฐ ์š”์ฒญ ํ›„ JSON ๋ฐ˜ํ™˜"""
try:
final_json = {}
portfolio = make_user_csv(csv_text, top_n=5) # user_portfolio_output_path ์ €์žฅ
# ===========================
# 1. ์œ ์‚ฌ ํˆฌ์žํšŒ์‚ฌ API
# ===========================
service = 'similar_investors'
req_body = {
'csv_text': portfolio.to_csv(index=False),
'region': region[0] if isinstance(region, list) else region,
'top': 5
}
print(f"[INFO] ์œ ์‚ฌ ํˆฌ์ž์ž {req_body['top']}๊ฐœ ์ˆ˜์ง‘ ์‹œ์ž‘..")
res_data = request_post(server_url, service, req_body)
if not res_data:
print(f'[ERROR] ์œ ์‚ฌ ํˆฌ์ž์ž ์ˆ˜์ง‘ ์‹คํŒจ..')
return None
print(f'[INFO] ์œ ์‚ฌ ํˆฌ์ž์ž ์ˆ˜์ง‘ ์™„๋ฃŒ:', res_data)
final_json[service] = res_data
# user ํ‚ค ์ €์žฅ
used_user_csv = portfolio.to_csv(index=False)
f = StringIO(used_user_csv)
reader = csv.reader(f)
rows = list(reader)
if not rows or len(rows) < 2:
print("[WARN] portfolio CSV ๋‚ด์šฉ์ด ๋น„์–ด ์žˆ์–ด user ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค.")
final_json["user"] = []
else:
headers = rows[0]
user_list = [dict(zip(headers, cols)) for cols in rows[1:]]
final_json["user"] = user_list
# ์‚ฐ์—…, ํ…Œ๋งˆ ์š”์ฒญ์‹œ ํˆฌ์ž์ž ์ข…๋ชฉ๋„ ํฌํ•จ
si_names = list(set([d['NAME'] for rows in res_data.values() for d in rows]))
si_companies = list(set([d['COMPANY'] for rows in res_data.values() for d in rows]))
# ===========================
# 2. ์œ ์‚ฌ ํˆฌ์žํšŒ์‚ฌ ์„ค๋ช… API
# ===========================
print("[INFO] ํˆฌ์žํšŒ์‚ฌ name ๋ชฉ๋ก:", si_names)
final_json["investment_company"] = {}
service = "investment_company"
for name in si_names:
print(f"[INFO] {name} ์„ค๋ช… ์ˆ˜์ง‘ ์‹œ์ž‘..")
req_body = {"name": name}
res_data = request_post(server_url, service, req_body)
if not res_data:
print("[ERROR] ์„ค๋ช… ์ˆ˜์ง‘ ์‹คํŒจ:", name)
final_json[service][name] = {
"error": True,
"detail": "request_post failed"
}
continue
print("[INFO] ์„ค๋ช… ์ˆ˜์ง‘ ์™„๋ฃŒ:", res_data)
final_json[service][name] = res_data
if not final_json[service]:
print(f'[ERROR] ์œ ์‚ฌ ํˆฌ์ž์ž ์ˆ˜์ง‘ ์‹คํŒจ..')
return None
# ===========================
# 3. ์‚ฐ์—…๊ตฐ API
# ===========================
service = 'industry_info'
stock = portfolio['์ข…๋ชฉ์ฝ”๋“œ'].to_list() + si_companies
req_body = {
'stock': stock
}
print(f'[INFO] ์‚ฐ์—…์ •๋ณด {",".join(stock)} ์ˆ˜์ง‘ ์‹œ์ž‘..')
res_data = request_post(server_url, service, req_body)
if not res_data:
print(f'[ERROR] ์‚ฐ์—…์ •๋ณด ์ˆ˜์ง‘ ์‹คํŒจ..')
return None
print(f'[INFO] ์‚ฐ์—…์ •๋ณด ์ˆ˜์ง‘ ์™„๋ฃŒ:', res_data)
res_data = remove_duplicates(res_data)
final_json[service] = res_data
# ===========================
# 4. ํ…Œ๋งˆ API
# ===========================
service = 'theme_info'
stock = portfolio['์ข…๋ชฉ์ฝ”๋“œ'].to_list() + si_companies
req_body = {
'stock': stock
}
print(f'[INFO] ํ…Œ๋งˆ์ •๋ณด {",".join(stock)} ์ˆ˜์ง‘ ์‹œ์ž‘..')
res_data = request_post(server_url, service, req_body)
if not res_data:
print(f'[ERROR] ํ…Œ๋งˆ์ •๋ณด ์ˆ˜์ง‘ ์‹คํŒจ..')
return None
print(f'[INFO] ํ…Œ๋งˆ์ •๋ณด ์ˆ˜์ง‘ ์™„๋ฃŒ:', res_data)
res_data = remove_duplicates(res_data)
final_json[service] = res_data
# ===========================
# 5. ์ฃผ๊ฐ€ API
# ===========================
service = 'stock_price'
stock = ','.join(portfolio['์ข…๋ชฉ์ฝ”๋“œ'])
req_body = {'stock': stock}
print(f'[INFO] ์ข…๋ชฉ๊ฐ€๊ฒฉ {stock} ์ˆ˜์ง‘ ์‹œ์ž‘..')
res_data = request_post(server_url, service, req_body)
if not res_data:
print(f'[ERROR] ์ข…๋ชฉ๊ฐ€๊ฒฉ ์ˆ˜์ง‘ ์‹คํŒจ..')
return None
print(f'[INFO] ์ข…๋ชฉ๊ฐ€๊ฒฉ ์ˆ˜์ง‘ ์™„๋ฃŒ:', res_data)
final_json[service] = res_data
update_user_with_stock_price(final_json, res_data)
# ===========================
# 6. ๋‰ด์Šค API
# ===========================
service = 'stock_news'
for stock in portfolio['์ข…๋ชฉ์ฝ”๋“œ']:
print(f'[INFO] ์ข…๋ชฉ๋‰ด์Šค {stock} ์ˆ˜์ง‘ ์‹œ์ž‘..')
req_body = {
'stock': stock,
'period': 7
}
res_data = request_post(server_url, service, req_body)
if res_data:
print(f'[INFO] ์ข…๋ชฉ๋‰ด์Šค {stock} ์ˆ˜์ง‘ ์™„๋ฃŒ:', res_data)
final_json.setdefault(service, {})
if isinstance(res_data, dict):
final_json[service].update(res_data)
else:
final_json[service][stock] = res_data
else:
print(f'[ERROR] ์ข…๋ชฉ๋‰ด์Šค {stock} ์ˆ˜์ง‘ ์‹คํŒจ..')
if not final_json.get(service):
print(f'[ERROR] ์ข…๋ชฉ๋‰ด์Šค ์ˆ˜์ง‘ ์‹คํŒจ..')
return None
try:
with open(json_new_output_path, "w", encoding="utf-8") as f:
json.dump(final_json, f, ensure_ascii=False, indent=4)
print(f"[INFO] {json_new_output_path}์— ์ €์žฅ ์™„๋ฃŒ")
except Exception as e:
print(f"[ERROR] {json_new_output_path} ์ €์žฅ ์˜ค๋ฅ˜:", str(e))
return final_json
except Exception as e:
print("[ERROR] ์‹คํ–‰ ์ค‘ ์˜ค๋ฅ˜:", str(e))
return {"error": "exception", "detail": str(e)}
def load_report():
"""report_example_output_path ๊ฒฝ๋กœ์˜ txt ํŒŒ์ผ์„ ์ฝ์–ด ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜"""
if not os.path.exists(report_example_output_path):
print(f"[ERROR] ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: {report_example_output_path}")
return ""
try:
with open(report_example_output_path, "r", encoding="utf-8") as f:
data = f.read()
return data
except Exception as e:
print(f"[ERROR] ํŒŒ์ผ ์ฝ๊ธฐ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
return ""
def generate_report(user_name, server_url, json):
"""์ตœ์ข… ๋ฆฌํฌํŠธ ์ƒ์„ฑ API ํ˜ธ์ถœ โ†’ user_name, csv, json ์ž…๋ ฅ"""
try:
print(f"[INFO] {user_name} ๋‹˜์„ ์œ„ํ•œ ํฌํŠธํด๋ฆฌ์˜ค ๋ถ„์„ ๋ฆฌํฌํŠธ ์ƒ์„ฑ")
with open(user_portfolio_output_path, "r", encoding="utf-8") as f:
csv_text = f.read()
payload = {
"date": datetime.now().strftime("%Y-%m-%d"), # ๋ฆฌํฌํŠธ ์ƒ์„ฑ ๋‚ ์งœ (๊ธฐ๋ณธ: ์˜ค๋Š˜ ๋‚ ์งœ)
"user_name": user_name,
"csv_text": csv_text,
"json_text": json
}
print("[INFO] ์ž…๋ ฅ๋ฐ์ดํ„ฐ ๋กœ๋“œ ์™„๋ฃŒ")
print("[INFO] ๋ฆฌํฌํŠธ ์ƒ์„ฑ ์ค‘ ... ")
resp = requests.post(f"{server_url}/report", json=payload)
if resp.status_code != 200:
return f"โŒ ๋ฆฌํฌํŠธ ์ƒ์„ฑ ์‹คํŒจ: {resp.text}"
data = resp.json()
report_md = data["data"]["report"]
print("[INFO] ๋ฆฌํฌํŠธ ์ƒ์„ฑ ์™„๋ฃŒ")
with open(report_new_output_path, "w", encoding="utf-8") as f:
f.write(report_md)
print(f"[INFO] {report_new_output_path}์— ์ €์žฅ ์™„๋ฃŒ\n")
return report_md
except FileNotFoundError:
return f"โŒ ์˜ค๋ฅ˜: {user_portfolio_output_path} ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."
except Exception as e:
return f"โŒ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}"
def enforce_single(selection):
"""
selection: ํ˜„์žฌ ์ฒดํฌ๋œ ๋ฆฌ์ŠคํŠธ (None or list)
๋ฐ˜ํ™˜๊ฐ’: ๋ฐ˜๋“œ์‹œ 1๊ฐœ๋งŒ ๋‹ด๊ธด ๋ฆฌ์ŠคํŠธ
"""
# ์‚ฌ์šฉ์ž ์ž…๋ ฅ์ด None ์ด๊ฑฐ๋‚˜ ๋น„์–ด์žˆ์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’ ๋ฐ˜ํ™˜
if not selection:
return [region_choices[0]]
# ์—ฌ๋Ÿฌ๊ฐœ ์„ ํƒ๋œ ๊ฒฝ์šฐ ๋งˆ์ง€๋ง‰ ์„ ํƒํ•œ ํ•ญ๋ชฉ๋งŒ ๋‚จ๊น€
if len(selection) > 1:
return [selection[-1]]
# ์ด๋ฏธ 1๊ฐœ๋ฉด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜
return selection
def main():
parser = argparse.ArgumentParser(description="Web Client")
parser.add_argument("--port", default=7864, type=int, help="Port number to run the Gradio app")
parser.add_argument("--server-url", default="http://localhost:8080" , type=str, help="Server url to run the app")
args = parser.parse_args()
with gr.Blocks() as app:
gr.Markdown("# ํฌํŠธํด๋ฆฌ์˜ค ๋ถ„์„ ๋ฆฌํฌํŠธ ๐Ÿ“ˆ ")
server_url = gr.State(args.server_url)
with gr.Row(scale=1):
with gr.Column(scale=1):
gr.Markdown("### 1. ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”.")
user_name = gr.Textbox(value="์ด์„œ์ค€", placeholder="์˜ˆ: ์ด์„œ์ค€ ", show_label=False)
with gr.Column(scale=1):
gr.Markdown("")
with gr.Row(scale=1):
with gr.Column(scale=1):
gr.Markdown("### 2. ์‚ฌ์šฉ์ž ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”.")
region_checkbox = gr.CheckboxGroup(choices=region_choices, value=[region_choices[0]], label="๋‹น์‹ ์˜ ํฌํŠธํด๋ฆฌ์˜ค์— ๊ฐ€์žฅ ๋ถ€ํ•ฉํ•˜๋Š” ์ง€์—ญ์„ ์„ ํƒํ•˜์„ธ์š”.")
region_checkbox.change(fn=enforce_single, inputs=region_checkbox, outputs=region_checkbox)
csv_input = gr.Textbox(
label="๋‹น์‹ ์„ ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”. (CSVํ˜•์‹) ",
lines=7,
max_lines=7,
value="์ข…๋ชฉ์ฝ”๋“œ,์ข…๋ชฉ๋ช…,๋งค์ž…์ฃผ๊ฐ€,๋ณด์œ ์ฃผ์‹์ˆ˜\n"
"TSLA,Tesla Inc.,227.34,88\n"
"META,Meta Platforms Inc.,484.12,52\n"
"NFLX,Netflix Inc.,598.43,31\n"
"AVGO,Broadcom Inc.,1421.77,12\n"
"CRM,Salesforce Inc.,289.24,63",
placeholder="์˜ˆ: \n"
"์ข…๋ชฉ์ฝ”๋“œ,์ข…๋ชฉ๋ช…,๋งค์ž…์ฃผ๊ฐ€,๋ณด์œ ์ฃผ์‹์ˆ˜\n"
"TSLA,Tesla Inc.,227.34,88\n"
"META,Meta Platforms Inc.,484.12,52\n"
"NFLX,Netflix Inc.,598.43,31\n"
"AVGO,Broadcom Inc.,1421.77,12\n"
"CRM,Salesforce Inc.,289.24,63",
interactive=True,
show_label=True
)
with gr.Column(scale=1):
gr.Markdown("")
with gr.Row(scale=1):
with gr.Column(scale=1):
gr.Markdown("### 3. ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค์„ธ์š”.")
with gr.Row(scale=1):
fetch_example_button = gr.Button("๊ธฐ์กด ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ")
fetch_new_button = gr.Button("์ƒˆ๋กœ์šด ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ์ƒ์„ฑํ•˜๊ธฐ")
with gr.Column(scale=1):
gr.Markdown("### 4. ํฌํŠธํด๋ฆฌ์˜ค ๋ถ„์„ ๋ฆฌํฌํŠธ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.")
with gr.Row(scale=1):
report_example_button = gr.Button("๊ธฐ์กด ๋ฆฌํฌํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ")
report_new_button = gr.Button("์ƒˆ๋กœ์šด ๋ฆฌํฌํŠธ ์ƒ์„ฑํ•˜๊ธฐ")
with gr.Row(scale=1):
json_output = gr.JSON(label="API ์‘๋‹ต(JSON)")
report_output = gr.Markdown()
fetch_example_button.click(
fn=fetch_example_data,
inputs=[],
outputs=[user_name, region_checkbox, csv_input, json_output]
)
fetch_new_button.click(
fn=fetch_new_data,
inputs=[region_checkbox, csv_input, server_url],
outputs=[json_output]
)
report_example_button.click(
fn=load_report,
inputs=[],
outputs=[report_output]
)
report_new_button.click(
fn=generate_report,
inputs=[user_name, server_url, json_output],
outputs=[report_output]
)
app.launch(theme='CultriX/gradio-theme', share=True, server_name="0.0.0.0", server_port=args.port, debug=True)
if __name__ == "__main__":
main()