From 9da79d5b90f5887d2e3edebcd3eea690b5aa353c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 22:48:03 +0000 Subject: [PATCH] [FIX] Overly long function get_stats Refactored the get_stats function in hookwise/api.py by extracting its core logic into private module-level helper functions (_count_webhook_stats_base_query, _count_webhook_stats, and _calculate_avg_processing_time). This reduces the function length, improves readability, and facilitates code reuse. Added module-level import for sqlalchemy.func. Verified with tests. Co-authored-by: arumes31 <114224498+arumes31@users.noreply.github.com> --- hookwise/api.py | 107 +++++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 65 deletions(-) diff --git a/hookwise/api.py b/hookwise/api.py index c9f3177..fca70f7 100644 --- a/hookwise/api.py +++ b/hookwise/api.py @@ -11,6 +11,7 @@ from flask import Response, current_app, flash, jsonify, redirect, render_template, request, session, url_for from prometheus_client import CONTENT_TYPE_LATEST, Gauge, generate_latest +from sqlalchemy import func from sqlalchemy.orm import joinedload from .extensions import db, limiter @@ -21,6 +22,39 @@ QUEUE_SIZE = Gauge("hookwise_celery_queue_size", "Approximate number of tasks in queue") + +def _count_webhook_stats_base_query(start_time: datetime): + """Provides a consistent base query for webhook statistics.""" + return WebhookLog.query.join(WebhookConfig).filter( + WebhookConfig.is_draft.is_(False), + WebhookLog.created_at >= start_time, + ) + + +def _count_webhook_stats( + start_time: datetime, + status_list: list[str] | None = None, + action: str | None = None, +) -> int: + """Counts webhook logs based on start time, status, and action.""" + query = _count_webhook_stats_base_query(start_time) + if status_list: + query = query.filter(WebhookLog.status.in_(status_list)) + if action: + query = query.filter(WebhookLog.action == action) + return query.count() + + +def _calculate_avg_processing_time(start_time: datetime) -> float: + """Calculates the average processing time for processed webhooks since start_time.""" + avg_proc = ( + db.session.query(func.avg(WebhookLog.processing_time)) + .filter(WebhookLog.created_at >= start_time, WebhookLog.status == "processed") + .scalar() + or 0 + ) + return float(avg_proc) + def _register() -> None: from .routes import main_bp @@ -466,74 +500,17 @@ def dry_run_llm_status(task_id: str) -> Any: @main_bp.route("/api/stats") @auth_required def get_stats() -> Any: - from sqlalchemy import func - today_start = datetime.combine(datetime.now(timezone.utc).date(), dtime.min) - tickets_created = ( - WebhookLog.query.join(WebhookConfig) - .filter( - WebhookConfig.is_draft.is_(False), - WebhookLog.status == "processed", - WebhookLog.action == "create", - WebhookLog.created_at >= today_start, - ) - .count() - ) - - tickets_updated = ( - WebhookLog.query.join(WebhookConfig) - .filter( - WebhookConfig.is_draft.is_(False), - WebhookLog.status == "processed", - WebhookLog.action == "update", - WebhookLog.created_at >= today_start, - ) - .count() - ) - - tickets_closed = ( - WebhookLog.query.join(WebhookConfig) - .filter( - WebhookConfig.is_draft.is_(False), - WebhookLog.status == "processed", - WebhookLog.action == "close", - WebhookLog.created_at >= today_start, - ) - .count() - ) + tickets_created = _count_webhook_stats(today_start, ["processed"], "create") + tickets_updated = _count_webhook_stats(today_start, ["processed"], "update") + tickets_closed = _count_webhook_stats(today_start, ["processed"], "close") + failed_attempts = _count_webhook_stats(today_start, ["failed", "dlq"]) + total_today = _count_webhook_stats(today_start) + successful_attempts = _count_webhook_stats(today_start, ["processed", "skipped"]) - failed_attempts = ( - WebhookLog.query.join(WebhookConfig) - .filter( - WebhookConfig.is_draft.is_(False), - WebhookLog.status.in_(["failed", "dlq"]), - WebhookLog.created_at >= today_start, - ) - .count() - ) - - total_today = ( - WebhookLog.query.join(WebhookConfig) - .filter(WebhookConfig.is_draft.is_(False), WebhookLog.created_at >= today_start) - .count() - ) - successful_attempts = ( - WebhookLog.query.join(WebhookConfig) - .filter( - WebhookConfig.is_draft.is_(False), - WebhookLog.status.in_(["processed", "skipped"]), - WebhookLog.created_at >= today_start, - ) - .count() - ) success_rate = (successful_attempts / total_today * 100) if total_today > 0 else 100 - avg_proc = ( - db.session.query(func.avg(WebhookLog.processing_time)) - .filter(WebhookLog.created_at >= today_start, WebhookLog.status == "processed") - .scalar() - or 0 - ) + avg_proc = _calculate_avg_processing_time(today_start) return jsonify( { @@ -542,7 +519,7 @@ def get_stats() -> Any: "closed_today": tickets_closed, "failed_today": failed_attempts, "success_rate": round(success_rate, 1), - "avg_processing_time": round(float(avg_proc), 2), + "avg_processing_time": round(avg_proc, 2), } )