mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-13 10:36:35 +00:00
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>
108 lines
3.0 KiB
Python
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
|