Skip to content

fix: deprecate ActivityAPI + fix get_insights signature (closes #107)#113

Open
fulviofreitas wants to merge 2 commits into
masterfrom
fix/issue-107-activity-insights
Open

fix: deprecate ActivityAPI + fix get_insights signature (closes #107)#113
fulviofreitas wants to merge 2 commits into
masterfrom
fix/issue-107-activity-insights

Conversation

@fulviofreitas

Copy link
Copy Markdown
Owner

Closes #107.

Summary

ActivityAPI's five methods target /networks/{id}/activity* endpoints that no longer exist on Eero's cloud API — every call raises 404. Deprecate the whole surface (removal in v6.0.0) and point migrators to InsightsAPI.get_insights and DataUsageAPI.get_data_usage.

While probing the replacement endpoint I discovered InsightsAPI.get_insights(network_id) was also 100% broken — the API requires four required query params (start, end, insight_type, cadence) that the SDK wasn't sending. Fixed the signature in the same PR so the migration target actually works.

Live-established API facts

Probed against a real account, network 3401709:

Path Result
GET /2.2/networks/{id}/activity 404
GET /2.3/networks/{id}/activity 404
GET /2.2/networks/{id}/activity/clients 404
GET /2.2/networks/{id}/activity/categories 404
GET /2.2/networks/{id}/activity/history 404
Rename candidates (/timeline, /history, /analytics, /traffic, /clientusage, /activity/summary, etc.) 404
Network resource map Lists insights, no activity entry
GET /2.2/networks/{id}/insights (no params) 400 error.form.errorsstart, end, cadence, insight_type all required
GET /2.2/networks/{id}/insights?start=…&end=…&cadence=daily&insight_type=adblock 200 ✅
insight_type=blocked response 7 series: blocked, malware, botnet, phishing, parked, domains, compromised

Changes

src/eero/api/insights.py — new signature, keyword-only

async def get_insights(
    self,
    network_id: str,
    *,
    start: str,              # ISO 8601
    end: str,                # ISO 8601
    insight_type: str,       # "adblock" | "blocked" | "inspected"
    cadence: str = "daily",  # "hourly" | "daily" | "weekly"
) -> Dict[str, Any]:

Only cadence gets an SDK default (bucketing = display concern, not data scope). Response envelope passed through raw — v2.0 contract preserved.

src/eero/api/activity.py — 5 methods emit DeprecationWarning

Shared ACTIVITY_DEPRECATION_MSG constant, docstring migration pointers to get_insights / get_data_usage. Class docstring updated. Same pattern as PRIORITY_DEPRECATION_MSG from PR #112.

src/eero/client.py

  • get_insights wrapper: new required kwargs mirrored.
  • 5 activity wrappers: mirror DeprecationWarning.
  • Import ACTIVITY_DEPRECATION_MSG from api/activity.py.

Tests

  • tests/api/test_insights.py: 4 new tests covering param forwarding, cadence default, raw pass-through, keyword-only enforcement.
  • tests/api/test_activity.py: rewrote — every existing method call now wrapped in pytest.warns(DeprecationWarning, match=…); new TestActivityAPIDeprecationMessage class asserts the shared message names both replacements + tracking issue.
  • pytest tests/482 passed (whole SDK unit suite).

What this does NOT include (v2.0 contract enforcement)

  • ❌ No get_activityget_insights adapter that reshapes the response. Would violate v2.0 "raw JSON pass-through". Callers migrate their own call sites.
  • ❌ No last_24h() / last_week() helpers for building start/end. Those belong in downstream clients.
  • ❌ No defaults for start/end/insight_type. Those are data-scoping decisions the caller must make.

Downstream impact — real work required

The following repos have callers that will break (or, in some cases, will finally start working) once this ships:

  • eero-prometheus-exporter — calls client.get_activity, get_activity_clients, get_activity_categories, AND the now-fixed client.get_insights. All were failing on every scrape; issue filed for migration.
  • eeroctl — has commands/activity.py. Similar migration needed; issue filed.
  • eero-ui — no known callers, but worth grep-checking after merge.

Follow-up issues linked in comments once filed.

Commits

  1. 23ed5dd fix(insights): make get_insights actually work — add required query params
  2. 3af7b85 refactor(activity): deprecate ActivityAPI — endpoints removed from Eero API

Not squashing (per prior convention on PR #112) — each commit is scoped and reads clearly in git blame.


Live-probing, implementation, and verification done by me. Code review invited from you (@fulviofreitas); happy to bring in a security-engineer agent for a second pass if you want the same treatment as PR #112.

…arams

The Eero cloud API rejects GET /networks/{id}/insights without the four
query parameters `start`, `end`, `cadence`, and `insight_type` (returns
400 error.form.errors). The current SDK method sent none of them, so
every call silently 400'd — nobody was actually using this method
successfully.

New signature:

    async def get_insights(
        self,
        network_id: str,
        *,
        start: str,          # ISO 8601, e.g. "2026-07-21T00:00:00Z"
        end: str,            # ISO 8601
        insight_type: str,   # "adblock" | "blocked" | "inspected"
        cadence: str = "daily",   # "hourly" | "daily" | "weekly"
    )

Only `cadence` gets an SDK-supplied default, since it controls display
bucketing rather than data scope. Response envelope is passed through
raw as always (v2.0 contract preserved).

Live-verified against a real account: returns the expected
`{series: [{insight_type, sum, values: [{time, value}]}]}` shape.
The `insight_type=blocked` variant returns seven series (blocked,
malware, botnet, phishing, parked, domains, compromised) — the
enum is broader in the response than in the request.

Breaking change to any caller of get_insights(network_id), but since
that call was already 100% broken (400), nothing usable regresses.
Follow-up cleanup filed for eero-prometheus-exporter and eeroctl.

Refs #107.
…ro API

Every /networks/{id}/activity* endpoint targeted by ActivityAPI now
returns 404. Live-verified on API versions 2.2 and 2.3, and against
the network's own resource map: the map lists `insights` but has NO
`activity` resource. Rename candidates (timeline, history, analytics,
traffic, events, clientusage) also all 404.

All five ActivityAPI methods (and their EeroClient wrappers) now
emit a DeprecationWarning pointing callers to:
- InsightsAPI.get_insights(...) — category / adblock / inspected
  breakdowns
- DataUsageAPI.get_data_usage(...) — bandwidth per client / node

The existing implementations are retained (they'll continue to
raise EeroAPIException with a 404 as they do today) so nothing
regresses during the deprecation window. Scheduled for removal in
v6.0.0.

ACTIVITY_DEPRECATION_MSG is defined once in api/activity.py and
imported by client.py — single source of truth for the removal
target and issue URL, matching the pattern established for
PRIORITY_DEPRECATION_MSG.

Live-verified: DeprecationWarning fires on all five methods.

Closes #107. Follow-up migration issues filed in
eero-prometheus-exporter and eeroctl.
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@fulviofreitas, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 7 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ed8e7767-f3aa-4105-8283-89bcff9f221c

📥 Commits

Reviewing files that changed from the base of the PR and between 49a7093 and 3af7b85.

📒 Files selected for processing (5)
  • src/eero/api/activity.py
  • src/eero/api/insights.py
  • src/eero/client.py
  • tests/api/test_activity.py
  • tests/api/test_insights.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-107-activity-insights

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

[Bug]: get_activity/get_activity_categories 404 on both API v2.2 and v2.3 (/networks/{id}/activity path doesn't exist)

1 participant