Skip to content

chore: extract a shared JSON-write helper in the analytics static site export #4944

Description

@hunterckx

(Text courtesy of Claude)

Follow-up from #4942 / #4943, spun out of review rather than folded into that PR.

Problem

analytics/analytics_package/analytics/static_site/export.py writes its JSON output through ten near-identical blocks:

with (output_dir / "monthly_traffic.json").open("w") as f:
    json.dump(traffic_data.to_dict(orient="records"), f, indent=2)
print(f"  Wrote monthly_traffic.json ({len(traffic_data)} records)")

They appear at monthly_traffic.json, file_downloads.json, access_requests.json, file_download_events.json, search_queries.json, custom_events.json, event_{key}_detail.json, event_charts.json, config.json and meta.json — plus an eleventh copy as the tail of export_df_as_json. Each repeats the with / open("w") ceremony, indent=2, the two-space Wrote log prefix, and the filename twice (once as a path, once inside the message).

The concrete cost showed up in #4942: enabling ruff's PTH rules meant hand-applying the same os.path.joinpathlib change eleven times in this one file, and PTH118/PTH123 accounted for 27 of that PR's 33 violations. Beyond the churn, indent=2, the encoding, and the log convention can each drift independently across eleven sites, and the path/message filename pair can silently disagree.

Suggested fix

One module-level helper, then one call per output file:

def _write_json(path, payload, detail=None):
    with path.open("w") as f:
        json.dump(payload, f, indent=2)
    print(f"  Wrote {path.name}" + (f" ({detail})" if detail else ""))
_write_json(output_dir / "file_downloads.json", {"total": file_downloads}, f"total: {file_downloads}")
_write_json(output_dir / "config.json", config)

A detail=None parameter covers every existing message variant — N records, total: X, N queries, N events, N charts, and the bare Wrote config.json / Wrote meta.json — with byte-identical output. export_df_as_json's tail collapses into the same helper. Net effect is roughly −16 lines.

Why this wasn't done in #4943

#4942 scoped its PTH commit to the path-handling change with no unrelated cleanup, so that the commit stayed reviewable against the rule it was named for. The repetition is pre-existing — #4943 converted it, it did not create it.

Verification

  • npm run lint:python and npm run check-format:python pass clean, and the same steps pass in run-checks.yml CI.
  • Printed stdout and every generated JSON file must be byte-identical before and after, since this is a pure extraction. A fresh-venv generate_static_site.py run including historic_data_path (LungMAP), per the chore: retire legacy analytics formats — tracking #4913 convention, with the generated site output diffed against main — expect no differences beyond data/meta.json's generated_at timestamp.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions