import locale import numbers import os from starlette.templating import Jinja2Templates TRANSACTION_TYPE_DE = { "deposit": "Einzahlung", "withdrawal": "Auszahlung", "expense": "Auslage", "order": "Einkauf", } UNITS_OF_MEASURE = {"piece": "Stück"} def format_number(value: float): try: return f"{value:.2f}".replace(".", ",") except TypeError: return value def get_jinja_renderer() -> Jinja2Templates: renderer = Jinja2Templates(directory="src/allmende_payment_system/templates") renderer.env.filters["transaction_type_de"] = lambda x: TRANSACTION_TYPE_DE[x] renderer.env.filters["units_of_measure_de"] = lambda x: UNITS_OF_MEASURE.get(x, x) renderer.env.filters["format_number"] = format_number renderer.env.filters["timestamp_de"] = lambda x: x.strftime("%d.%m.%Y %H:%M") renderer.env.globals["production_mode"] = "APS_PRODUCTION_MODE" in os.environ renderer.env.globals["read_only_mode"] = "APS_READ_ONLY" in os.environ return renderer def timer_context(name: str): import time class Timer: def __enter__(self): self.start = time.perf_counter() def __exit__(self, exc_type, exc_val, exc_tb): end = time.perf_counter() print(f"{name} took {end - self.start:.4f} seconds") return Timer() import cProfile import io import pstats from contextlib import contextmanager @contextmanager def profile(top_n: int = 20, sort_by: str = "cumulative", min_time: float = 0.001): pr = cProfile.Profile() pr.enable() try: yield finally: pr.disable() s = io.StringIO() ps = pstats.Stats(pr, stream=s).strip_dirs() ps.sort_stats(sort_by) ps.print_stats() rows = [] for line in s.getvalue().splitlines(): parts = line.split(None, 5) if len(parts) < 6: continue try: cum = float(parts[3]) if cum >= min_time: rows.append( ( int(parts[0].split("/")[0]), float(parts[1]), cum, float(parts[4]), parts[5].strip(), ) ) except (ValueError, IndexError): continue rows = rows[:top_n] if not rows: print("[profiler] nothing exceeded min_time threshold") return w = 55 print(f"\n── profile ({sort_by}, ≥{min_time}s) ──────────────────────────────") print(f"{'calls':>7} {'tot':>8} {'cum':>8} {'percall':>8} {'function':<{w}}") print("─" * (7 + 8 + 8 + 8 + w + 6)) for calls, tot, cum, percall, loc in rows: c = ( f"\033[91m{cum:8.4f}\033[0m" if cum > 1 else f"\033[93m{cum:8.4f}\033[0m" if cum > 0.1 else f"{cum:8.4f}" ) print( f"{calls:>7} {tot:8.4f} {c} {percall:8.4f} {loc[-w:] if len(loc) > w else loc:<{w}}" ) print(f"─" * (7 + 8 + 8 + 8 + w + 6)) print( f" {len(rows)} functions | tot accounted: {sum(r[1] for r in rows):.4f}s\n" )