Update app.py
Browse files
app.py
CHANGED
@@ -1,114 +1,90 @@
|
|
1 |
-
|
2 |
-
import gradio as gr
|
3 |
import requests
|
|
|
4 |
from datetime import datetime
|
5 |
-
from transformers import
|
6 |
-
import os
|
7 |
|
8 |
-
#
|
9 |
-
|
10 |
-
login(token=os.environ.get("HF_TOKEN"), new_session=False)
|
11 |
|
12 |
-
#
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
SCHEDULE_URL = "https://open.neis.go.kr/hub/SchoolSchedule"
|
22 |
|
23 |
-
|
24 |
-
"
|
25 |
-
|
26 |
-
}
|
|
|
|
|
27 |
|
28 |
-
|
|
|
29 |
|
|
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
"SCHUL_NM": school_name,
|
38 |
-
"ATPT_OFCDC_SC_CODE": region_code
|
39 |
-
}
|
40 |
-
res = requests.get(SCHOOL_INFO_URL, params=params)
|
41 |
-
data = res.json()
|
42 |
-
try:
|
43 |
-
return data["schoolInfo"][1]["row"][0]["SD_SCHUL_CODE"], data["schoolInfo"][1]["row"][0]["ATPT_OFCDC_SC_CODE"]
|
44 |
-
except:
|
45 |
-
return None, None
|
46 |
-
|
47 |
-
|
48 |
-
def get_schedule(region_code, school_code, year, month):
|
49 |
-
from_ymd = f"{year}{month}01"
|
50 |
-
to_ymd = f"{year}{month}31"
|
51 |
-
params = {
|
52 |
-
"KEY": NEIS_KEY,
|
53 |
-
"Type": "json",
|
54 |
-
"pIndex": 1,
|
55 |
-
"pSize": 100,
|
56 |
-
"ATPT_OFCDC_SC_CODE": region_code,
|
57 |
-
"SD_SCHUL_CODE": school_code,
|
58 |
-
"AA_FROM_YMD": from_ymd,
|
59 |
-
"AA_TO_YMD": to_ymd
|
60 |
-
}
|
61 |
-
res = requests.get(SCHEDULE_URL, params=params)
|
62 |
-
data = res.json()
|
63 |
-
try:
|
64 |
-
return data["SchoolSchedule"][1]["row"]
|
65 |
-
except:
|
66 |
-
return []
|
67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
-
|
70 |
-
now = datetime.now()
|
71 |
-
if not year:
|
72 |
-
year = str(now.year)
|
73 |
-
if not month:
|
74 |
-
month = str(now.month).zfill(2)
|
75 |
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
|
80 |
-
|
81 |
-
if not school_code:
|
82 |
-
return "β νκ΅ μ 보λ₯Ό μ°Ύμ μ μμ΅λλ€."
|
83 |
|
84 |
-
|
85 |
-
if not schedule_rows:
|
86 |
-
schedule_text = "νμ¬ μΌμ μ 보λ μμ΅λλ€."
|
87 |
-
else:
|
88 |
-
schedule_text = "\n".join(f"{row['AA_YMD']}: {row['EVENT_NM']}" for row in schedule_rows)
|
89 |
-
|
90 |
-
prompt = f"""μΌμ μ 보:
|
91 |
-
{schedule_text}
|
92 |
-
|
93 |
-
μ¬μ©μ μ§λ¬Έ: {question}
|
94 |
-
|
95 |
-
μμ°μ€λ½κ² νκ΅μ΄λ‘ λλ΅ν΄ μ£ΌμΈμ."""
|
96 |
-
|
97 |
-
result = generator(prompt, max_new_tokens=200, temperature=0.7)[0]["generated_text"]
|
98 |
-
return result
|
99 |
-
|
100 |
-
|
101 |
-
with gr.Interface(
|
102 |
-
fn=generate_answer,
|
103 |
-
inputs=[
|
104 |
-
gr.Dropdown(choices=list(REGIONS.keys()), label="κ΅μ‘μ² μ ν"),
|
105 |
-
gr.Textbox(label="νκ΅λͺ
μ
λ ₯"),
|
106 |
-
gr.Textbox(label="λ
λ μ
λ ₯ (μ: 2025, λΉμλλ©΄ νμ¬ μ°λ μ¬μ©)"),
|
107 |
-
gr.Dropdown(choices=MONTH_NAMES, label="μ μ ν (μ: 07, λΉμλλ©΄ νμ¬ μ μ¬μ©)"),
|
108 |
-
gr.Textbox(label="μ§λ¬Έ μ
λ ₯ (μ: μ¬λ¦λ°©νμ μΈμ μΌ?)")
|
109 |
-
],
|
110 |
-
outputs=gr.Textbox(label="GPTμ μλ΅"),
|
111 |
-
title="π
νμ¬μΌμ + GPT μ±λ΄ (Gemma 2B)",
|
112 |
-
description="Gemma λͺ¨λΈ κΈ°λ°μ νμ¬μΌμ μ±λ΄μ
λλ€. μ°λ/μμ μλ΅ μ μ€λ κΈ°μ€μΌλ‘ μ²λ¦¬λ©λλ€."
|
113 |
-
) as app:
|
114 |
-
app.launch()
|
|
|
1 |
+
import os
|
|
|
2 |
import requests
|
3 |
+
import gradio as gr
|
4 |
from datetime import datetime
|
5 |
+
from transformers import pipeline
|
|
|
6 |
|
7 |
+
# ββββββββββββββββββββββββββββββ λͺ¨λΈ λΆλ¬μ€κΈ° ββββββββββββββββββββββββββββββ
|
8 |
+
llm = pipeline("text-generation", model="google/gemma-2-2b-it", max_new_tokens=512)
|
|
|
9 |
|
10 |
+
# ββββββββββββββββββββββββββββββ API μ²λ¦¬ ν¨μ ββββββββββββββββββββββββββββββ
|
11 |
+
def get_school_info(region_code, school_name, api_key):
|
12 |
+
url = f"https://open.neis.go.kr/hub/schoolInfo?KEY={api_key}&Type=json&pIndex=1&pSize=1&SCHUL_NM={school_name}&ATPT_OFCDC_SC_CODE={region_code}"
|
13 |
+
res = requests.get(url)
|
14 |
+
data = res.json()
|
15 |
+
school = data.get("schoolInfo", [{}])[1].get("row", [{}])[0]
|
16 |
+
return school.get("SD_SCHUL_CODE"), school.get("ATPT_OFCDC_SC_CODE")
|
17 |
+
|
18 |
+
def get_schedule(region_code, school_code, year, api_key):
|
19 |
+
from_ymd = f"{year}0101"
|
20 |
+
to_ymd = f"{year}1231"
|
21 |
+
url = f"https://open.neis.go.kr/hub/SchoolSchedule?KEY={api_key}&Type=json&pIndex=1&pSize=500&ATPT_OFCDC_SC_CODE={region_code}&SD_SCHUL_CODE={school_code}&AA_FROM_YMD={from_ymd}&AA_TO_YMD={to_ymd}"
|
22 |
+
res = requests.get(url)
|
23 |
+
data = res.json()
|
24 |
+
rows = data.get("SchoolSchedule", [{}])[1].get("row", [])
|
25 |
+
return rows
|
26 |
+
|
27 |
+
def summarize_schedule(rows, school_name, year):
|
28 |
+
lines = []
|
29 |
+
for row in rows:
|
30 |
+
date = row["AA_YMD"]
|
31 |
+
dt = datetime.strptime(date, "%Y%m%d").strftime("%-mμ %-dμΌ")
|
32 |
+
event = row["EVENT_NM"]
|
33 |
+
lines.append(f"{dt}: {event}")
|
34 |
+
text = "\n".join(lines)
|
35 |
+
prompt = f"{school_name}μ {year}λ
νμ¬μΌμ μ λ€μκ³Ό κ°λ€:\n{text}\nμ΄ λ΄μ©μ μμ½ν΄μ€. μ£Όμ μΌμ μ€μ¬μΌλ‘ κ°κ²°νκ²."
|
36 |
+
result = llm([{"role": "user", "content": prompt}])
|
37 |
+
return result[0]["generated_text"].replace(prompt, "").strip()
|
38 |
+
|
39 |
+
# ββββββββββββββββββββββββββββββ κ·ΈλΌλμ€ μΈν°νμ΄μ€ ν¨μ ββββββββββββββββββββββββββββββ
|
40 |
+
def load_and_summarize(region_code, school_name, year, month):
|
41 |
+
api_key = os.environ.get("NEIS_API_KEY", "a69e08342c8947b4a52cd72789a5ecaf")
|
42 |
+
|
43 |
+
if not school_name.strip():
|
44 |
+
return "β νκ΅λͺ
μ μ
λ ₯ν΄μ£ΌμΈμ.", "", ""
|
45 |
+
|
46 |
+
school_code, confirmed_region = get_school_info(region_code, school_name, api_key)
|
47 |
+
if not school_code:
|
48 |
+
return "β νκ΅ μ 보λ₯Ό μ°Ύμ μ μμ΅λλ€. μ
λ ₯μ νμΈν΄μ£ΌμΈμ.", "", ""
|
49 |
|
50 |
+
schedule_rows = get_schedule(confirmed_region, school_code, year, api_key)
|
51 |
+
if not schedule_rows:
|
52 |
+
return "βΉοΈ νμ¬μΌμ μ λ³΄κ° μμ΅λλ€.", "", ""
|
|
|
53 |
|
54 |
+
# μλ³ μΌμ νν°λ§
|
55 |
+
month_rows = [r for r in schedule_rows if r["AA_YMD"].startswith(f"{year}{month:02}")]
|
56 |
+
month_display = "\n".join(
|
57 |
+
f"{datetime.strptime(r['AA_YMD'], '%Y%m%d').strftime('%Y-%m-%d')} - {r['EVENT_NM']}"
|
58 |
+
for r in month_rows
|
59 |
+
) or "π μ νν μμ ν΄λΉνλ μΌμ μ΄ μμ΅λλ€."
|
60 |
|
61 |
+
# μμ½ μμ±
|
62 |
+
summary = summarize_schedule(schedule_rows, school_name, year)
|
63 |
|
64 |
+
return f"β
{school_name}μ {year}λ
{month}μ μΌμ μ
λλ€.", month_display, summary
|
65 |
|
66 |
+
# ββββββββββββββββββββββββββββββ Gradio UI κ΅¬μ± ββββββββββββββββββββββββββββββ
|
67 |
+
region_options = {
|
68 |
+
"B10": "μμΈ", "C10": "λΆμ°", "D10": "λꡬ", "E10": "μΈμ²", "F10": "κ΄μ£Ό", "G10": "λμ ",
|
69 |
+
"H10": "μΈμ°", "I10": "μΈμ’
", "J10": "κ²½κΈ°", "K10": "κ°μ", "M10": "μΆ©λΆ", "N10": "μΆ©λ¨",
|
70 |
+
"P10": "μ λΆ", "Q10": "μ λ¨", "R10": "κ²½λΆ", "S10": "κ²½λ¨", "T10": "μ μ£Ό"
|
71 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
|
73 |
+
with gr.Blocks(title="νμ¬μΌμ μμ½ μΊλ¦°λ") as demo:
|
74 |
+
gr.Markdown("## π« νμ¬μΌμ μ‘°ν λ° AI μμ½ (google/gemma-2-2b-it)")
|
75 |
+
with gr.Row():
|
76 |
+
region = gr.Dropdown(label="μ§μ κ΅μ‘μ²", choices=list(region_options.keys()), value="B10", interactive=True)
|
77 |
+
school_name = gr.Textbox(label="νκ΅λͺ
", placeholder="μ: μ리μ΄λ±νκ΅")
|
78 |
+
with gr.Row():
|
79 |
+
year = gr.Dropdown(label="λ
λ", choices=[2022, 2023, 2024, 2025], value=2024)
|
80 |
+
month = gr.Slider(label="μ", minimum=1, maximum=12, value=7, step=1)
|
81 |
|
82 |
+
btn = gr.Button("π
μΌμ λΆλ¬μ€κΈ° λ° μμ½")
|
|
|
|
|
|
|
|
|
|
|
83 |
|
84 |
+
status = gr.Markdown()
|
85 |
+
month_output = gr.Textbox(label="π μ νν μμ μΌμ ", lines=8)
|
86 |
+
summary_output = gr.Textbox(label="π 1λ
νμ¬μΌμ μμ½ (Gemma)", lines=6)
|
87 |
|
88 |
+
btn.click(fn=load_and_summarize, inputs=[region, school_name, year, month], outputs=[status, month_output, summary_output])
|
|
|
|
|
89 |
|
90 |
+
demo.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|