""" Response formatter for API responses. """ from typing import Any, Dict, Optional from datetime import datetime class ResponseFormatter: """Format API responses consistently""" def __init__(self): self.stats = { 'responses_formatted': 0, 'errors_formatted': 0, 'success_responses': 0, 'created_at': datetime.utcnow().isoformat() } def success(self, data: Any, message: str = "Success", metadata: Optional[Dict] = None) -> Dict[str, Any]: """Format success response""" self.stats['responses_formatted'] += 1 self.stats['success_responses'] += 1 response = { "status": "success", "message": message, "data": data, "timestamp": datetime.utcnow().isoformat() } if metadata: response["metadata"] = metadata return response def error(self, message: str, code: str = "ERROR", details: Optional[Dict] = None) -> Dict[str, Any]: """Format error response""" self.stats['responses_formatted'] += 1 self.stats['errors_formatted'] += 1 response = { "status": "error", "message": message, "code": code, "timestamp": datetime.utcnow().isoformat() } if details: response["details"] = details return response def health(self, healthy: bool = True, components: Optional[Dict] = None) -> Dict[str, Any]: """Format health check response""" self.stats['responses_formatted'] += 1 return { "status": "healthy" if healthy else "unhealthy", "timestamp": datetime.utcnow().isoformat(), "components": components or {} } def rate_limit_error(self, client_stats: Dict) -> Dict[str, Any]: """Format rate limit error response""" self.stats['responses_formatted'] += 1 self.stats['errors_formatted'] += 1 return { "status": "error", "message": "Rate limit exceeded", "code": "RATE_LIMIT_EXCEEDED", "timestamp": datetime.utcnow().isoformat(), "details": { "remaining_tokens": client_stats.get('remaining_tokens', 0), "reset_time": client_stats.get('reset_time', 0), "requests_per_minute": client_stats.get('requests_per_minute', 0) } } def validation_error(self, field: str, message: str) -> Dict[str, Any]: """Format validation error response""" self.stats['responses_formatted'] += 1 self.stats['errors_formatted'] += 1 return { "status": "error", "message": f"Validation error: {message}", "code": "VALIDATION_ERROR", "timestamp": datetime.utcnow().isoformat(), "details": { "field": field, "validation_message": message } } def status_response(self, data: Dict) -> Dict[str, Any]: """Format status response""" self.stats['responses_formatted'] += 1 self.stats['success_responses'] += 1 return { "status": "success", "message": "System status", "data": data, "timestamp": datetime.utcnow().isoformat() } def heatmap_response(self, heatmap_data: Any, symbol: str, exchange: Optional[str] = None) -> Dict[str, Any]: """Format heatmap response""" self.stats['responses_formatted'] += 1 self.stats['success_responses'] += 1 if not heatmap_data: return self.error("Heatmap data not found", "HEATMAP_NOT_FOUND") return { "status": "success", "message": f"Heatmap data for {symbol}", "data": { "symbol": symbol, "exchange": exchange or "consolidated", "heatmap": heatmap_data }, "timestamp": datetime.utcnow().isoformat() } def orderbook_response(self, orderbook_data: Any, symbol: str, exchange: str) -> Dict[str, Any]: """Format order book response""" self.stats['responses_formatted'] += 1 self.stats['success_responses'] += 1 if not orderbook_data: return self.error("Order book data not found", "ORDERBOOK_NOT_FOUND") return { "status": "success", "message": f"Order book data for {symbol}@{exchange}", "data": { "symbol": symbol, "exchange": exchange, "orderbook": orderbook_data }, "timestamp": datetime.utcnow().isoformat() } def metrics_response(self, metrics_data: Any, symbol: str, exchange: str) -> Dict[str, Any]: """Format metrics response""" self.stats['responses_formatted'] += 1 self.stats['success_responses'] += 1 if not metrics_data: return self.error("Metrics data not found", "METRICS_NOT_FOUND") return { "status": "success", "message": f"Metrics data for {symbol}@{exchange}", "data": { "symbol": symbol, "exchange": exchange, "metrics": metrics_data }, "timestamp": datetime.utcnow().isoformat() } def get_stats(self) -> Dict[str, Any]: """Get formatter statistics""" return { **self.stats, 'uptime_seconds': (datetime.utcnow() - datetime.fromisoformat(self.stats['created_at'])).total_seconds(), 'error_rate': self.stats['errors_formatted'] / max(1, self.stats['responses_formatted']) }