cteward-ng/cteward_ng/renderers.py

71 lines
1.5 KiB
Python
Raw Normal View History

2026-06-06 10:18:15 +02:00
"""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',
)