Add JSON export to the report downloader

Python · Python · intermediate · modification

Refactors report export into a clean, extensible exporter architecture: an abstract ReportExporter base with a metaclass that auto-registers each format into a central registry, so future formats drop in by subclassing with no change to the dispatch logic. Adds JSON alongside the existing CSV.

`rows` is a list of uniform dicts produced by a fixed report query. The empty-report case returns an empty CSV today and must keep working.

Requirements

Files touched

--- app/reports/export.py
 import csv
 import io
+import json
+
+EXPORTER_REGISTRY = {}
 
 
-def export_report(rows):
-    if not rows:
-        return ""
-    buffer = io.StringIO()
-    writer = csv.DictWriter(buffer, fieldnames=list(rows[0].keys()))
-    writer.writeheader()
-    writer.writerows(rows)
-    return buffer.getvalue()
+class ExporterMeta(type):
+    def __new__(mcs, name, bases, namespace):
+        cls = super().__new__(mcs, name, bases, namespace)
+        fmt = namespace.get("format_name")
+        if fmt is not None:
+            EXPORTER_REGISTRY[fmt] = cls
+        return cls
 
+
+class ReportExporter(metaclass=ExporterMeta):
+    format_name = None
+
+    def render(self, rows):
+        raise NotImplementedError

Review this PR

Python practice