QAway-to commited on
Commit
56da3ec
·
1 Parent(s): 823e404

New style APP (Tab Changes v1.7)

Browse files
Files changed (2) hide show
  1. app.py +28 -7
  2. core/comparison_table.py +52 -0
app.py CHANGED
@@ -74,6 +74,25 @@ h2, h3, .gr-markdown {
74
  background: transparent !important;
75
  box-shadow: none !important;
76
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  """) as demo:
78
  gr.Markdown("## Investment Portfolio Analyzer")
79
  gr.Markdown(
@@ -94,13 +113,15 @@ h2, h3, .gr-markdown {
94
  analyze_output = gr.Textbox(label="Analysis Result", lines=15)
95
  analyze_button.click(fn=analyzer.run, inputs=portfolio_input, outputs=analyze_output)
96
 
97
- # --- Comparison Tab ---
98
- with gr.TabItem("Comparison"):
99
- compare_input_1 = gr.Textbox(label="Portfolio A", value='3852a354-e66e-4bc5-97e9-55124e31e687')
100
- compare_input_2 = gr.Textbox(label="Portfolio B", value='b1ef37aa-5b9a-41b4-9394-8823f2de36bb')
101
- compare_button = gr.Button("Compare Portfolios", variant="primary")
102
- compare_output = gr.Textbox(label="Comparison Result", lines=20)
103
- compare_button.click(fn=comparer.run, inputs=[compare_input_1, compare_input_2], outputs=compare_output)
 
 
104
 
105
  # --- Chat Assistant Tab ---
106
  with gr.TabItem("Assistant"):
 
74
  background: transparent !important;
75
  box-shadow: none !important;
76
  }
77
+ /* === Styled comparison table === */
78
+ .gr-dataframe table {
79
+ border-collapse: collapse !important;
80
+ width: 100% !important;
81
+ color: #c9d1d9 !important;
82
+ background-color: #161b22 !important;
83
+ }
84
+ .gr-dataframe th {
85
+ background-color: #21262d !important;
86
+ color: #f0f6fc !important;
87
+ font-weight: 600 !important;
88
+ text-transform: uppercase;
89
+ border-bottom: 1px solid #30363d !important;
90
+ }
91
+ .gr-dataframe td {
92
+ border-top: 1px solid #30363d !important;
93
+ padding: 8px !important;
94
+ }
95
+
96
  """) as demo:
97
  gr.Markdown("## Investment Portfolio Analyzer")
98
  gr.Markdown(
 
113
  analyze_output = gr.Textbox(label="Analysis Result", lines=15)
114
  analyze_button.click(fn=analyzer.run, inputs=portfolio_input, outputs=analyze_output)
115
 
116
+ # --- Comparison Table Tab ---
117
+ with gr.TabItem("Comparison Table"):
118
+ comp_input_1 = gr.Textbox(label="Portfolio A", value="3852a354-e66e-4bc5-97e9-55124e31e687")
119
+ comp_input_2 = gr.Textbox(label="Portfolio B", value="b1ef37aa-5b9a-41b4-9394-8823f2de36bb")
120
+ comp_button = gr.Button("Load Comparison", variant="primary")
121
+ comp_output = gr.Dataframe(label="Comparative Metrics", wrap=True)
122
+ from core.comparison_table import show_comparison_table
123
+ comp_button.click(fn=show_comparison_table, inputs=[comp_input_1, comp_input_2], outputs=comp_output)
124
+
125
 
126
  # --- Chat Assistant Tab ---
127
  with gr.TabItem("Assistant"):
core/comparison_table.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ 🇬🇧 Module: comparison_table.py
3
+ Purpose: Generates comparative DataFrame for two portfolios with styled metric differences.
4
+
5
+ 🇷🇺 Модуль: comparison_table.py
6
+ Назначение: создаёт сравнительную таблицу метрик двух портфелей в формате DataFrame
7
+ с визуальными индикаторами различий и форматированными значениями.
8
+ """
9
+
10
+ import pandas as pd
11
+ import asyncio
12
+ from services.output_api import fetch_metrics_async, extract_portfolio_id
13
+
14
+
15
+ def show_comparison_table(portfolio_a: str, portfolio_b: str):
16
+ """Public function for Gradio: build a styled comparison DataFrame."""
17
+ pid_a = extract_portfolio_id(portfolio_a)
18
+ pid_b = extract_portfolio_id(portfolio_b)
19
+ if not pid_a or not pid_b:
20
+ return "❌ Invalid portfolio IDs."
21
+
22
+ try:
23
+ df = asyncio.run(_build_comparison_df(pid_a, pid_b))
24
+ return df
25
+ except Exception as e:
26
+ return f"❌ Error building comparison table: {e}"
27
+
28
+
29
+ async def _build_comparison_df(p1: str, p2: str) -> pd.DataFrame:
30
+ """Async helper to build portfolio comparison DataFrame."""
31
+ m1 = await fetch_metrics_async(p1)
32
+ m2 = await fetch_metrics_async(p2)
33
+ if not m1 or not m2:
34
+ raise ValueError("Metrics unavailable for one or both portfolios.")
35
+
36
+ # Union of all metrics
37
+ all_keys = sorted(set(m1.keys()) | set(m2.keys()))
38
+ rows = []
39
+ for k in all_keys:
40
+ v1 = m1.get(k, 0)
41
+ v2 = m2.get(k, 0)
42
+ diff = v1 - v2
43
+ symbol = "▲" if diff > 0 else "▼" if diff < 0 else "—"
44
+ rows.append({
45
+ "Metric": k,
46
+ "Portfolio A": round(v1, 3),
47
+ "Portfolio B": round(v2, 3),
48
+ "Δ Difference": f"{symbol} {diff:+.3f}"
49
+ })
50
+
51
+ df = pd.DataFrame(rows, columns=["Metric", "Portfolio A", "Portfolio B", "Δ Difference"])
52
+ return df