Skip to content

Commit f2c1366

Browse files
committed
🗑️ Deprecate the two *-time-ago aggregation methods (#44)
## Summary Soft-deprecates the two legacy aggregation aliases in favour of their current-spelling replacements: - `get_site_networks_ts_time_ago` → **`get_site_time_series`** - `get_site_consumption_breakdown_time_ago` → **`get_top_consumption`** Both legacy methods now emit a `DeprecationWarning` (with `stacklevel=2`, so it points at the caller) but are **otherwise unchanged**: same endpoints (`site-networks-ts-time-ago` / `consumption-breakdown-time-ago`, both still returning `200` live), same defaults, same response shape. Nothing is removed — existing callers (e.g. the Home Assistant integration) keep working without changes. Why not just delete them / re-point them at the new endpoints? Because the new methods have **different defaults** (`aggregation_level` NONE→HOUR, `time_ago_unit` HOUR→DAY), so delegating would silently change behaviour for callers relying on defaults. A pure soft-deprecation is zero-risk. ## Changes - `comwatt_client/_aggregations.py`: `warnings.warn(..., DeprecationWarning, stacklevel=2)` at the top of both methods + a `.. deprecated::` docstring note. - `tests/test_aggregations.py`: two new tests asserting the warning category/message and that behaviour (endpoint + returned data) is unchanged; the existing legacy-method tests get a per-test `@pytest.mark.filterwarnings("ignore::DeprecationWarning")` so the project's global `filterwarnings = error` policy stays intact everywhere else. - `README.md`: both methods flagged **Deprecated** in the feature list; usage example switched to `get_site_time_series` / `get_top_consumption`. ## Not included (by request) - No version bump / release commit — releases are separate commits in this repo. ## Test plan - [x] `pytest` → 94 passed (2 new). - [x] `mypy comwatt_client` → clean. - [x] `filterwarnings = error` kept globally; only the legacy-method tests opt out. Opened as a draft (WIP) — mark ready for review when you're happy. Co-authored-by: Mateo Greil <mateo@go-electra.com> Reviewed-on: https://git.greil.fr/mat/python-comwatt-client/pulls/44
1 parent 84c12a8 commit f2c1366

3 files changed

Lines changed: 89 additions & 8 deletions

File tree

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ The client currently supports the following methods:
1313
- `logout(self)`: Logs the current session out server-side (`POST /v1/logout`) and clears the stored credentials so `auto_reauth` cannot silently restore the session. Idempotent (a 401 when already logged out is a no-op). Note this is distinct from `close()`, which only releases the local HTTP session without logging out.
1414
- `get_authenticated_user(self)`: Retrieves information about the authenticated user.
1515
- `get_sites(self)`: Retrieves a list of sites associated with the authenticated user.
16-
- `get_site_networks_ts_time_ago(self, site_id, measure_kind = "FLOW", aggregation_level = "NONE", aggregation_type = None, time_ago_unit = "HOUR", time_ago_value = 1, start = None, end = None)`: Retrieves the time series data for the networks of a specific site, based on the provided parameters.
17-
- `get_site_consumption_breakdown_time_ago(self, site_id, aggregation_level = "HOUR", time_ago_unit = "DAY", time_ago_value = 1, start = None, end = None)` Retrieves the consumption breakdown data for a specific site, based on the provided parameters.
16+
- `get_site_networks_ts_time_ago(self, site_id, measure_kind = "FLOW", aggregation_level = "NONE", aggregation_type = None, time_ago_unit = "HOUR", time_ago_value = 1, start = None, end = None)`: Retrieves the time series data for the networks of a specific site, based on the provided parameters. **Deprecated** — use `get_site_time_series` instead (emits a `DeprecationWarning`; the endpoint still works but the app has moved to `site-time-series`).
17+
- `get_site_consumption_breakdown_time_ago(self, site_id, aggregation_level = "HOUR", time_ago_unit = "DAY", time_ago_value = 1, start = None, end = None)` Retrieves the consumption breakdown data for a specific site, based on the provided parameters. **Deprecated** — use `get_top_consumption` instead (emits a `DeprecationWarning`; the endpoint still works but the app has moved to `top-consumption`).
1818
- `get_devices(self, site_id)`: Retrieves a list of devices for the specified site.
1919
- `get_connected_objects(self, site_id=None, gateway_uid=None)`: Retrieves the connected objects for a site or a gateway. Exactly one of `site_id` / `gateway_uid` is required (raises `ValueError` otherwise).
2020
- `get_connected_object(self, connected_object_id)`: Retrieves information about a specific connected object.
@@ -68,13 +68,13 @@ print(user_info)
6868
sites = client.get_sites()
6969
print(sites)
7070

71-
# Get time series data for the networks of a specific site
72-
networks_time_series_data = client.get_site_networks_ts_time_ago(sites[0]['id'])
73-
print(networks_time_series_data)
71+
# Get the whole-site rollup time series (productions, consumptions, injections, ...)
72+
site_time_series_data = client.get_site_time_series(sites[0]['id'])
73+
print(site_time_series_data)
7474

75-
# Get the consumption breakdown data for a specific site, based on the provided parameters.
76-
consumption_breakdown_data = client.get_site_consumption_breakdown_time_ago(sites[0]['id'])
77-
print(consumption_breakdown_data)
75+
# Get the per-device consumption breakdown for a specific site (top 5 + "others")
76+
top_consumption_data = client.get_top_consumption(sites[0]['id'])
77+
print(top_consumption_data)
7878

7979
# Get a list of devices for a specific site
8080
devices = client.get_devices(sites[0]['id'])

comwatt_client/_aggregations.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import warnings
34
from datetime import datetime, timezone
45
from typing import Any
56

@@ -76,8 +77,21 @@ def get_site_networks_ts_time_ago(self, site_id: int | str,
7677
ValueError: If `end` is given without `start`.
7778
Exception: If an error occurs while retrieving the data.
7879
80+
.. deprecated::
81+
Use :meth:`get_site_time_series` instead. The
82+
``site-networks-ts-time-ago`` endpoint still responds, but the app
83+
has moved to ``site-time-series``; this alias is kept only for
84+
backward compatibility.
85+
7986
"""
8087

88+
warnings.warn(
89+
"get_site_networks_ts_time_ago() is deprecated and will be removed in a "
90+
"future release; use get_site_time_series() instead.",
91+
DeprecationWarning,
92+
stacklevel=2,
93+
)
94+
8195
params = _aggregations_query(
8296
id_param="siteId", id_value=site_id, aggregation_level=aggregation_level,
8397
measure_kind=measure_kind, aggregation_type=aggregation_type,
@@ -115,8 +129,21 @@ def get_site_consumption_breakdown_time_ago(self, site_id: int | str,
115129
ValueError: If `end` is given without `start`.
116130
Exception: If an error occurs while retrieving the data.
117131
132+
.. deprecated::
133+
Use :meth:`get_top_consumption` instead. The
134+
``consumption-breakdown-time-ago`` endpoint still responds, but the
135+
app has moved to ``top-consumption``; this alias is kept only for
136+
backward compatibility.
137+
118138
"""
119139

140+
warnings.warn(
141+
"get_site_consumption_breakdown_time_ago() is deprecated and will be "
142+
"removed in a future release; use get_top_consumption() instead.",
143+
DeprecationWarning,
144+
stacklevel=2,
145+
)
146+
120147
params = _aggregations_query(
121148
id_param="siteId", id_value=site_id, aggregation_level=aggregation_level,
122149
time_ago_unit=time_ago_unit, time_ago_value=time_ago_value,

tests/test_aggregations.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from tests.conftest import BASE_URL
99

1010

11+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
1112
@responses.activate
1213
def test_get_site_networks_ts_time_ago_defaults(client):
1314
mock_data = {"values": [1, 2, 3]}
@@ -34,6 +35,7 @@ def test_get_site_networks_ts_time_ago_defaults(client):
3435
assert "aggregationType" not in qs
3536

3637

38+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
3739
@responses.activate
3840
def test_get_site_networks_ts_time_ago_with_aggregation_type(client):
3941
mock_data = {"values": [4, 5, 6]}
@@ -53,6 +55,7 @@ def test_get_site_networks_ts_time_ago_with_aggregation_type(client):
5355
assert qs["aggregationType"] == ["SUM"]
5456

5557

58+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
5659
@responses.activate
5760
def test_get_site_networks_ts_time_ago_custom_params(client):
5861
mock_data = {"values": [7, 8, 9]}
@@ -81,6 +84,7 @@ def test_get_site_networks_ts_time_ago_custom_params(client):
8184
assert qs["timeAgoValue"] == ["3"]
8285

8386

87+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
8488
@responses.activate
8589
def test_get_site_networks_ts_time_ago_error(client):
8690
responses.add(
@@ -96,6 +100,7 @@ def test_get_site_networks_ts_time_ago_error(client):
96100
assert "500" in str(exc_info.value)
97101

98102

103+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
99104
@responses.activate
100105
def test_get_site_consumption_breakdown_time_ago_defaults(client):
101106
mock_data = {"breakdown": "data"}
@@ -120,6 +125,7 @@ def test_get_site_consumption_breakdown_time_ago_defaults(client):
120125
assert qs["timeAgoValue"] == ["1"]
121126

122127

128+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
123129
@responses.activate
124130
def test_get_site_consumption_breakdown_time_ago_custom_params(client):
125131
mock_data = {"breakdown": "custom"}
@@ -147,6 +153,7 @@ def test_get_site_consumption_breakdown_time_ago_custom_params(client):
147153
assert qs["timeAgoValue"] == ["2"]
148154

149155

156+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
150157
@responses.activate
151158
def test_get_site_consumption_breakdown_time_ago_error(client):
152159
responses.add(
@@ -188,6 +195,7 @@ def test_get_device_ts_time_ago_defaults(client):
188195
assert qs["timeAgoValue"] == ["1"]
189196

190197

198+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
191199
@responses.activate
192200
def test_get_site_networks_ts_time_ago_with_naive_start(client):
193201
mock_data = {"values": [1]}
@@ -214,6 +222,7 @@ def test_get_site_networks_ts_time_ago_with_naive_start(client):
214222
assert qs["aggregationLevel"] == ["NONE"]
215223

216224

225+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
217226
@responses.activate
218227
def test_get_site_networks_ts_time_ago_with_start_and_end(client):
219228
mock_data = {"values": [2]}
@@ -240,6 +249,7 @@ def test_get_site_networks_ts_time_ago_with_start_and_end(client):
240249
assert "timeAgoValue" not in qs
241250

242251

252+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
243253
@responses.activate
244254
def test_get_site_networks_ts_time_ago_with_aware_start(client):
245255
mock_data = {"values": [3]}
@@ -260,6 +270,7 @@ def test_get_site_networks_ts_time_ago_with_aware_start(client):
260270
assert qs["start"] == ["2026-07-04T10:00:00Z"]
261271

262272

273+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
263274
@responses.activate
264275
def test_get_site_networks_ts_time_ago_with_string_start(client):
265276
mock_data = {"values": [4]}
@@ -281,6 +292,7 @@ def test_get_site_networks_ts_time_ago_with_string_start(client):
281292
assert qs["start"] == ["2026-07-04T10:00:00Z"]
282293

283294

295+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
284296
@responses.activate
285297
def test_get_site_networks_ts_time_ago_end_without_start_raises(client):
286298
with pytest.raises(ValueError):
@@ -290,6 +302,7 @@ def test_get_site_networks_ts_time_ago_end_without_start_raises(client):
290302
assert len(responses.calls) == 0
291303

292304

305+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
293306
@responses.activate
294307
def test_get_site_consumption_breakdown_time_ago_with_start_and_end(client):
295308
mock_data = {"breakdown": "windowed"}
@@ -316,6 +329,7 @@ def test_get_site_consumption_breakdown_time_ago_with_start_and_end(client):
316329
assert "timeAgoValue" not in qs
317330

318331

332+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
319333
@responses.activate
320334
def test_get_site_consumption_breakdown_time_ago_end_without_start_raises(client):
321335
with pytest.raises(ValueError):
@@ -702,3 +716,43 @@ def test_get_top_consumption_error(client):
702716
client.get_top_consumption("site-1")
703717

704718
assert "500" in str(exc_info.value)
719+
720+
721+
@responses.activate
722+
def test_get_site_networks_ts_time_ago_is_deprecated(client):
723+
mock_data = {"values": [1, 2, 3]}
724+
responses.add(
725+
responses.GET,
726+
f"{BASE_URL}/aggregations/site-networks-ts-time-ago",
727+
json=mock_data,
728+
status=200,
729+
)
730+
731+
with pytest.warns(DeprecationWarning, match="get_site_time_series") as record:
732+
result = client.get_site_networks_ts_time_ago("site-1")
733+
734+
# Behaviour is unchanged: still returns the data and still hits the legacy endpoint.
735+
assert result == mock_data
736+
parsed = urlparse(responses.calls[0].request.url)
737+
assert parsed.path == "/api/aggregations/site-networks-ts-time-ago"
738+
# stacklevel=2 -> the warning is attributed to the caller (this test file).
739+
assert record[0].filename == __file__
740+
741+
742+
@responses.activate
743+
def test_get_site_consumption_breakdown_time_ago_is_deprecated(client):
744+
mock_data = {"breakdown": "data"}
745+
responses.add(
746+
responses.GET,
747+
f"{BASE_URL}/aggregations/consumption-breakdown-time-ago",
748+
json=mock_data,
749+
status=200,
750+
)
751+
752+
with pytest.warns(DeprecationWarning, match="get_top_consumption") as record:
753+
result = client.get_site_consumption_breakdown_time_ago("site-1")
754+
755+
assert result == mock_data
756+
parsed = urlparse(responses.calls[0].request.url)
757+
assert parsed.path == "/api/aggregations/consumption-breakdown-time-ago"
758+
assert record[0].filename == __file__

0 commit comments

Comments
 (0)