eero-api 4.1.2__tar.gz → 4.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {eero_api-4.1.2/src/eero_api.egg-info → eero_api-4.2.0}/PKG-INFO +1 -1
- {eero_api-4.1.2 → eero_api-4.2.0}/pyproject.toml +2 -2
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/__init__.py +1 -1
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/__init__.py +2 -0
- eero_api-4.2.0/src/eero/api/data_usage.py +64 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/sqm.py +9 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/client.py +12 -0
- {eero_api-4.1.2 → eero_api-4.2.0/src/eero_api.egg-info}/PKG-INFO +1 -1
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero_api.egg-info/SOURCES.txt +1 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/LICENSE +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/README.md +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/setup.cfg +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/setup.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/__main__.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/ac_compat.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/activity.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/auth.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/auth_storage.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/backup.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/base.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/blacklist.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/burst_reporters.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/devices.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/diagnostics.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/dns.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/eeros.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/forwards.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/insights.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/networks.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/ouicheck.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/password.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/profiles.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/reservations.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/routing.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/schedule.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/security.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/settings.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/support.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/thread.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/transfer.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/api/updates.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/const.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/exceptions.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/logging.py +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero/py.typed +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero_api.egg-info/dependency_links.txt +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero_api.egg-info/requires.txt +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/src/eero_api.egg-info/top_level.txt +0 -0
- {eero_api-4.1.2 → eero_api-4.2.0}/tests/test_logging.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "eero-api"
|
|
7
|
-
version = "4.
|
|
7
|
+
version = "4.2.0"
|
|
8
8
|
description = "Modern async Python client for Eero network management"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -121,7 +121,7 @@ asyncio_mode = "auto"
|
|
|
121
121
|
|
|
122
122
|
[tool.commitizen]
|
|
123
123
|
name = "cz_conventional_commits"
|
|
124
|
-
version = "4.
|
|
124
|
+
version = "4.2.0"
|
|
125
125
|
version_files = [
|
|
126
126
|
"pyproject.toml:project.version",
|
|
127
127
|
"src/eero/__init__.py:__version__",
|
|
@@ -10,6 +10,7 @@ from .auth import AuthAPI
|
|
|
10
10
|
from .backup import BackupAPI
|
|
11
11
|
from .blacklist import BlacklistAPI
|
|
12
12
|
from .burst_reporters import BurstReportersAPI
|
|
13
|
+
from .data_usage import DataUsageAPI
|
|
13
14
|
from .devices import DevicesAPI
|
|
14
15
|
from .diagnostics import DiagnosticsAPI
|
|
15
16
|
from .dns import DnsAPI
|
|
@@ -72,6 +73,7 @@ class EeroAPI:
|
|
|
72
73
|
self.forwards = ForwardsAPI(self.auth)
|
|
73
74
|
self.transfer = TransferAPI(self.auth)
|
|
74
75
|
self.burst_reporters = BurstReportersAPI(self.auth)
|
|
76
|
+
self.data_usage = DataUsageAPI(self.auth)
|
|
75
77
|
self.ac_compat = ACCompatAPI(self.auth)
|
|
76
78
|
self.ouicheck = OUICheckAPI(self.auth)
|
|
77
79
|
self.password = PasswordAPI(self.auth)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Data Usage API for Eero.
|
|
2
|
+
|
|
3
|
+
IMPORTANT: This module returns RAW responses from the Eero Cloud API.
|
|
4
|
+
All data extraction, field mapping, and transformation must be done by downstream clients.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
9
|
+
|
|
10
|
+
from ..const import API_ENDPOINT
|
|
11
|
+
from ..exceptions import EeroAuthenticationException
|
|
12
|
+
from .auth import AuthAPI
|
|
13
|
+
from .base import AuthenticatedAPI
|
|
14
|
+
|
|
15
|
+
_LOGGER = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class DataUsageAPI(AuthenticatedAPI):
|
|
19
|
+
"""Data Usage API for Eero.
|
|
20
|
+
|
|
21
|
+
All methods return raw, unmodified JSON responses from the Eero Cloud API.
|
|
22
|
+
Response format: {"meta": {...}, "data": {...}}
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, auth_api: AuthAPI) -> None:
|
|
26
|
+
"""Initialize the DataUsageAPI.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
auth_api: Authentication API instance
|
|
30
|
+
"""
|
|
31
|
+
super().__init__(auth_api, API_ENDPOINT)
|
|
32
|
+
|
|
33
|
+
async def get_data_usage(
|
|
34
|
+
self, network_id: str, payload: Dict[str, Any], resource: Optional[str] = None
|
|
35
|
+
) -> Dict[str, Any]:
|
|
36
|
+
"""Get data usage statistics - returns raw Eero API response.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
network_id: ID of the network to get usage from
|
|
40
|
+
payload: JSON payload to send with the GET request.
|
|
41
|
+
Note: The eero cloud API expects a JSON body on this GET
|
|
42
|
+
request (e.g., timezone, period filters), which is uncommon
|
|
43
|
+
but matches the behavior used by Home Assistant's eero
|
|
44
|
+
integration.
|
|
45
|
+
resource: Optional resource type (e.g., "devices", "eeros")
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Raw API response: {"meta": {...}, "data": {...}}
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
EeroAuthenticationException: If not authenticated
|
|
52
|
+
EeroAPIException: If the API returns an error
|
|
53
|
+
"""
|
|
54
|
+
auth_token = await self._auth_api.get_auth_token()
|
|
55
|
+
if not auth_token:
|
|
56
|
+
raise EeroAuthenticationException("Not authenticated")
|
|
57
|
+
|
|
58
|
+
path = f"networks/{network_id}/data_usage"
|
|
59
|
+
if resource:
|
|
60
|
+
path = f"{path}/{resource}"
|
|
61
|
+
|
|
62
|
+
_LOGGER.debug("Getting data usage for network %s (resource=%s)", network_id, resource)
|
|
63
|
+
|
|
64
|
+
return await self.get(path, auth_token=auth_token, json=payload)
|
|
@@ -125,6 +125,9 @@ class SqmAPI(AuthenticatedAPI):
|
|
|
125
125
|
download_mbps,
|
|
126
126
|
)
|
|
127
127
|
|
|
128
|
+
# TODO: Verify whether bandwidth payload should be flattened (e.g. {"sqm": true,
|
|
129
|
+
# "upload_bandwidth": N}) rather than nested ({"sqm": {...}}) — pending live API
|
|
130
|
+
# verification against the /settings endpoint.
|
|
128
131
|
return await self.put(
|
|
129
132
|
f"networks/{network_id}/settings",
|
|
130
133
|
auth_token=auth_token,
|
|
@@ -167,6 +170,9 @@ class SqmAPI(AuthenticatedAPI):
|
|
|
167
170
|
|
|
168
171
|
_LOGGER.debug("Configuring SQM for network %s: %s", network_id, sqm_payload)
|
|
169
172
|
|
|
173
|
+
# TODO: Verify whether combined enable+bandwidth payload should be flattened rather
|
|
174
|
+
# than nested ({"sqm": {...}}) — pending live API verification against the /settings
|
|
175
|
+
# endpoint.
|
|
170
176
|
return await self.put(
|
|
171
177
|
f"networks/{network_id}/settings",
|
|
172
178
|
auth_token=auth_token,
|
|
@@ -188,6 +194,9 @@ class SqmAPI(AuthenticatedAPI):
|
|
|
188
194
|
|
|
189
195
|
_LOGGER.debug("Setting SQM to auto mode for network %s", network_id)
|
|
190
196
|
|
|
197
|
+
# TODO: Verify whether auto-mode payload should be flattened (e.g. {"sqm": true,
|
|
198
|
+
# "mode": "auto"}) rather than nested ({"sqm": {"enabled": true, "mode": "auto"}}) —
|
|
199
|
+
# pending live API verification against the /settings endpoint.
|
|
191
200
|
return await self.put(
|
|
192
201
|
f"networks/{network_id}/settings",
|
|
193
202
|
auth_token=auth_token,
|
|
@@ -671,6 +671,7 @@ class EeroClient:
|
|
|
671
671
|
response = await self._api.profiles.rename_profile(network_id, profile_id, name)
|
|
672
672
|
|
|
673
673
|
self._invalidate_profile_cache(network_id, profile_id)
|
|
674
|
+
self._invalidate_profiles_list_cache(network_id)
|
|
674
675
|
|
|
675
676
|
return response
|
|
676
677
|
|
|
@@ -693,6 +694,7 @@ class EeroClient:
|
|
|
693
694
|
response = await self._api.profiles.delete_profile(network_id, profile_id)
|
|
694
695
|
|
|
695
696
|
self._invalidate_profile_cache(network_id, profile_id)
|
|
697
|
+
self._invalidate_profiles_list_cache(network_id)
|
|
696
698
|
|
|
697
699
|
return response
|
|
698
700
|
|
|
@@ -824,6 +826,16 @@ class EeroClient:
|
|
|
824
826
|
network_id = await self._ensure_network_id(network_id, auto_discover=False)
|
|
825
827
|
return await self._api.transfer.get_transfer_stats(network_id, device_id)
|
|
826
828
|
|
|
829
|
+
async def get_data_usage(
|
|
830
|
+
self,
|
|
831
|
+
network_id: Optional[str] = None,
|
|
832
|
+
payload: Optional[Dict[str, Any]] = None,
|
|
833
|
+
resource: Optional[str] = None,
|
|
834
|
+
) -> Dict[str, Any]:
|
|
835
|
+
"""Get data usage statistics - returns raw Eero API response."""
|
|
836
|
+
network_id = await self._ensure_network_id(network_id, auto_discover=False)
|
|
837
|
+
return await self._api.data_usage.get_data_usage(network_id, payload or {}, resource)
|
|
838
|
+
|
|
827
839
|
async def get_burst_reporters(self, network_id: Optional[str] = None) -> Dict[str, Any]:
|
|
828
840
|
"""Get burst reporters - returns raw Eero API response."""
|
|
829
841
|
network_id = await self._ensure_network_id(network_id, auto_discover=False)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|