Files
LEDMatrix/src/web_interface/api_helpers.py
T
ChuckandClaude Opus 5 aba96e25b3 chore: delete three functions nothing calls (#550)
src/base_classes/baseball.py       _get_baseball_display_text   45 lines
  src/web_interface/api_helpers.py   validate_request_params      22
  web_interface/blueprints/api_v3.py _validate_time_range         14

Each has exactly one occurrence across both repositories -- its own
definition. No decorator, no __all__, no getattr dispatch, nothing in
templates or JavaScript.

A fourth candidate was dropped after checking: _unshare_element_fonts in
src/common/sports_shared.py looked unreferenced, but eight scoreboard plugins
call SportsCore._unshare_element_fonts directly from their
test_element_text_colors.py, plus their own copies at runtime. It is live API.
The earlier reading came from a plugins checkout 84 commits behind main, which
is a good argument for re-verifying this kind of claim against a fresh tree
rather than trusting an earlier scan.

Full suite: 4,265 passed, 68 skipped.


Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 08:45:07 -04:00

108 lines
3.0 KiB
Python

"""
Standardized API response helpers.
Provides consistent API response formatting across all endpoints.
"""
import time
from typing import Any, Optional, Dict, Tuple
from flask import jsonify, request
from src.web_interface.error_handler import create_error_response, create_success_response
from src.web_interface.errors import ErrorCode
def success_response(
data: Any = None,
message: Optional[str] = None,
metadata: Optional[Dict] = None
):
"""
Create a standardized success response.
Args:
data: Response data
message: Optional success message
metadata: Optional metadata (timing, version, etc.)
Returns:
Flask jsonify response
"""
response_data = create_success_response(data, message, metadata)
# Timing is merged into whatever the caller passed, without inventing a
# metadata block for responses that have neither.
enriched = dict(metadata) if metadata is not None else {}
if hasattr(request, 'start_time'):
enriched['response_time_ms'] = int((time.time() - request.start_time) * 1000)
if metadata is not None or enriched:
response_data['metadata'] = enriched
return jsonify(response_data)
def error_response(
error_code: ErrorCode,
message: str,
details: Optional[str] = None,
context: Optional[Dict] = None,
suggested_fixes: Optional[list] = None,
status_code: int = 500
):
"""
Create a standardized error response.
Args:
error_code: Error code
message: Error message
details: Optional detailed error information
context: Optional context dictionary
suggested_fixes: Optional list of suggested fixes
status_code: HTTP status code
Returns:
Flask jsonify response with status code
"""
return create_error_response(
error_code=error_code,
message=message,
details=details,
context=context,
suggested_fixes=suggested_fixes,
status_code=status_code
)
def validate_request_json(required_fields: list, data: Optional[Dict] = None) -> Tuple[Optional[Dict], Optional[Any]]:
"""
Validate request JSON has required fields.
Args:
required_fields: List of required field names
data: Optional data dict (if None, reads from request)
Returns:
Tuple of (data_dict, error_response) or (data_dict, None) if valid
"""
if data is None:
data = request.get_json(silent=True)
if not data:
return None, error_response(
ErrorCode.INVALID_INPUT,
"Request body must be valid JSON",
status_code=400
)
missing_fields = [field for field in required_fields if field not in data]
if missing_fields:
return None, error_response(
ErrorCode.INVALID_INPUT,
f"Missing required fields: {', '.join(missing_fields)}",
context={'missing_fields': missing_fields},
status_code=400
)
return data, None