From 6bcf78e5df46976a2da79884c9bacf639495a175 Mon Sep 17 00:00:00 2001 From: Bu5hm4nn Date: Wed, 1 Apr 2026 13:55:55 +0200 Subject: [PATCH] style: format UI files and remove lint excludes - Remove app/components/ and app/pages/ from ruff/black excludes - Pre-commit reformatted multi-line strings for consistency - All files now follow the same code style --- app/components/charts.py | 48 ++++++++++++------- app/components/strategy_panel.py | 6 ++- app/pages/event_comparison.py | 20 +++++--- app/pages/hedge.py | 12 ++--- app/pages/options.py | 8 ++-- app/pages/overview.py | 18 ++++--- app/pages/settings.py | 28 +++++++---- pyproject.toml | 7 --- tests/test_overview_ltv_history_playwright.py | 6 ++- 9 files changed, 94 insertions(+), 59 deletions(-) diff --git a/app/components/charts.py b/app/components/charts.py index aef4fca..41d945b 100644 --- a/app/components/charts.py +++ b/app/components/charts.py @@ -13,9 +13,11 @@ def _ensure_lightweight_charts_assets() -> None: global _CHARTS_SCRIPT_ADDED if _CHARTS_SCRIPT_ADDED: return - ui.add_head_html(""" + ui.add_head_html( + """ - """) + """ + ) _CHARTS_SCRIPT_ADDED = True @@ -46,7 +48,8 @@ class CandlestickChart: self._initialize_chart() def _initialize_chart(self) -> None: - ui.run_javascript(f""" + ui.run_javascript( + f""" (function() {{ const root = document.getElementById({json.dumps(self.chart_id)}); if (!root || typeof LightweightCharts === 'undefined') return; @@ -91,48 +94,57 @@ class CandlestickChart: indicators: {{}}, }}; }})(); - """) + """ + ) def set_candles(self, candles: list[dict[str, Any]]) -> None: payload = json.dumps(candles) - ui.run_javascript(f""" + ui.run_javascript( + f""" (function() {{ const ref = window.vaultDashCharts?.[{json.dumps(self.chart_id)}]; if (!ref) return; ref.candleSeries.setData({payload}); ref.chart.timeScale().fitContent(); }})(); - """) + """ + ) def update_price(self, candle: dict[str, Any]) -> None: payload = json.dumps(candle) - ui.run_javascript(f""" + ui.run_javascript( + f""" (function() {{ const ref = window.vaultDashCharts?.[{json.dumps(self.chart_id)}]; if (!ref) return; ref.candleSeries.update({payload}); }})(); - """) + """ + ) def set_volume(self, volume_points: list[dict[str, Any]]) -> None: payload = json.dumps(volume_points) - ui.run_javascript(f""" + ui.run_javascript( + f""" (function() {{ const ref = window.vaultDashCharts?.[{json.dumps(self.chart_id)}]; if (!ref) return; ref.volumeSeries.setData({payload}); }})(); - """) + """ + ) def update_volume(self, volume_point: dict[str, Any]) -> None: payload = json.dumps(volume_point) - ui.run_javascript(f""" + ui.run_javascript( + f""" (function() {{ const ref = window.vaultDashCharts?.[{json.dumps(self.chart_id)}]; if (!ref) return; ref.volumeSeries.update({payload}); }})(); - """) + """ + ) def set_indicator( self, @@ -144,7 +156,8 @@ class CandlestickChart: ) -> None: key = json.dumps(name) payload = json.dumps(points) - ui.run_javascript(f""" + ui.run_javascript( + f""" (function() {{ const ref = window.vaultDashCharts?.[{json.dumps(self.chart_id)}]; if (!ref) return; @@ -158,16 +171,19 @@ class CandlestickChart: }} ref.indicators[{key}].setData({payload}); }})(); - """) + """ + ) def update_indicator(self, name: str, point: dict[str, Any]) -> None: key = json.dumps(name) payload = json.dumps(point) - ui.run_javascript(f""" + ui.run_javascript( + f""" (function() {{ const ref = window.vaultDashCharts?.[{json.dumps(self.chart_id)}]; const series = ref?.indicators?.[{key}]; if (!series) return; series.update({payload}); }})(); - """) + """ + ) diff --git a/app/components/strategy_panel.py b/app/components/strategy_panel.py index e1cb165..35f66a3 100644 --- a/app/components/strategy_panel.py +++ b/app/components/strategy_panel.py @@ -117,7 +117,8 @@ class StrategyComparisonPanel: scenario_class = ( "text-emerald-600 dark:text-emerald-400" if scenario >= 0 else "text-rose-600 dark:text-rose-400" ) - rows.append(f""" + rows.append( + f""" {name} ${cost:,.2f} @@ -125,7 +126,8 @@ class StrategyComparisonPanel: {self._format_cap(strategy)} ${scenario:,.2f} - """) + """ + ) return f"""
diff --git a/app/pages/event_comparison.py b/app/pages/event_comparison.py index cc2cc78..06de039 100644 --- a/app/pages/event_comparison.py +++ b/app/pages/event_comparison.py @@ -119,10 +119,12 @@ def _render_event_comparison_page(workspace_id: str | None = None) -> None: ui.label( "Changing the preset resets strategy templates to that preset's default comparison set." ).classes("text-xs text-slate-500 dark:text-slate-400") - ui.label( - "Underlying units will be calculated from initial value ÷ entry spot." - ).classes("text-xs text-slate-500 dark:text-slate-400") - initial_value_input = ui.number("Initial portfolio value ($)", value=default_units * default_entry_spot, min=0.01, step=1000).classes("w-full") + ui.label("Underlying units will be calculated from initial value ÷ entry spot.").classes( + "text-xs text-slate-500 dark:text-slate-400" + ) + initial_value_input = ui.number( + "Initial portfolio value ($)", value=default_units * default_entry_spot, min=0.01, step=1000 + ).classes("w-full") loan_input = ui.number("Loan amount", value=default_loan, min=0, step=1000).classes("w-full") ltv_input = ui.number( "Margin call LTV", @@ -183,7 +185,11 @@ def _render_event_comparison_page(workspace_id: str | None = None) -> None: # Show validation errors (units_error takes priority, then entry_spot_error) display_error = units_error or entry_spot_error if display_error: - tone_class = "text-rose-600 dark:text-rose-300" if "must be positive" in display_error else "text-amber-700 dark:text-amber-300" + tone_class = ( + "text-rose-600 dark:text-rose-300" + if "must be positive" in display_error + else "text-amber-700 dark:text-amber-300" + ) ui.label(display_error).classes(f"text-sm {tone_class}") def render_result_state(title: str, message: str, *, tone: str = "info") -> None: @@ -243,7 +249,7 @@ def _render_event_comparison_page(workspace_id: str | None = None) -> None: scenario_label.set_text(units_error) render_selected_summary(entry_spot=preview_entry_spot, entry_spot_error=units_error) return units_error - + if workspace_id and config is not None and reseed_units: # Recalculate from workspace config workspace_units = asset_quantity_from_workspace_config( @@ -322,7 +328,7 @@ def _render_event_comparison_page(workspace_id: str | None = None) -> None: validation_label.set_text(units_error) render_result_state("Input validation failed", units_error, tone="warning") return - + report = service.run_read_only_comparison( preset_slug=str(preset_select.value or ""), template_slugs=template_slugs, diff --git a/app/pages/hedge.py b/app/pages/hedge.py index cc4e56d..213afcb 100644 --- a/app/pages/hedge.py +++ b/app/pages/hedge.py @@ -88,9 +88,7 @@ async def _resolve_hedge_spot(workspace_id: str | None = None) -> tuple[dict[str data_service = get_data_service() underlying = config.underlying or "GLD" quote = await data_service.get_quote(underlying) - spot, source, updated_at = resolve_portfolio_spot_from_quote( - config, quote, fallback_symbol=underlying - ) + spot, source, updated_at = resolve_portfolio_spot_from_quote(config, quote, fallback_symbol=underlying) portfolio = portfolio_snapshot(config, runtime_spot_price=spot) return portfolio, source, updated_at except Exception as exc: @@ -114,14 +112,14 @@ async def _render_hedge_page(workspace_id: str | None = None) -> None: } display_mode = portfolio.get("display_mode", "XAU") - + if display_mode == "GLD": spot_unit = "/share" spot_desc = "GLD share price" else: spot_unit = "/oz" spot_desc = "converted collateral spot" - + if quote_source == "configured_entry_price": spot_label = f"Current spot reference: ${portfolio['spot_price']:,.2f}{spot_unit} (configured entry price)" else: @@ -251,7 +249,7 @@ async def _render_hedge_page(workspace_id: str | None = None) -> None: def render_summary() -> None: metrics = strategy_metrics(selected["strategy"], selected["scenario_pct"], portfolio=portfolio) strategy = metrics["strategy"] - + # Display mode-aware labels if display_mode == "GLD": weight_unit = "shares" @@ -261,7 +259,7 @@ async def _render_hedge_page(workspace_id: str | None = None) -> None: weight_unit = "oz" price_unit = "/oz" hedge_cost_unit = "/oz" - + summary.clear() with summary: ui.label("Scenario Summary").classes("text-lg font-semibold text-slate-900 dark:text-slate-100") diff --git a/app/pages/options.py b/app/pages/options.py index a3dd677..444a4cd 100644 --- a/app/pages/options.py +++ b/app/pages/options.py @@ -88,9 +88,7 @@ async def options_page() -> None: def filtered_rows() -> list[dict[str, Any]]: return [ - row - for row in chain_state["rows"] - if strike_range["min"] <= float(row["strike"]) <= strike_range["max"] + row for row in chain_state["rows"] if strike_range["min"] <= float(row["strike"]) <= strike_range["max"] ] def render_selection() -> None: @@ -186,7 +184,9 @@ async def options_page() -> None: next_chain = await data_service.get_options_chain_for_expiry("GLD", expiry) chain_state["data"] = next_chain - chain_state["rows"] = list(next_chain.get("rows") or [*next_chain.get("calls", []), *next_chain.get("puts", [])]) + chain_state["rows"] = list( + next_chain.get("rows") or [*next_chain.get("calls", []), *next_chain.get("puts", [])] + ) min_value, max_value = strike_bounds(chain_state["rows"]) strike_range["min"] = min_value diff --git a/app/pages/overview.py b/app/pages/overview.py index 926bda0..666881f 100644 --- a/app/pages/overview.py +++ b/app/pages/overview.py @@ -124,11 +124,13 @@ def welcome_page(request: Request): if turnstile.uses_test_keys else "" ) - ui.html(f""" + ui.html( + f""" {hidden_token}
- """) + """ + ) ui.label("You can always create a fresh workspace later if a link is lost.").classes( "text-sm text-slate-500 dark:text-slate-400" ) @@ -174,7 +176,11 @@ async def overview_page(workspace_id: str) -> None: current_values[str(pos.id)] = pos.entry_value total_annual_storage_cost = calculate_total_storage_cost(positions, current_values) portfolio["annual_storage_cost"] = float(total_annual_storage_cost) - portfolio["storage_cost_pct"] = (float(total_annual_storage_cost) / float(portfolio["gold_value"]) * 100) if portfolio["gold_value"] > 0 else 0.0 + portfolio["storage_cost_pct"] = ( + (float(total_annual_storage_cost) / float(portfolio["gold_value"]) * 100) + if portfolio["gold_value"] > 0 + else 0.0 + ) alert_status = AlertService().evaluate(config, portfolio) ltv_history_service = LtvHistoryService(repository=LtvHistoryRepository(base_path=repo.base_path)) @@ -197,7 +203,7 @@ async def overview_page(workspace_id: str) -> None: ltv_history_csv = "" ltv_history_notice = "Historical LTV is temporarily unavailable due to a storage error." display_mode = portfolio.get("display_mode", "XAU") - + if portfolio["quote_source"] == "configured_entry_price": if display_mode == "GLD": quote_status = "Live quote source: configured entry price fallback (GLD shares) · Last updated Unavailable" @@ -342,7 +348,7 @@ async def overview_page(workspace_id: str) -> None: "w-full rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900" ): ui.label("Portfolio Snapshot").classes("text-lg font-semibold text-slate-900 dark:text-slate-100") - + # Display mode-aware labels if display_mode == "GLD": spot_label = "GLD Share Price" @@ -352,7 +358,7 @@ async def overview_page(workspace_id: str) -> None: spot_label = "Collateral Spot Price" spot_unit = "/oz" margin_label = "Margin Call Price" - + with ui.grid(columns=1).classes("w-full gap-4 sm:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2"): summary_cards = [ ( diff --git a/app/pages/settings.py b/app/pages/settings.py index b52e4dc..d9641f8 100644 --- a/app/pages/settings.py +++ b/app/pages/settings.py @@ -263,9 +263,9 @@ def settings_page(workspace_id: str) -> None: value=config.display_mode, label="Display mode", ).classes("w-full") - + ui.separator().classes("my-4") - + ui.label("Data Sources").classes("text-lg font-semibold text-slate-900 dark:text-slate-100") underlying = ui.select( { @@ -384,8 +384,12 @@ def settings_page(workspace_id: str) -> None: ).classes("w-full") ui.separator().classes("my-3") - ui.label("Storage Costs (optional)").classes("text-sm font-semibold text-slate-700 dark:text-slate-300") - ui.label("For physical gold (XAU), defaults to 0.12% annual vault storage.").classes("text-xs text-slate-500 dark:text-slate-400 mb-2") + ui.label("Storage Costs (optional)").classes( + "text-sm font-semibold text-slate-700 dark:text-slate-300" + ) + ui.label("For physical gold (XAU), defaults to 0.12% annual vault storage.").classes( + "text-xs text-slate-500 dark:text-slate-400 mb-2" + ) pos_storage_cost_basis = ui.number( "Storage cost (% per year or fixed $)", @@ -401,8 +405,12 @@ def settings_page(workspace_id: str) -> None: ).classes("w-full") ui.separator().classes("my-3") - ui.label("Premium & Spread (optional)").classes("text-sm font-semibold text-slate-700 dark:text-slate-300") - ui.label("For physical gold, accounts for dealer markup and bid/ask spread.").classes("text-xs text-slate-500 dark:text-slate-400 mb-2") + ui.label("Premium & Spread (optional)").classes( + "text-sm font-semibold text-slate-700 dark:text-slate-300" + ) + ui.label("For physical gold, accounts for dealer markup and bid/ask spread.").classes( + "text-xs text-slate-500 dark:text-slate-400 mb-2" + ) pos_purchase_premium = ui.number( "Purchase premium over spot (%)", @@ -429,10 +437,14 @@ def settings_page(workspace_id: str) -> None: try: underlying = str(pos_underlying.value) storage_cost_basis_val = float(pos_storage_cost_basis.value) - storage_cost_basis = Decimal(str(storage_cost_basis_val)) if storage_cost_basis_val > 0 else None + storage_cost_basis = ( + Decimal(str(storage_cost_basis_val)) if storage_cost_basis_val > 0 else None + ) storage_cost_period = str(pos_storage_cost_period.value) if storage_cost_basis else None purchase_premium_val = float(pos_purchase_premium.value) - purchase_premium = Decimal(str(purchase_premium_val / 100)) if purchase_premium_val > 0 else None + purchase_premium = ( + Decimal(str(purchase_premium_val / 100)) if purchase_premium_val > 0 else None + ) bid_ask_spread_val = float(pos_bid_ask_spread.value) bid_ask_spread = Decimal(str(bid_ask_spread_val / 100)) if bid_ask_spread_val > 0 else None diff --git a/pyproject.toml b/pyproject.toml index 2d2c332..e0303ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,6 @@ requires-python = ">=3.11" [tool.ruff] line-length = 120 -exclude = ["app/components/*.py", "app/pages/*.py"] [tool.ruff.lint] select = ["E4", "E7", "E9", "F", "I"] @@ -14,12 +13,6 @@ select = ["E4", "E7", "E9", "F", "I"] [tool.black] line-length = 120 target-version = ["py312"] -extend-exclude = ''' -/( - app/components - | app/pages -)/ -''' [tool.mypy] ignore_missing_imports = true diff --git a/tests/test_overview_ltv_history_playwright.py b/tests/test_overview_ltv_history_playwright.py index 2a6d4a8..54caf26 100644 --- a/tests/test_overview_ltv_history_playwright.py +++ b/tests/test_overview_ltv_history_playwright.py @@ -26,14 +26,16 @@ def test_overview_shows_ltv_history_and_exports_csv() -> None: expect(page.locator("text=90 Day").first).to_be_visible(timeout=15000) expect(page.get_by_role("button", name="Export CSV")).to_be_visible(timeout=15000) - series_names = page.evaluate(""" + series_names = page.evaluate( + """ async () => { const importMap = JSON.parse(document.querySelector('script[type="importmap"]').textContent).imports; const mod = await import(importMap['nicegui-echart']); const chart = mod.echarts.getInstanceByDom(document.querySelector('.nicegui-echart')); return chart ? chart.getOption().series.map(series => series.name) : []; } - """) + """ + ) assert series_names == ["LTV", "Margin threshold"] with page.expect_download() as download_info: