Skip to content

feat: support excluding anomalous dates from static analytics reports (#4907) - #4908

Open
NoopDog wants to merge 3 commits into
mainfrom
noopdog/4907-exclude-dates
Open

feat: support excluding anomalous dates from static analytics reports (#4907)#4908
NoopDog wants to merge 3 commits into
mainfrom
noopdog/4907-exclude-dates

Conversation

@NoopDog

@NoopDog NoopDog commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Closes #4907

What changed

  • analytics/analytics_package/analytics/static_site/fetch.py: fetch_data() gains an optional exclude_dates parameter (list of YYYY-MM-DD strings). When set, the dates are compiled into a GA4 dimension filter via the package's existing filter DSL (date!=YYYYMMDD;... through parse_filter_expressions) and AND-merged into base_dimension_filter, so every query the dashboard makes excludes those days.
  • analytics/analytics_package/analytics/static_site/generator.py: passes the new parameter through generate_site().
  • analytics/anvil-explorer-sheets/constants.py + generate_static_site.py: new EXCLUDE_BOT_TRAFFIC_DATES = ["2025-02-10", "2025-02-11"] constant, passed as exclude_dates.
  • gh-pages/anvil-explorer/: regenerated. Only monthly_traffic.json (Feb 2025: 9,480 → 277 users, 19,951 → 2,239 pageviews) and meta.json (timestamp) changed; all other data files are byte-identical.

Why

GA4 recorded a synthetic traffic burst on 2025-02-10/11: ~9,160 "users" sharing one fingerprint (headless-Chrome 800×600 viewport, single geolocation, every session a first visit) hammering the site — likely a load test. It shows as a bogus spike in the dashboard's monthly traffic chart. GA4 cannot retroactively remove data, so the report queries exclude those dates instead. Excluding at query time (rather than post-processing) keeps GA's user deduplication correct — daily user counts are not additive, so client-side subtraction would corrupt user metrics.

Assumptions I made

  • Date exclusion (losing the ~50–70 real users on those two days) was chosen over fingerprint-based filtering, which would silently drop matching traffic forever; the two days are ~0.1% of the chart's range.
  • The dates live in per-site constants (property-specific facts), not in the package.
  • The exclusion applies to GA4 queries only, not to historic_data_path (pre-GA4 UA history) — documented in both docstrings; no current caller combines the two in an affected range.
  • The regenerated data was verified equivalent to a direct GA4 Data API query with the same filter before committing, so no other data files needed to change.
  • anvil-portal will consume this via its analytics dependency on this repo's main for the same fix there (chore: exclude 2025-02-10 bot traffic from portal analytics report anvilproject/anvil-portal#4077).

How to verify

Definition of done from #4907: (1) the package supports excluding dates from report queries, (2) the AnVIL Explorer report excludes 2025-02-10/11, (3) the regenerated site no longer shows the spike.

  1. Open gh-pages/anvil-explorer/data/monthly_traffic.json and find the 2025-02 entry: it should read 277 users / 2,239 pageviews (previously 9,480 / 19,951). Cross-check in the GA4 UI: AnVIL Explorer property, Feb 2025, exclude Feb 10–11.
  2. Serve the site locally (cd gh-pages/anvil-explorer && python -m http.server 8080) and look at the Monthly Traffic Over Time chart: February 2025 should look like an ordinary month, no spike.
  3. Confirm every other file under gh-pages/anvil-explorer/data/ is unchanged in this diff (only meta.json's generated_at moved) — the exclusion touched nothing outside those two days.
  4. Optionally regenerate end-to-end: cd analytics/anvil-explorer-sheets && python generate_static_site.py (requires GA4 OAuth); the console prints "Excluding dates from all queries: 2025-02-10, 2025-02-11".

🤖 Generated with Claude Code

…4907

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support in the analytics static-site generator for excluding specific anomalous dates from all GA4 queries, and applies it to the AnVIL Explorer report to remove a known synthetic traffic spike in Feb 2025.

Changes:

  • Add an exclude_dates parameter to static-site generation and fetch logic, merged into the existing GA4 dimension filter via the filter DSL.
  • Wire exclude_dates through the AnVIL Explorer generation script using a new per-site constant for known bot-traffic dates.
  • Regenerate the published AnVIL Explorer static site data to reflect the exclusion (notably Feb 2025 monthly traffic).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
analytics/analytics_package/analytics/static_site/fetch.py Adds date-exclusion support by AND-merging a date!=YYYYMMDD filter into the base GA4 dimension filter.
analytics/analytics_package/analytics/static_site/generator.py Plumbs exclude_dates through generate_site() into fetch_data().
analytics/anvil-explorer-sheets/constants.py Introduces an AnVIL Explorer-specific constant for excluded bot-traffic dates.
analytics/anvil-explorer-sheets/generate_static_site.py Passes the excluded dates into generate_site() for AnVIL Explorer.
gh-pages/anvil-explorer/data/monthly_traffic.json Updates Feb 2025 monthly rollup to remove the anomalous spike.
gh-pages/anvil-explorer/data/meta.json Updates generated timestamp metadata.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread analytics/analytics_package/analytics/static_site/fetch.py
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (1)

analytics/analytics_package/analytics/static_site/fetch.py:368

  • Optional robustness: the regex check ensures YYYY-MM-DD formatting, but it still accepts non-existent calendar dates like 2025-02-31 or 2025-13-01. Validating with date.fromisoformat() will fail fast with a clear error rather than silently generating a GA4 filter that matches nothing (or triggers an API error).
    if exclude_dates:
        for d in exclude_dates:
            if not re.fullmatch(r"\d{4}-\d{2}-\d{2}", d):
                raise ValueError(f"exclude_dates entries must be YYYY-MM-DD, got: {d!r}")

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: support excluding anomalous dates from static analytics reports; exclude 2025-02-10/11 bot traffic from AnVIL Explorer

2 participants