github-actions[bot] commited on
Commit
e589290
Β·
1 Parent(s): a572e7a

sync from df72c1c

Browse files
Files changed (3) hide show
  1. README.md +2 -2
  2. app.py +245 -131
  3. requirements.txt +1 -1
README.md CHANGED
@@ -4,9 +4,9 @@ emoji: πŸ“Š
4
  colorFrom: red
5
  colorTo: yellow
6
  sdk: gradio
7
- sdk_version: "5.0"
8
  app_file: app.py
9
  pinned: true
10
  license: mit
11
- short_description: DART + EDGAR disclosure analysis β€” try without install
12
  ---
 
4
  colorFrom: red
5
  colorTo: yellow
6
  sdk: gradio
7
+ sdk_version: "6.10.0"
8
  app_file: app.py
9
  pinned: true
10
  license: mit
11
+ short_description: DART + EDGAR disclosure analysis
12
  ---
app.py CHANGED
@@ -4,6 +4,7 @@ from __future__ import annotations
4
 
5
  import gc
6
  import os
 
7
  import threading
8
  from collections import OrderedDict
9
 
@@ -20,6 +21,12 @@ _HAS_AI = bool(os.environ.get("OPENAI_API_KEY"))
20
  if _HAS_AI:
21
  dartlab.llm.configure(provider="openai", api_key=os.environ["OPENAI_API_KEY"])
22
 
 
 
 
 
 
 
23
 
24
  # ── μœ ν‹Έ ──────────────────────────────────────────────
25
 
@@ -61,28 +68,62 @@ def _warmup():
61
  threading.Thread(target=_warmup, daemon=True).start()
62
 
63
 
64
- # ── ν•Έλ“€λŸ¬: 검색 ─────────────────────────────────────
65
-
66
-
67
- def handleSearch(keyword: str):
68
- """μ’…λͺ© 검색."""
69
- if not keyword or not keyword.strip():
70
- return None
71
- df = dartlab.search(keyword.strip())
72
- return _toPandas(df)
73
-
74
-
75
- # ── ν•Έλ“€λŸ¬: κΈ°μ—… κ°œμš” + 재무 ─────────────────────────
76
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- def handleLoadCompany(code: str):
79
- """κΈ°μ—… κ°œμš” λ‘œλ“œ β†’ (기본정보 markdown, topics 리슀트, 재무 DataFrame)."""
80
- if not code or not code.strip():
81
- return "μ’…λͺ©μ½”λ“œλ₯Ό μž…λ ₯ν•˜μ„Έμš”.", gr.update(choices=[]), None
82
  try:
83
  c = _getCompany(code)
84
  except Exception as e:
85
- return f"λ‘œλ“œ μ‹€νŒ¨: {e}", gr.update(choices=[]), None
 
 
 
 
 
 
 
86
 
87
  # 기본정보
88
  info = f"## {c.corpName} ({c.stockCode})\n"
@@ -104,7 +145,12 @@ def handleLoadCompany(code: str):
104
  except Exception:
105
  pass
106
 
107
- return info, gr.update(choices=topics, value=topics[0] if topics else None), finance
 
 
 
 
 
108
 
109
 
110
  def handleFinance(code: str, sheet: str):
@@ -116,7 +162,7 @@ def handleFinance(code: str, sheet: str):
116
  except Exception:
117
  return None
118
 
119
- lookup = {"BS": "BS", "IS": "IS", "CF": "CF", "ratios": "ratios"}
120
  attr = lookup.get(sheet, "IS")
121
  try:
122
  result = getattr(c, attr, None)
@@ -125,9 +171,6 @@ def handleFinance(code: str, sheet: str):
125
  return None
126
 
127
 
128
- # ── ν•Έλ“€λŸ¬: Sections ──────────────────────────────────
129
-
130
-
131
  def handleShow(code: str, topic: str):
132
  """sections show β†’ DataFrame λ˜λŠ” Markdown."""
133
  if not code or not topic:
@@ -153,7 +196,10 @@ def handleChat(message: str, history: list, code: str):
153
  if not _HAS_AI:
154
  history = history + [
155
  {"role": "user", "content": message},
156
- {"role": "assistant", "content": "OPENAI_API_KEYκ°€ μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.\n\nHuggingFace Spaces Settings β†’ Variables and secretsμ—μ„œ μ„€μ •ν•˜μ„Έμš”."},
 
 
 
157
  ]
158
  return history, ""
159
 
@@ -161,16 +207,12 @@ def handleChat(message: str, history: list, code: str):
161
  if not stockCode:
162
  history = history + [
163
  {"role": "user", "content": message},
164
- {"role": "assistant", "content": "λ¨Όμ € Company νƒ­μ—μ„œ μ’…λͺ©μ„ λ‘œλ“œν•˜μ„Έμš”."},
165
  ]
166
  return history, ""
167
 
168
- # ask() 호좜 β€” raw=True둜 Generator λ°›μ•„μ„œ 슀트리밍
169
  try:
170
- if stockCode:
171
- query = f"{stockCode} {message}"
172
- else:
173
- query = message
174
  answer = dartlab.ask(query, stream=False, raw=False)
175
  except Exception as e:
176
  answer = f"뢄석 μ‹€νŒ¨: {e}"
@@ -185,119 +227,191 @@ def handleChat(message: str, history: list, code: str):
185
  # ── UI ────────────────────────────────────────────────
186
 
187
  _CSS = """
188
- .main-title { text-align: center; margin-bottom: 0.5em; }
189
- .subtitle { text-align: center; color: #666; margin-top: 0; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  """
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  with gr.Blocks(
193
- title="DartLab β€” DART/EDGAR κ³΅μ‹œ 뢄석",
194
- theme=gr.themes.Soft(),
195
  css=_CSS,
196
  ) as demo:
197
- gr.Markdown("# DartLab", elem_classes="main-title")
198
- gr.Markdown(
199
- "DART μ „μžκ³΅μ‹œ + EDGAR β€” μ’…λͺ©μ½”λ“œ ν•˜λ‚˜λ‘œ κΈ°μ—… 뢄석",
200
- elem_classes="subtitle",
201
- )
202
 
203
- # 곡유 state
204
- codeState = gr.State("")
 
 
 
 
 
 
205
 
206
- with gr.Tabs():
207
- # ── Tab 1: 검색 ──
208
- with gr.Tab("Search"):
209
- with gr.Row():
210
- searchInput = gr.Textbox(
211
- label="μ’…λͺ© 검색",
212
- placeholder="μ‚Όμ„±μ „μž, AAPL, 005930 ...",
213
- scale=4,
214
- )
215
- searchBtn = gr.Button("검색", scale=1, variant="primary")
216
- searchResult = gr.DataFrame(label="검색 κ²°κ³Ό", interactive=False)
217
-
218
- with gr.Row():
219
- selectedCode = gr.Textbox(
220
- label="μ’…λͺ©μ½”λ“œ μž…λ ₯ ν›„ 뢄석",
221
- placeholder="005930",
222
- scale=4,
223
- )
224
- loadBtn = gr.Button("λΆ„μ„ν•˜κΈ°", scale=1, variant="primary")
225
-
226
- searchBtn.click(handleSearch, inputs=searchInput, outputs=searchResult)
227
- searchInput.submit(handleSearch, inputs=searchInput, outputs=searchResult)
228
-
229
- # ── Tab 2: κΈ°μ—… + 재무 ──
230
- with gr.Tab("Company"):
231
- companyInfo = gr.Markdown("μ’…λͺ©μ½”λ“œλ₯Ό μž…λ ₯ν•˜κ³  'λΆ„μ„ν•˜κΈ°'λ₯Ό ν΄λ¦­ν•˜μ„Έμš”.")
232
-
233
- with gr.Row():
234
- sheetSelect = gr.Dropdown(
235
- choices=["IS", "BS", "CF", "ratios"],
236
- value="IS",
237
- label="μž¬λ¬΄μ œν‘œ",
238
- scale=1,
239
- )
240
- financeTable = gr.DataFrame(label="μž¬λ¬΄μ œν‘œ", interactive=False)
241
-
242
- sheetSelect.change(
243
- handleFinance,
244
- inputs=[codeState, sheetSelect],
245
- outputs=financeTable,
246
- )
247
 
248
- # ── Tab 3: Sections ──
249
- with gr.Tab("Sections"):
250
- gr.Markdown("topic Γ— period μˆ˜ν‰ν™” β€” κΈ°μ—…μ˜ 전체 지도")
251
- topicSelect = gr.Dropdown(
252
- choices=[],
253
- label="Topic",
254
- interactive=True,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  )
256
- sectionTable = gr.DataFrame(label="Section 데이터", interactive=False)
257
- sectionText = gr.Markdown("")
258
-
259
- topicSelect.change(
260
- handleShow,
261
- inputs=[codeState, topicSelect],
262
- outputs=[sectionTable, sectionText],
263
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
 
265
- # ── Tab 4: AI Chat ──
266
- with gr.Tab("AI Chat"):
267
- if not _HAS_AI:
268
- gr.Markdown(
269
- "**AI 뢄석을 μ‚¬μš©ν•˜λ €λ©΄** HuggingFace Spaces Settings β†’ "
270
- "Variables and secretsμ—μ„œ `OPENAI_API_KEY`λ₯Ό μ„€μ •ν•˜μ„Έμš”."
271
- )
272
- chatbot = gr.Chatbot(label="AI 뢄석", type="messages", height=500)
273
- with gr.Row():
274
- chatInput = gr.Textbox(
275
- label="질문",
276
- placeholder="μž¬λ¬΄κ±΄μ „μ„± λΆ„μ„ν•΄μ€˜, λ°°λ‹Ή 이상 μ§•ν›„ μ°Ύμ•„μ€˜ ...",
277
- scale=5,
278
- )
279
- chatBtn = gr.Button("전솑", scale=1, variant="primary")
280
-
281
- chatBtn.click(
282
- handleChat,
283
- inputs=[chatInput, chatbot, codeState],
284
- outputs=[chatbot, chatInput],
285
- )
286
- chatInput.submit(
287
- handleChat,
288
- inputs=[chatInput, chatbot, codeState],
289
- outputs=[chatbot, chatInput],
290
- )
291
 
292
- # ── λΆ„μ„ν•˜κΈ° λ²„νŠΌ β†’ Company νƒ­ λ‘œλ“œ ──
293
- loadBtn.click(
294
- lambda code: code.strip(),
295
- inputs=selectedCode,
296
- outputs=codeState,
297
- ).then(
298
- handleLoadCompany,
299
- inputs=selectedCode,
300
- outputs=[companyInfo, topicSelect, financeTable],
301
  )
302
 
303
 
 
4
 
5
  import gc
6
  import os
7
+ import re
8
  import threading
9
  from collections import OrderedDict
10
 
 
21
  if _HAS_AI:
22
  dartlab.llm.configure(provider="openai", api_key=os.environ["OPENAI_API_KEY"])
23
 
24
+ _LOGO_URL = "https://raw.githubusercontent.com/eddmpython/dartlab/master/.github/assets/logo.png"
25
+ _BLOG_URL = "https://eddmpython.github.io/dartlab/blog/dartlab-easy-start/"
26
+ _DOCS_URL = "https://eddmpython.github.io/dartlab/docs/getting-started/quickstart"
27
+ _COLAB_URL = "https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/showcase/01_quickstart.ipynb"
28
+ _REPO_URL = "https://github.com/eddmpython/dartlab"
29
+
30
 
31
  # ── μœ ν‹Έ ──────────────────────────────────────────────
32
 
 
68
  threading.Thread(target=_warmup, daemon=True).start()
69
 
70
 
71
+ # ── ν•Έλ“€λŸ¬: 톡합 뢄석 ────────────────────────────────
72
+
73
+
74
+ def handleAnalyze(query: str):
75
+ """μ’…λͺ©μ½”λ“œ λ˜λŠ” νšŒμ‚¬λͺ… β†’ 기업정보 + μž¬λ¬΄μ œν‘œ + topics."""
76
+ if not query or not query.strip():
77
+ return (
78
+ "μ’…λͺ©μ½”λ“œ λ˜λŠ” νšŒμ‚¬λͺ…을 μž…λ ₯ν•˜μ„Έμš”.",
79
+ "",
80
+ None,
81
+ gr.update(choices=[], value=None),
82
+ None,
83
+ "",
84
+ )
85
+
86
+ query = query.strip()
87
+
88
+ # μ’…λͺ©μ½”λ“œ νŒλ³„: 6자리 숫자 λ˜λŠ” 영문 티컀
89
+ if re.match(r"^\d{6}$", query) or re.match(r"^[A-Z]{1,5}$", query):
90
+ code = query
91
+ else:
92
+ # 검색 λ¨Όμ €
93
+ try:
94
+ results = dartlab.search(query)
95
+ if results is None or len(results) == 0:
96
+ return (
97
+ f"'{query}' 검색 κ²°κ³Όκ°€ μ—†μŠ΅λ‹ˆλ‹€. μ’…λͺ©μ½”λ“œ(예: 005930)λ‚˜ 티컀(예: AAPL)λ₯Ό 직접 μž…λ ₯ν•΄λ³΄μ„Έμš”.",
98
+ "",
99
+ None,
100
+ gr.update(choices=[], value=None),
101
+ None,
102
+ "",
103
+ )
104
+ code = str(results[0, "stockCode"])
105
+ except Exception as e:
106
+ return (
107
+ f"검색 μ‹€νŒ¨: {e}",
108
+ "",
109
+ None,
110
+ gr.update(choices=[], value=None),
111
+ None,
112
+ "",
113
+ )
114
 
115
+ # Company λ‘œλ“œ
 
 
 
116
  try:
117
  c = _getCompany(code)
118
  except Exception as e:
119
+ return (
120
+ f"κΈ°μ—… λ‘œλ“œ μ‹€νŒ¨: {e}",
121
+ "",
122
+ None,
123
+ gr.update(choices=[], value=None),
124
+ None,
125
+ "",
126
+ )
127
 
128
  # 기본정보
129
  info = f"## {c.corpName} ({c.stockCode})\n"
 
145
  except Exception:
146
  pass
147
 
148
+ topicUpdate = gr.update(
149
+ choices=topics,
150
+ value=topics[0] if topics else None,
151
+ )
152
+
153
+ return info, code, finance, topicUpdate, None, ""
154
 
155
 
156
  def handleFinance(code: str, sheet: str):
 
162
  except Exception:
163
  return None
164
 
165
+ lookup = {"IS": "IS", "BS": "BS", "CF": "CF", "ratios": "ratios"}
166
  attr = lookup.get(sheet, "IS")
167
  try:
168
  result = getattr(c, attr, None)
 
171
  return None
172
 
173
 
 
 
 
174
  def handleShow(code: str, topic: str):
175
  """sections show β†’ DataFrame λ˜λŠ” Markdown."""
176
  if not code or not topic:
 
196
  if not _HAS_AI:
197
  history = history + [
198
  {"role": "user", "content": message},
199
+ {
200
+ "role": "assistant",
201
+ "content": "OPENAI_API_KEYκ°€ μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.\n\nHuggingFace Spaces Settings β†’ Variables and secretsμ—μ„œ μ„€μ •ν•˜μ„Έμš”.",
202
+ },
203
  ]
204
  return history, ""
205
 
 
207
  if not stockCode:
208
  history = history + [
209
  {"role": "user", "content": message},
210
+ {"role": "assistant", "content": "λ¨Όμ € μƒλ‹¨μ—μ„œ μ’…λͺ©μ„ λΆ„μ„ν•˜μ„Έμš”."},
211
  ]
212
  return history, ""
213
 
 
214
  try:
215
+ query = f"{stockCode} {message}" if stockCode else message
 
 
 
216
  answer = dartlab.ask(query, stream=False, raw=False)
217
  except Exception as e:
218
  answer = f"뢄석 μ‹€νŒ¨: {e}"
 
227
  # ── UI ────────────────────────────────────────────────
228
 
229
  _CSS = """
230
+ /* ── dartlab λΈŒλžœλ”© ── */
231
+ .gradio-container {
232
+ background: #0a0d16 !important;
233
+ max-width: 960px !important;
234
+ }
235
+ .main-header {
236
+ text-align: center;
237
+ padding: 1.5rem 0 0.5rem;
238
+ }
239
+ .main-header img {
240
+ display: inline-block;
241
+ border-radius: 50%;
242
+ box-shadow: 0 0 32px rgba(234,70,71,0.25);
243
+ }
244
+ .main-header h1 {
245
+ color: #ea4647 !important;
246
+ font-size: 2.2rem !important;
247
+ margin: 0.5rem 0 0.2rem !important;
248
+ font-weight: 800 !important;
249
+ }
250
+ .main-header .tagline {
251
+ color: #94a3b8;
252
+ font-size: 1.05rem;
253
+ margin: 0;
254
+ }
255
+ .section-label {
256
+ color: #ea4647 !important;
257
+ font-weight: 700 !important;
258
+ font-size: 1.1rem !important;
259
+ margin: 1rem 0 0.3rem !important;
260
+ border-bottom: 1px solid #1e2433;
261
+ padding-bottom: 0.3rem;
262
+ }
263
+ .footer-links {
264
+ text-align: center;
265
+ padding: 1.5rem 0 0.5rem;
266
+ color: #64748b;
267
+ font-size: 0.9rem;
268
+ }
269
+ .footer-links a {
270
+ color: #94a3b8 !important;
271
+ text-decoration: none;
272
+ margin: 0 0.5rem;
273
+ }
274
+ .footer-links a:hover {
275
+ color: #ea4647 !important;
276
+ }
277
  """
278
 
279
+ _THEME = gr.themes.Base(
280
+ primary_hue=gr.themes.Color(
281
+ c50="#fef2f2", c100="#fee2e2", c200="#fecaca", c300="#fca5a5",
282
+ c400="#f87171", c500="#ea4647", c600="#dc2626", c700="#c83232",
283
+ c800="#991b1b", c900="#7f1d1d", c950="#450a0a",
284
+ ),
285
+ neutral_hue=gr.themes.Color(
286
+ c50="#f8fafc", c100="#f1f5f9", c200="#e2e8f0", c300="#cbd5e1",
287
+ c400="#94a3b8", c500="#64748b", c600="#475569", c700="#334155",
288
+ c800="#1e293b", c900="#0f172a", c950="#0a0d16",
289
+ ),
290
+ font=("system-ui", "-apple-system", "sans-serif"),
291
+ ).set(
292
+ body_background_fill="#0a0d16",
293
+ body_text_color="#f1f5f9",
294
+ block_background_fill="#0f1219",
295
+ block_border_color="#1e2433",
296
+ input_background_fill="#1a1f2b",
297
+ button_primary_background_fill="#ea4647",
298
+ button_primary_text_color="#ffffff",
299
+ button_secondary_background_fill="#1a1f2b",
300
+ button_secondary_text_color="#f1f5f9",
301
+ button_secondary_border_color="#1e2433",
302
+ )
303
+
304
+
305
  with gr.Blocks(
306
+ title="DartLab β€” μ’…λͺ©μ½”λ“œ ν•˜λ‚˜λ‘œ κΈ°μ—… 뢄석",
307
+ theme=_THEME,
308
  css=_CSS,
309
  ) as demo:
 
 
 
 
 
310
 
311
+ # ── 헀더 ──
312
+ gr.HTML(f"""
313
+ <div class="main-header">
314
+ <img src="{_LOGO_URL}" width="100" height="100" alt="DartLab">
315
+ <h1>DartLab</h1>
316
+ <p class="tagline">μ’…λͺ©μ½”λ“œ ν•˜λ‚˜. κΈ°μ—…μ˜ 전체 이야기.</p>
317
+ </div>
318
+ """)
319
 
320
+ # ── 곡유 state ──
321
+ codeState = gr.State("")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
 
323
+ # ── 톡합 μž…λ ₯ ──
324
+ with gr.Row():
325
+ queryInput = gr.Textbox(
326
+ label="μ’…λͺ©μ½”λ“œ λ˜λŠ” νšŒμ‚¬λͺ…",
327
+ placeholder="μ‚Όμ„±μ „μž, 005930, AAPL ...",
328
+ scale=4,
329
+ )
330
+ analyzeBtn = gr.Button("λΆ„μ„ν•˜κΈ°", scale=1, variant="primary", size="lg")
331
+
332
+ # ── κΈ°μ—… 정보 ──
333
+ companyInfo = gr.Markdown("μ’…λͺ©μ½”λ“œλ₯Ό μž…λ ₯ν•˜κ³  **λΆ„μ„ν•˜κΈ°**λ₯Ό ν΄λ¦­ν•˜μ„Έμš”.")
334
+
335
+ # ── μž¬λ¬΄μ œν‘œ ──
336
+ gr.Markdown("### μž¬λ¬΄μ œν‘œ", elem_classes="section-label")
337
+ with gr.Row():
338
+ sheetSelect = gr.Dropdown(
339
+ choices=["IS", "BS", "CF", "ratios"],
340
+ value="IS",
341
+ label="μ‹œνŠΈ",
342
+ scale=1,
343
+ )
344
+ financeTable = gr.DataFrame(label="μž¬λ¬΄μ œν‘œ", interactive=False)
345
+
346
+ # ── Sections ──
347
+ gr.Markdown("### Sections β€” topic Γ— period μˆ˜ν‰ν™”", elem_classes="section-label")
348
+ topicSelect = gr.Dropdown(
349
+ choices=[],
350
+ label="Topic",
351
+ interactive=True,
352
+ )
353
+ sectionTable = gr.DataFrame(label="Section 데이터", interactive=False)
354
+ sectionText = gr.Markdown("")
355
+
356
+ # ── AI Chat (μ ‘νž˜) ──
357
+ with gr.Accordion("AI 뢄석 (OpenAI API ν•„μš”)", open=False):
358
+ if not _HAS_AI:
359
+ gr.Markdown(
360
+ "**AI 뢄석을 μ‚¬μš©ν•˜λ €λ©΄** HuggingFace Spaces Settings β†’ "
361
+ "Variables and secretsμ—μ„œ `OPENAI_API_KEY`λ₯Ό μ„€μ •ν•˜μ„Έμš”."
362
  )
363
+ chatbot = gr.Chatbot(label="AI 뢄석", type="messages", height=400)
364
+ with gr.Row():
365
+ chatInput = gr.Textbox(
366
+ label="질문",
367
+ placeholder="μž¬λ¬΄κ±΄μ „μ„± λΆ„μ„ν•΄μ€˜, λ°°λ‹Ή 이상 μ§•ν›„ μ°Ύμ•„μ€˜ ...",
368
+ scale=5,
 
369
  )
370
+ chatBtn = gr.Button("전솑", scale=1, variant="primary")
371
+
372
+ chatBtn.click(
373
+ handleChat,
374
+ inputs=[chatInput, chatbot, codeState],
375
+ outputs=[chatbot, chatInput],
376
+ )
377
+ chatInput.submit(
378
+ handleChat,
379
+ inputs=[chatInput, chatbot, codeState],
380
+ outputs=[chatbot, chatInput],
381
+ )
382
+
383
+ # ── ν‘Έν„° ──
384
+ gr.HTML(f"""
385
+ <div class="footer-links">
386
+ <a href="{_BLOG_URL}">πŸ“– μ„€μΉ˜ κ°€μ΄λ“œ</a> Β·
387
+ <a href="{_DOCS_URL}">πŸ“˜ 곡식 λ¬Έμ„œ</a> Β·
388
+ <a href="{_COLAB_URL}">πŸ”¬ Colab</a> Β·
389
+ <a href="{_REPO_URL}">⭐ GitHub</a>
390
+ </div>
391
+ """)
392
+
393
+ # ── 이벀트 바인딩 ──
394
+ analyzeBtn.click(
395
+ handleAnalyze,
396
+ inputs=queryInput,
397
+ outputs=[companyInfo, codeState, financeTable, topicSelect, sectionTable, sectionText],
398
+ )
399
+ queryInput.submit(
400
+ handleAnalyze,
401
+ inputs=queryInput,
402
+ outputs=[companyInfo, codeState, financeTable, topicSelect, sectionTable, sectionText],
403
+ )
404
 
405
+ sheetSelect.change(
406
+ handleFinance,
407
+ inputs=[codeState, sheetSelect],
408
+ outputs=financeTable,
409
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
 
411
+ topicSelect.change(
412
+ handleShow,
413
+ inputs=[codeState, topicSelect],
414
+ outputs=[sectionTable, sectionText],
 
 
 
 
 
415
  )
416
 
417
 
requirements.txt CHANGED
@@ -1,2 +1,2 @@
1
  dartlab>=0.7.8
2
- gradio>=5.0,<6
 
1
  dartlab>=0.7.8
2
+ gradio>=6.0,<7