JayLacoma commited on
Commit
bb36a68
·
verified ·
1 Parent(s): 1e83598

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -10
app.py CHANGED
@@ -9,6 +9,8 @@ import concurrent.futures
9
  import time
10
  from typing import Dict, List, Optional, Any, Tuple
11
  import logging
 
 
12
 
13
  # Set up logging
14
  logging.basicConfig(
@@ -335,7 +337,7 @@ async def analyze_tickers(
335
  logger.info(f"Analysis completed in {time.time() - start_time:.2f} seconds")
336
  return scores_table, metrics_table, bar_chart, radar_chart
337
 
338
- # Helper: Convert DataFrame to Markdown (for LLMs)
339
  def dataframe_to_markdown(df: pd.DataFrame) -> str:
340
  if df.empty:
341
  return ""
@@ -345,6 +347,21 @@ def dataframe_to_markdown(df: pd.DataFrame) -> str:
345
  rows = ["| " + " | ".join(str(val) for val in row) + " |" for _, row in df.iterrows()]
346
  return "\n".join([header, separator] + rows)
347
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  # Custom CSS for better appearance
349
  custom_css = """
350
  .gradio-container {
@@ -376,7 +393,9 @@ def create_gradio_interface():
376
  placeholder="AAPL, MSFT, GOOG, AMZN, TSLA",
377
  lines=1
378
  )
379
- analyze_btn = gr.Button("Analyze Stocks", variant="primary")
 
 
380
 
381
  with gr.Row():
382
  with gr.Column():
@@ -398,10 +417,6 @@ def create_gradio_interface():
398
  bar_chart_output = gr.Plot(label="Component Scores Chart")
399
  with gr.Column():
400
  radar_chart_output = gr.Plot(label="Top Stocks Comparison")
401
-
402
- # --- NEW: Compact Markdown copy boxes (only appear after analysis) ---
403
- scores_md = gr.Textbox(label="📋 Copy Scores as Markdown", value="", lines=3, max_lines=10, interactive=False)
404
- metrics_md = gr.Textbox(label="📋 Copy Metrics as Markdown", value="", lines=3, max_lines=10, interactive=False)
405
 
406
  with gr.TabItem("Help & Information"):
407
  gr.Markdown("""
@@ -427,16 +442,29 @@ def create_gradio_interface():
427
  Financial data is provided by Yahoo Finance via the yfinance package.
428
  """)
429
 
 
 
 
 
430
  def analyze_wrapper(*args):
431
  scores_df, metrics_df, bar_fig, radar_fig = asyncio.run(analyze_tickers(*args))
432
- scores_md_str = dataframe_to_markdown(scores_df)
433
- metrics_md_str = dataframe_to_markdown(metrics_df)
434
- return scores_df, metrics_df, bar_fig, radar_fig, scores_md_str, metrics_md_str
 
 
 
435
 
436
  analyze_btn.click(
437
  analyze_wrapper,
438
  inputs=[tickers_input, growth_weight, value_weight, risk_weight],
439
- outputs=[scores_output, metrics_output, bar_chart_output, radar_chart_output, scores_md, metrics_md]
 
 
 
 
 
 
440
  )
441
 
442
  return iface
 
9
  import time
10
  from typing import Dict, List, Optional, Any, Tuple
11
  import logging
12
+ import tempfile
13
+ import os
14
 
15
  # Set up logging
16
  logging.basicConfig(
 
337
  logger.info(f"Analysis completed in {time.time() - start_time:.2f} seconds")
338
  return scores_table, metrics_table, bar_chart, radar_chart
339
 
340
+ # Helper: Convert DataFrame to Markdown
341
  def dataframe_to_markdown(df: pd.DataFrame) -> str:
342
  if df.empty:
343
  return ""
 
347
  rows = ["| " + " | ".join(str(val) for val in row) + " |" for _, row in df.iterrows()]
348
  return "\n".join([header, separator] + rows)
349
 
350
+ # NEW: Generate downloadable .txt file with both tables
351
+ def download_tables(scores_df: pd.DataFrame, metrics_df: pd.DataFrame) -> str:
352
+ content = "# Stock Analysis Results\n\n"
353
+ content += "## Scores Table\n"
354
+ content += dataframe_to_markdown(scores_df) + "\n\n"
355
+ content += "## Financial Metrics Table\n"
356
+ content += dataframe_to_markdown(metrics_df) + "\n"
357
+
358
+ # Save to temporary file
359
+ temp_dir = tempfile.gettempdir()
360
+ path = os.path.join(temp_dir, "stock_analysis_tables.txt")
361
+ with open(path, "w", encoding="utf-8") as f:
362
+ f.write(content)
363
+ return path
364
+
365
  # Custom CSS for better appearance
366
  custom_css = """
367
  .gradio-container {
 
393
  placeholder="AAPL, MSFT, GOOG, AMZN, TSLA",
394
  lines=1
395
  )
396
+ with gr.Column():
397
+ analyze_btn = gr.Button("Analyze Stocks", variant="primary")
398
+ download_btn = gr.Button("📥 Download Tables (.txt)", variant="secondary")
399
 
400
  with gr.Row():
401
  with gr.Column():
 
417
  bar_chart_output = gr.Plot(label="Component Scores Chart")
418
  with gr.Column():
419
  radar_chart_output = gr.Plot(label="Top Stocks Comparison")
 
 
 
 
420
 
421
  with gr.TabItem("Help & Information"):
422
  gr.Markdown("""
 
442
  Financial data is provided by Yahoo Finance via the yfinance package.
443
  """)
444
 
445
+ # State to store last results
446
+ scores_state = gr.State(pd.DataFrame())
447
+ metrics_state = gr.State(pd.DataFrame())
448
+
449
  def analyze_wrapper(*args):
450
  scores_df, metrics_df, bar_fig, radar_fig = asyncio.run(analyze_tickers(*args))
451
+ return scores_df, metrics_df, bar_fig, radar_fig, scores_df, metrics_df
452
+
453
+ def download_wrapper(scores_df, metrics_df):
454
+ if scores_df.empty:
455
+ return None
456
+ return download_tables(scores_df, metrics_df)
457
 
458
  analyze_btn.click(
459
  analyze_wrapper,
460
  inputs=[tickers_input, growth_weight, value_weight, risk_weight],
461
+ outputs=[scores_output, metrics_output, bar_chart_output, radar_chart_output, scores_state, metrics_state]
462
+ )
463
+
464
+ download_btn.click(
465
+ download_wrapper,
466
+ inputs=[scores_state, metrics_state],
467
+ outputs=gr.File()
468
  )
469
 
470
  return iface