"""Response renderers. Replaces renderers.js: - JSON_OUTPUT: JSON with 2-decimal float formatting + JSONP callback support - CSV_OUTPUT: semicolon-delimited CSV """ import csv import io import json from flask import jsonify, Response def json_output(ctx): """Render data as JSON. Replaces JSON_OUTPUT from renderers.js. Supports JSONP via ?callback= query parameter. Rounds floats to 2 decimal places. """ data = ctx.get('data', {}) def _replacer(val): if isinstance(val, float): return round(val, 2) return val json_data = json.dumps(data, default=_replacer, indent=2) from flask import request callback = request.args.get('callback') if callback: return Response( f'{callback}({json_data})', mimetype='application/javascript', ) return Response( json_data, mimetype='application/json; charset=utf-8', ) def csv_output(ctx): """Render data as semicolon-delimited CSV. Replaces CSV_OUTPUT from renderers.js. """ data = ctx.get('data', []) si = io.StringIO() writer = csv.writer( si, delimiter=';', lineterminator='\n', ) if data and isinstance(data[0], dict): # Write header writer.writerow(data[0].keys()) for row in data: writer.writerow(row.values()) body = si.getvalue() si.close() return Response( body.encode('utf-8'), mimetype='text/csv; charset=utf-8', )