garth 0.5.20.dev4__tar.gz → 0.5.22.dev0__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.
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.github/workflows/ci.yml +8 -6
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.github/workflows/publish.yml +2 -2
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/PKG-INFO +2 -1
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/pyproject.toml +1 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/body_battery/events.py +4 -4
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/body_battery/readings.py +2 -2
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/hrv.py +4 -1
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/sleep.py +4 -1
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/http.py +1 -1
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/sso.py +21 -8
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/utils.py +1 -1
- garth-0.5.22.dev0/src/garth/version.py +1 -0
- garth-0.5.22.dev0/tests/data/cassettes/test_daily_body_battery_stress_get_incomplete_data.yaml +350 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/test_body_battery_data.py +9 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/test_http.py +1 -1
- garth-0.5.22.dev0/uv.lock +2263 -0
- garth-0.5.20.dev4/src/garth/version.py +0 -1
- garth-0.5.20.dev4/uv.lock +0 -2129
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.coderabbit.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.devcontainer/Dockerfile +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.devcontainer/devcontainer.json +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.devcontainer/noop.txt +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.gitattributes +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.github/dependabot.yml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.gitignore +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.markdownlint.json +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.pre-commit-config.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/.vscode/settings.json +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/LICENSE +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/Makefile +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/README.md +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/colabs/chatgpt_analysis_of_stats.ipynb +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/colabs/sleep.ipynb +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/colabs/stress.ipynb +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/__init__.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/auth_tokens.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/cli.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/__init__.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/_base.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/body_battery/__init__.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/body_battery/daily_stress.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/data/weight.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/exc.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/py.typed +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/stats/__init__.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/stats/_base.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/stats/hrv.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/stats/hydration.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/stats/intensity_minutes.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/stats/sleep.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/stats/steps.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/stats/stress.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/users/__init__.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/users/profile.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/src/garth/users/settings.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/12129115726_ACTIVITY.fit +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_client_request.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_connectapi.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_delete.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_download.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_exchange.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_login_command.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_login_email_password_fail.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_login_mfa_fail.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_login_return_on_mfa.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_login_success.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_login_success_mfa.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_login_success_mfa_async.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_profile_alias.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_put.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_refresh_oauth2_token.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_resume_login.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_upload.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_user_profile.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_user_settings.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_user_settings_sleep_windows.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/cassettes/test_username.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/conftest.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_body_battery_data_get.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_body_battery_data_list.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_body_battery_properties_edge_cases.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_daily_body_battery_stress_get.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_daily_body_battery_stress_get_no_data.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_daily_body_battery_stress_list.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_get_daily_weight_data.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_get_manual_weight_data.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_get_nonexistent_weight_data.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_hrv_data_get.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_hrv_data_list.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_sleep_data_get.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_sleep_data_list.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_weight_data_list.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_weight_data_list_empty.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/cassettes/test_weight_data_list_single_day.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/test_hrv_data.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/test_sleep_data.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/data/test_weight_data.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_hrv.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_hrv_no_results.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_hrv_paginate.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_hrv_paginate_no_results.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_hydration.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_intensity_minutes.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_sleep.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_steps.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_stress.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_daily_stress_pagination.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_weekly_intensity_minutes.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_weekly_steps.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_weekly_stress.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_weekly_stress_beyond_data.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/cassettes/test_weekly_stress_pagination.yaml +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/test_hrv.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/test_hydration.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/test_intensity_minutes.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/test_sleep_stats.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/test_steps.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/stats/test_stress.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/test_auth_tokens.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/test_cli.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/test_sso.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/test_users.py +0 -0
- {garth-0.5.20.dev4 → garth-0.5.22.dev0}/tests/test_utils.py +0 -0
|
@@ -24,13 +24,14 @@ jobs:
|
|
|
24
24
|
strategy:
|
|
25
25
|
fail-fast: false
|
|
26
26
|
matrix:
|
|
27
|
-
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
27
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
28
28
|
steps:
|
|
29
|
-
- uses: actions/checkout@
|
|
29
|
+
- uses: actions/checkout@v6
|
|
30
30
|
|
|
31
|
-
- uses: actions/setup-python@
|
|
31
|
+
- uses: actions/setup-python@v6
|
|
32
32
|
with:
|
|
33
33
|
python-version: ${{ matrix.python-version }}
|
|
34
|
+
allow-prereleases: true
|
|
34
35
|
|
|
35
36
|
- uses: astral-sh/setup-uv@v7
|
|
36
37
|
|
|
@@ -51,7 +52,7 @@ jobs:
|
|
|
51
52
|
fail-fast: false
|
|
52
53
|
matrix:
|
|
53
54
|
os: [ubuntu, macos, windows]
|
|
54
|
-
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
55
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
55
56
|
|
|
56
57
|
env:
|
|
57
58
|
PYTHON: ${{ matrix.python-version }}
|
|
@@ -60,11 +61,12 @@ jobs:
|
|
|
60
61
|
runs-on: ${{ matrix.os }}-latest
|
|
61
62
|
|
|
62
63
|
steps:
|
|
63
|
-
- uses: actions/checkout@
|
|
64
|
+
- uses: actions/checkout@v6
|
|
64
65
|
|
|
65
|
-
- uses: actions/setup-python@
|
|
66
|
+
- uses: actions/setup-python@v6
|
|
66
67
|
with:
|
|
67
68
|
python-version: ${{ matrix.python-version }}
|
|
69
|
+
allow-prereleases: true
|
|
68
70
|
|
|
69
71
|
- uses: astral-sh/setup-uv@v7
|
|
70
72
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: garth
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.22.dev0
|
|
4
4
|
Summary: Garmin SSO auth + Connect client
|
|
5
5
|
Project-URL: Homepage, https://github.com/matin/garth
|
|
6
6
|
Project-URL: Repository, https://github.com/matin/garth
|
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
24
|
Requires-Python: >=3.10
|
|
24
25
|
Requires-Dist: pydantic<3.0.0,>=1.10.12
|
|
25
26
|
Requires-Dist: requests-oauthlib<3.0.0,>=1.3.1
|
|
@@ -20,6 +20,7 @@ classifiers = [
|
|
|
20
20
|
"Programming Language :: Python :: 3.11",
|
|
21
21
|
"Programming Language :: Python :: 3.12",
|
|
22
22
|
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Programming Language :: Python :: 3.14",
|
|
23
24
|
"Operating System :: MacOS :: MacOS X",
|
|
24
25
|
"Operating System :: Microsoft :: Windows",
|
|
25
26
|
"Operating System :: POSIX :: Linux",
|
|
@@ -121,7 +121,7 @@ class BodyBatteryData(Data):
|
|
|
121
121
|
|
|
122
122
|
# Validate numeric fields
|
|
123
123
|
timezone_offset = event_data.get("timezoneOffset", 0)
|
|
124
|
-
if not isinstance(timezone_offset,
|
|
124
|
+
if not isinstance(timezone_offset, int | float):
|
|
125
125
|
logging.warning(
|
|
126
126
|
f"Invalid timezone_offset type: "
|
|
127
127
|
f"{type(timezone_offset)}, using 0"
|
|
@@ -129,7 +129,7 @@ class BodyBatteryData(Data):
|
|
|
129
129
|
timezone_offset = 0
|
|
130
130
|
|
|
131
131
|
duration_ms = event_data.get("durationInMilliseconds", 0)
|
|
132
|
-
if not isinstance(duration_ms,
|
|
132
|
+
if not isinstance(duration_ms, int | float):
|
|
133
133
|
logging.warning(
|
|
134
134
|
f"Invalid durationInMilliseconds type: "
|
|
135
135
|
f"{type(duration_ms)}, using 0"
|
|
@@ -137,7 +137,7 @@ class BodyBatteryData(Data):
|
|
|
137
137
|
duration_ms = 0
|
|
138
138
|
|
|
139
139
|
battery_impact = event_data.get("bodyBatteryImpact", 0)
|
|
140
|
-
if not isinstance(battery_impact,
|
|
140
|
+
if not isinstance(battery_impact, int | float):
|
|
141
141
|
logging.warning(
|
|
142
142
|
f"Invalid bodyBatteryImpact type: "
|
|
143
143
|
f"{type(battery_impact)}, using 0"
|
|
@@ -178,7 +178,7 @@ class BodyBatteryData(Data):
|
|
|
178
178
|
# Validate average_stress
|
|
179
179
|
avg_stress = item.get("averageStress")
|
|
180
180
|
if avg_stress is not None and not isinstance(
|
|
181
|
-
avg_stress,
|
|
181
|
+
avg_stress, int | float
|
|
182
182
|
):
|
|
183
183
|
logging.warning(
|
|
184
184
|
f"Invalid averageStress type: "
|
|
@@ -29,8 +29,8 @@ def parse_body_battery_readings(
|
|
|
29
29
|
for values in body_battery_values_array or []:
|
|
30
30
|
# Each reading requires 4 values: timestamp, status, level, version
|
|
31
31
|
if len(values) >= 4:
|
|
32
|
-
timestamp, status, level, version = values
|
|
33
|
-
if
|
|
32
|
+
timestamp, status, level, version, *_ = values
|
|
33
|
+
if level is None or status is None:
|
|
34
34
|
continue
|
|
35
35
|
readings.append(
|
|
36
36
|
BodyBatteryReading(
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import builtins
|
|
1
4
|
from datetime import date, datetime
|
|
2
5
|
|
|
3
6
|
from pydantic.dataclasses import dataclass
|
|
@@ -39,7 +42,7 @@ class HRVReading:
|
|
|
39
42
|
class HRVData(Data):
|
|
40
43
|
user_profile_pk: int
|
|
41
44
|
hrv_summary: HRVSummary
|
|
42
|
-
hrv_readings: list[HRVReading]
|
|
45
|
+
hrv_readings: builtins.list[HRVReading]
|
|
43
46
|
start_timestamp_gmt: datetime
|
|
44
47
|
end_timestamp_gmt: datetime
|
|
45
48
|
start_timestamp_local: datetime
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import builtins
|
|
1
4
|
from datetime import date, datetime
|
|
2
5
|
|
|
3
6
|
from pydantic.dataclasses import dataclass
|
|
@@ -93,7 +96,7 @@ class SleepMovement:
|
|
|
93
96
|
@dataclass
|
|
94
97
|
class SleepData(Data):
|
|
95
98
|
daily_sleep_dto: DailySleepDTO
|
|
96
|
-
sleep_movement: list[SleepMovement] | None = None
|
|
99
|
+
sleep_movement: builtins.list[SleepMovement] | None = None
|
|
97
100
|
|
|
98
101
|
@classmethod
|
|
99
102
|
def get(
|
|
@@ -24,7 +24,7 @@ class Client:
|
|
|
24
24
|
oauth2_token: OAuth2Token | dict[str, Any] | None = None
|
|
25
25
|
timeout: int = 10
|
|
26
26
|
retries: int = 3
|
|
27
|
-
status_forcelist: tuple[int, ...] = (408,
|
|
27
|
+
status_forcelist: tuple[int, ...] = (408, 500, 502, 503, 504)
|
|
28
28
|
backoff_factor: float = 0.5
|
|
29
29
|
pool_connections: int = 10
|
|
30
30
|
pool_maxsize: int = 10
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
4
|
+
import inspect
|
|
2
5
|
import re
|
|
3
6
|
import time
|
|
4
7
|
from collections.abc import Callable
|
|
@@ -46,7 +49,7 @@ def login(
|
|
|
46
49
|
email: str,
|
|
47
50
|
password: str,
|
|
48
51
|
/,
|
|
49
|
-
client:
|
|
52
|
+
client: http.Client | None = None,
|
|
50
53
|
prompt_mfa: Callable | None = lambda: input("MFA code: "),
|
|
51
54
|
return_on_mfa: bool = False,
|
|
52
55
|
) -> (
|
|
@@ -128,11 +131,11 @@ def login(
|
|
|
128
131
|
title = get_title(client.last_resp.text)
|
|
129
132
|
|
|
130
133
|
if title != "Success":
|
|
131
|
-
raise GarthException(f"
|
|
134
|
+
raise GarthException(f"Login failed: {title}") # pragma: no cover
|
|
132
135
|
return _complete_login(client)
|
|
133
136
|
|
|
134
137
|
|
|
135
|
-
def get_oauth1_token(ticket: str, client:
|
|
138
|
+
def get_oauth1_token(ticket: str, client: http.Client) -> OAuth1Token:
|
|
136
139
|
sess = GarminOAuth1Session(parent=client.sess)
|
|
137
140
|
base_url = f"https://connectapi.{client.domain}/oauth-service/oauth/"
|
|
138
141
|
login_url = f"https://sso.{client.domain}/sso/embed"
|
|
@@ -151,7 +154,7 @@ def get_oauth1_token(ticket: str, client: "http.Client") -> OAuth1Token:
|
|
|
151
154
|
return OAuth1Token(domain=client.domain, **token) # type: ignore
|
|
152
155
|
|
|
153
156
|
|
|
154
|
-
def exchange(oauth1: OAuth1Token, client:
|
|
157
|
+
def exchange(oauth1: OAuth1Token, client: http.Client) -> OAuth2Token:
|
|
155
158
|
sess = GarminOAuth1Session(
|
|
156
159
|
resource_owner_key=oauth1.oauth_token,
|
|
157
160
|
resource_owner_secret=oauth1.oauth_token_secret,
|
|
@@ -176,10 +179,10 @@ def exchange(oauth1: OAuth1Token, client: "http.Client") -> OAuth2Token:
|
|
|
176
179
|
|
|
177
180
|
|
|
178
181
|
def handle_mfa(
|
|
179
|
-
client:
|
|
182
|
+
client: http.Client, signin_params: dict, prompt_mfa: Callable
|
|
180
183
|
) -> None:
|
|
181
184
|
csrf_token = get_csrf_token(client.last_resp.text)
|
|
182
|
-
if
|
|
185
|
+
if inspect.iscoroutinefunction(prompt_mfa):
|
|
183
186
|
mfa_code = asyncio.run(prompt_mfa())
|
|
184
187
|
else:
|
|
185
188
|
mfa_code = prompt_mfa()
|
|
@@ -196,6 +199,10 @@ def handle_mfa(
|
|
|
196
199
|
},
|
|
197
200
|
)
|
|
198
201
|
|
|
202
|
+
title = get_title(client.last_resp.text)
|
|
203
|
+
if title != "Success":
|
|
204
|
+
raise GarthException("MFA verification failed")
|
|
205
|
+
|
|
199
206
|
|
|
200
207
|
def set_expirations(token: dict) -> dict:
|
|
201
208
|
token["expires_at"] = int(time.time() + token["expires_in"])
|
|
@@ -234,10 +241,16 @@ def resume_login(
|
|
|
234
241
|
client = client_state["client"]
|
|
235
242
|
signin_params = client_state["signin_params"]
|
|
236
243
|
handle_mfa(client, signin_params, lambda: mfa_code)
|
|
237
|
-
|
|
244
|
+
oauth1, oauth2 = _complete_login(client)
|
|
245
|
+
|
|
246
|
+
# Explicitly set tokens on the client
|
|
247
|
+
client.oauth1_token = oauth1
|
|
248
|
+
client.oauth2_token = oauth2
|
|
249
|
+
|
|
250
|
+
return oauth1, oauth2
|
|
238
251
|
|
|
239
252
|
|
|
240
|
-
def _complete_login(client:
|
|
253
|
+
def _complete_login(client: http.Client) -> tuple[OAuth1Token, OAuth2Token]:
|
|
241
254
|
"""Complete the login process after successful authentication.
|
|
242
255
|
|
|
243
256
|
Args:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.5.22.dev0"
|
garth-0.5.22.dev0/tests/data/cassettes/test_daily_body_battery_stress_get_incomplete_data.yaml
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
interactions:
|
|
2
|
+
- request:
|
|
3
|
+
body: null
|
|
4
|
+
headers:
|
|
5
|
+
Accept:
|
|
6
|
+
- '*/*'
|
|
7
|
+
Accept-Encoding:
|
|
8
|
+
- gzip, deflate
|
|
9
|
+
Authorization:
|
|
10
|
+
- Bearer SANITIZED
|
|
11
|
+
Connection:
|
|
12
|
+
- keep-alive
|
|
13
|
+
User-Agent:
|
|
14
|
+
- GCM-iOS-5.7.2.1
|
|
15
|
+
method: GET
|
|
16
|
+
uri: https://connectapi.garmin.com/wellness-service/wellness/dailyStress/2025-12-18
|
|
17
|
+
response:
|
|
18
|
+
body:
|
|
19
|
+
string: '{"userProfilePK": 104516149, "calendarDate": "2025-12-18", "startTimestampGMT":
|
|
20
|
+
"2025-12-18T06:00:00.0", "endTimestampGMT": "2025-12-19T06:00:00.0", "startTimestampLocal":
|
|
21
|
+
"2025-12-18T00:00:00.0", "endTimestampLocal": "2025-12-19T00:00:00.0", "maxStressLevel":
|
|
22
|
+
97, "avgStressLevel": 22, "stressChartValueOffset": 1, "stressChartYAxisOrigin":
|
|
23
|
+
-1, "stressValueDescriptorsDTOList": [{"key": "timestamp", "index": 0}, {"key":
|
|
24
|
+
"stressLevel", "index": 1}], "stressValuesArray": [[1766037600000, -1], [1766037780000,
|
|
25
|
+
-1], [1766037960000, -1], [1766038140000, -1], [1766038320000, -1], [1766038500000,
|
|
26
|
+
-1], [1766038680000, -1], [1766038860000, -1], [1766039040000, -1], [1766039220000,
|
|
27
|
+
-1], [1766039400000, -1], [1766039580000, -1], [1766039760000, -1], [1766039940000,
|
|
28
|
+
-1], [1766040120000, 25], [1766040300000, 25], [1766040480000, 25], [1766040660000,
|
|
29
|
+
28], [1766040840000, 34], [1766041020000, -1], [1766041200000, 25], [1766041380000,
|
|
30
|
+
16], [1766041560000, 16], [1766041740000, 15], [1766041920000, 11], [1766042100000,
|
|
31
|
+
16], [1766042280000, 18], [1766042460000, 14], [1766042640000, 13], [1766042820000,
|
|
32
|
+
15], [1766043000000, 15], [1766043180000, 15], [1766043360000, 12], [1766043540000,
|
|
33
|
+
13], [1766043720000, 12], [1766043900000, 26], [1766044080000, 38], [1766044260000,
|
|
34
|
+
44], [1766044440000, 28], [1766044620000, 25], [1766044800000, 20], [1766044980000,
|
|
35
|
+
18], [1766045160000, 18], [1766045340000, 17], [1766045520000, 15], [1766045700000,
|
|
36
|
+
16], [1766045880000, 15], [1766046060000, 10], [1766046240000, 12], [1766046420000,
|
|
37
|
+
8], [1766046600000, 4], [1766046780000, 4], [1766046960000, 5], [1766047140000,
|
|
38
|
+
4], [1766047320000, 4], [1766047500000, 2], [1766047680000, 3], [1766047860000,
|
|
39
|
+
2], [1766048040000, 4], [1766048220000, 5], [1766048400000, 15], [1766048580000,
|
|
40
|
+
15], [1766048760000, 20], [1766048940000, 17], [1766049120000, 14], [1766049300000,
|
|
41
|
+
17], [1766049480000, 12], [1766049660000, 5], [1766049840000, 5], [1766050020000,
|
|
42
|
+
2], [1766050200000, 2], [1766050380000, 2], [1766050560000, 3], [1766050740000,
|
|
43
|
+
3], [1766050920000, 3], [1766051100000, 3], [1766051280000, 5], [1766051460000,
|
|
44
|
+
3], [1766051640000, 2], [1766051820000, 5], [1766052000000, 5], [1766052180000,
|
|
45
|
+
3], [1766052360000, 5], [1766052540000, 3], [1766052720000, 3], [1766052900000,
|
|
46
|
+
4], [1766053080000, 4], [1766053260000, 7], [1766053440000, 5], [1766053620000,
|
|
47
|
+
6], [1766053800000, 5], [1766053980000, 5], [1766054160000, 6], [1766054340000,
|
|
48
|
+
14], [1766054520000, 8], [1766054700000, 5], [1766054880000, 2], [1766055060000,
|
|
49
|
+
6], [1766055240000, 6], [1766055420000, 4], [1766055600000, 10], [1766055780000,
|
|
50
|
+
3], [1766055960000, 5], [1766056140000, 2], [1766056320000, 2], [1766056500000,
|
|
51
|
+
6], [1766056680000, 4], [1766056860000, 4], [1766057040000, 4], [1766057220000,
|
|
52
|
+
4], [1766057400000, 6], [1766057580000, 6], [1766057760000, 7], [1766057940000,
|
|
53
|
+
16], [1766058120000, 25], [1766058300000, 25], [1766058480000, 12], [1766058660000,
|
|
54
|
+
11], [1766058840000, 16], [1766059020000, 19], [1766059200000, 15], [1766059380000,
|
|
55
|
+
14], [1766059560000, 13], [1766059740000, 15], [1766059920000, 12], [1766060100000,
|
|
56
|
+
12], [1766060280000, 15], [1766060460000, 15], [1766060640000, 15], [1766060820000,
|
|
57
|
+
15], [1766061000000, 16], [1766061180000, 17], [1766061360000, 11], [1766061540000,
|
|
58
|
+
14], [1766061720000, 13], [1766061900000, 7], [1766062080000, 8], [1766062260000,
|
|
59
|
+
11], [1766062440000, 16], [1766062620000, 14], [1766062800000, 15], [1766062980000,
|
|
60
|
+
4], [1766063160000, 8], [1766063340000, 12], [1766063520000, 13], [1766063700000,
|
|
61
|
+
6], [1766063880000, 11], [1766064060000, 13], [1766064240000, 10], [1766064420000,
|
|
62
|
+
12], [1766064600000, 16], [1766064780000, 13], [1766064960000, 6], [1766065140000,
|
|
63
|
+
9], [1766065320000, 5], [1766065500000, 6], [1766065680000, 5], [1766065860000,
|
|
64
|
+
6], [1766066040000, 13], [1766066220000, 10], [1766066400000, 15], [1766066580000,
|
|
65
|
+
20], [1766066760000, 23], [1766066940000, 22], [1766067120000, 18], [1766067300000,
|
|
66
|
+
17], [1766067480000, 17], [1766067660000, 16], [1766067840000, 14], [1766068020000,
|
|
67
|
+
33], [1766068200000, 26], [1766068380000, 24], [1766068560000, 31], [1766068740000,
|
|
68
|
+
30], [1766083860000, -1], [1766084040000, -1], [1766084220000, -1], [1766084400000,
|
|
69
|
+
-1], [1766084580000, -1], [1766084760000, -1], [1766084940000, -1], [1766085120000,
|
|
70
|
+
-1], [1766085300000, -1], [1766085480000, -1], [1766085660000, -1], [1766085840000,
|
|
71
|
+
-1], [1766086020000, -1], [1766086200000, -1], [1766086380000, -1], [1766086560000,
|
|
72
|
+
-1], [1766086740000, -1], [1766086920000, -1], [1766087100000, -1], [1766087280000,
|
|
73
|
+
-1], [1766087460000, -1], [1766087640000, -1], [1766087820000, -1], [1766088000000,
|
|
74
|
+
-1], [1766088180000, -1], [1766088360000, -1], [1766088540000, -1], [1766088720000,
|
|
75
|
+
-1], [1766088900000, -1], [1766089080000, -1], [1766089260000, -1], [1766089440000,
|
|
76
|
+
-1], [1766089620000, -1], [1766089800000, -1], [1766089980000, -1], [1766090160000,
|
|
77
|
+
-1], [1766090340000, -1], [1766090520000, -1], [1766090700000, -1], [1766090880000,
|
|
78
|
+
-1], [1766091060000, -1], [1766091240000, -1], [1766091420000, -1], [1766091600000,
|
|
79
|
+
-1], [1766091780000, -1], [1766091960000, -1], [1766092140000, -1], [1766092320000,
|
|
80
|
+
-1], [1766092500000, -1], [1766092680000, -1], [1766092860000, -1], [1766093040000,
|
|
81
|
+
-1], [1766093220000, -1], [1766093400000, -1], [1766093580000, -1], [1766093760000,
|
|
82
|
+
-1], [1766093940000, -1], [1766094120000, -1], [1766094300000, -1], [1766094480000,
|
|
83
|
+
-1], [1766094660000, -1], [1766094840000, -1], [1766095020000, -1], [1766095200000,
|
|
84
|
+
-1], [1766095380000, -1], [1766095560000, -1], [1766095740000, -1], [1766095920000,
|
|
85
|
+
-1], [1766096100000, -1], [1766096280000, -1], [1766096460000, -1], [1766096640000,
|
|
86
|
+
-1], [1766096820000, -1], [1766097000000, -1], [1766097180000, -1], [1766097360000,
|
|
87
|
+
-1], [1766097540000, -1], [1766097720000, -1], [1766097900000, -1], [1766098080000,
|
|
88
|
+
-1], [1766098260000, -1], [1766098440000, -1], [1766098620000, -1], [1766098800000,
|
|
89
|
+
-1], [1766098980000, -1], [1766099160000, -1], [1766099340000, -1], [1766099520000,
|
|
90
|
+
-1], [1766099700000, -1], [1766099880000, -1], [1766100060000, -1], [1766100240000,
|
|
91
|
+
-1], [1766100420000, -1], [1766100600000, -1], [1766100780000, -1], [1766100960000,
|
|
92
|
+
-1], [1766101140000, -1], [1766101320000, -1], [1766101500000, -1], [1766101680000,
|
|
93
|
+
-1], [1766101860000, -1], [1766102040000, -1], [1766102220000, -1], [1766102400000,
|
|
94
|
+
-1], [1766102580000, -1], [1766102760000, -1], [1766102940000, -1], [1766103120000,
|
|
95
|
+
-1], [1766103300000, -1], [1766103480000, -1], [1766103660000, -1], [1766103840000,
|
|
96
|
+
-1], [1766104020000, -1], [1766104200000, -1], [1766104380000, -1], [1766104560000,
|
|
97
|
+
-1], [1766104740000, -1], [1766104920000, -1], [1766105100000, -1], [1766105280000,
|
|
98
|
+
-1], [1766105460000, -1], [1766105640000, -1], [1766105820000, -1], [1766106000000,
|
|
99
|
+
-1], [1766106180000, -1], [1766106360000, -1], [1766106540000, -1], [1766106720000,
|
|
100
|
+
-1], [1766106900000, -1], [1766107080000, -1], [1766107260000, 92], [1766107440000,
|
|
101
|
+
84], [1766107620000, 71], [1766107800000, 57], [1766107980000, -2], [1766108160000,
|
|
102
|
+
-1], [1766108340000, -2], [1766108520000, -1], [1766108700000, -2], [1766108880000,
|
|
103
|
+
-2], [1766109060000, -2], [1766109240000, -2], [1766109420000, -1], [1766109600000,
|
|
104
|
+
78], [1766109780000, 59], [1766109960000, 51], [1766110140000, 54], [1766110320000,
|
|
105
|
+
43], [1766110500000, -1], [1766110680000, -1], [1766110860000, -1], [1766111040000,
|
|
106
|
+
-2], [1766111220000, -1], [1766111400000, 66], [1766111580000, 55], [1766111760000,
|
|
107
|
+
58], [1766111940000, 41], [1766112120000, 37], [1766112300000, 40], [1766112480000,
|
|
108
|
+
33], [1766112660000, 30], [1766112840000, 28], [1766113020000, 31], [1766113200000,
|
|
109
|
+
-2], [1766113380000, -2], [1766113560000, -2], [1766113740000, -1], [1766113920000,
|
|
110
|
+
73], [1766114100000, 69], [1766114280000, 64], [1766114460000, 36], [1766114640000,
|
|
111
|
+
30], [1766114820000, 25], [1766115000000, 25], [1766115180000, 58], [1766115360000,
|
|
112
|
+
50], [1766115540000, 67], [1766115720000, 73], [1766115900000, 79], [1766116080000,
|
|
113
|
+
63], [1766116260000, 34], [1766116440000, 39], [1766116620000, 43], [1766116800000,
|
|
114
|
+
-2], [1766116980000, -2], [1766117160000, -2], [1766117340000, -1], [1766117520000,
|
|
115
|
+
89], [1766117700000, 86], [1766117880000, 91], [1766118060000, 80], [1766118240000,
|
|
116
|
+
84], [1766118420000, 64], [1766118600000, 40], [1766118780000, 34], [1766118960000,
|
|
117
|
+
37], [1766119140000, 34], [1766119320000, 34], [1766119500000, 32], [1766119680000,
|
|
118
|
+
31], [1766119860000, 28], [1766120040000, 25], [1766120220000, 29], [1766120400000,
|
|
119
|
+
28], [1766120580000, 27], [1766120760000, 24], [1766120940000, 25], [1766121120000,
|
|
120
|
+
31], [1766121300000, 38], [1766121480000, 24], [1766121660000, 25], [1766121840000,
|
|
121
|
+
24], [1766122020000, 21], [1766122200000, 23], [1766122380000, 29], [1766122560000,
|
|
122
|
+
37], [1766122740000, 32], [1766122920000, 31], [1766123100000, 34], [1766123280000,
|
|
123
|
+
34], [1766123460000, 31], [1766123640000, 25], [1766123820000, 32]], "bodyBatteryValueDescriptorsDTOList":
|
|
124
|
+
[{"bodyBatteryValueDescriptorIndex": 0, "bodyBatteryValueDescriptorKey": "timestamp"},
|
|
125
|
+
{"bodyBatteryValueDescriptorIndex": 1, "bodyBatteryValueDescriptorKey": "bodyBatteryStatus"},
|
|
126
|
+
{"bodyBatteryValueDescriptorIndex": 2, "bodyBatteryValueDescriptorKey": "bodyBatteryLevel"},
|
|
127
|
+
{"bodyBatteryValueDescriptorIndex": 3, "bodyBatteryValueDescriptorKey": "bodyBatteryVersion"}],
|
|
128
|
+
"bodyBatteryValuesArray": [[1766037600000, null, null, 2.0], [1766037780000,
|
|
129
|
+
null, null, 2.0], [1766037960000, null, null, 2.0], [1766038140000, null,
|
|
130
|
+
null, 2.0], [1766038320000, null, null, 2.0], [1766038500000, null, null,
|
|
131
|
+
2.0], [1766038680000, null, null, 2.0], [1766038860000, null, null, 2.0],
|
|
132
|
+
[1766039040000, null, null, 2.0], [1766039220000, null, null, 2.0], [1766039400000,
|
|
133
|
+
null, null, 2.0], [1766039580000, null, null, 2.0], [1766039760000, null,
|
|
134
|
+
null, 2.0], [1766039940000, "RESET", 28, 2.0], [1766040120000, "MEASURED",
|
|
135
|
+
26, 2.0], [1766040300000, "MEASURED", 26, 2.0], [1766040480000, "MEASURED",
|
|
136
|
+
26, 2.0], [1766040660000, "MEASURED", 26, 2.0], [1766040840000, "MEASURED",
|
|
137
|
+
26, 2.0], [1766041020000, "MEASURED", 26, 2.0], [1766041200000, "MEASURED",
|
|
138
|
+
26, 2.0], [1766041380000, "MEASURED", 26, 2.0], [1766041560000, "MEASURED",
|
|
139
|
+
26, 2.0], [1766041740000, "MEASURED", 26, 2.0], [1766041920000, "MEASURED",
|
|
140
|
+
26, 2.0], [1766042100000, "MEASURED", 28, 2.0], [1766042280000, "MEASURED",
|
|
141
|
+
28, 2.0], [1766042460000, "MEASURED", 28, 2.0], [1766042640000, "MEASURED",
|
|
142
|
+
28, 2.0], [1766042820000, "MEASURED", 29, 2.0], [1766043000000, "MEASURED",
|
|
143
|
+
29, 2.0], [1766043180000, "MEASURED", 30, 2.0], [1766043360000, "MEASURED",
|
|
144
|
+
30, 2.0], [1766043540000, "MEASURED", 31, 2.0], [1766043720000, "MEASURED",
|
|
145
|
+
32, 2.0], [1766043900000, "MEASURED", 32, 2.0], [1766044080000, "MEASURED",
|
|
146
|
+
32, 2.0], [1766044260000, "MEASURED", 32, 2.0], [1766044440000, "MEASURED",
|
|
147
|
+
32, 2.0], [1766044620000, "MEASURED", 33, 2.0], [1766044800000, "MEASURED",
|
|
148
|
+
33, 2.0], [1766044980000, "MEASURED", 33, 2.0], [1766045160000, "MEASURED",
|
|
149
|
+
34, 2.0], [1766045340000, "MEASURED", 34, 2.0], [1766045520000, "MEASURED",
|
|
150
|
+
34, 2.0], [1766045700000, "MEASURED", 36, 2.0], [1766045880000, "MEASURED",
|
|
151
|
+
36, 2.0], [1766046060000, "MEASURED", 36, 2.0], [1766046240000, "MEASURED",
|
|
152
|
+
37, 2.0], [1766046420000, "MEASURED", 38, 2.0], [1766046600000, "MEASURED",
|
|
153
|
+
39, 2.0], [1766046780000, "MEASURED", 40, 2.0], [1766046960000, "MEASURED",
|
|
154
|
+
40, 2.0], [1766047140000, "MEASURED", 41, 2.0], [1766047320000, "MEASURED",
|
|
155
|
+
42, 2.0], [1766047500000, "MEASURED", 43, 2.0], [1766047680000, "MEASURED",
|
|
156
|
+
44, 2.0], [1766047860000, "MEASURED", 45, 2.0], [1766048040000, "MEASURED",
|
|
157
|
+
46, 2.0], [1766048220000, "MEASURED", 47, 2.0], [1766048400000, "MEASURED",
|
|
158
|
+
48, 2.0], [1766048580000, "MEASURED", 49, 2.0], [1766048760000, "MEASURED",
|
|
159
|
+
49, 2.0], [1766048940000, "MEASURED", 50, 2.0], [1766049120000, "MEASURED",
|
|
160
|
+
50, 2.0], [1766049300000, "MEASURED", 52, 2.0], [1766049480000, "MEASURED",
|
|
161
|
+
52, 2.0], [1766049660000, "MEASURED", 52, 2.0], [1766049840000, "MEASURED",
|
|
162
|
+
53, 2.0], [1766050020000, "MEASURED", 55, 2.0], [1766050200000, "MEASURED",
|
|
163
|
+
55, 2.0], [1766050380000, "MEASURED", 56, 2.0], [1766050560000, "MEASURED",
|
|
164
|
+
58, 2.0], [1766050740000, "MEASURED", 58, 2.0], [1766050920000, "MEASURED",
|
|
165
|
+
59, 2.0], [1766051100000, "MEASURED", 60, 2.0], [1766051280000, "MEASURED",
|
|
166
|
+
60, 2.0], [1766051460000, "MEASURED", 61, 2.0], [1766051640000, "MEASURED",
|
|
167
|
+
62, 2.0], [1766051820000, "MEASURED", 62, 2.0], [1766052000000, "MEASURED",
|
|
168
|
+
63, 2.0], [1766052180000, "MEASURED", 64, 2.0], [1766052360000, "MEASURED",
|
|
169
|
+
65, 2.0], [1766052540000, "MEASURED", 65, 2.0], [1766052720000, "MEASURED",
|
|
170
|
+
66, 2.0], [1766052900000, "MEASURED", 67, 2.0], [1766053080000, "MEASURED",
|
|
171
|
+
68, 2.0], [1766053260000, "MEASURED", 68, 2.0], [1766053440000, "MEASURED",
|
|
172
|
+
68, 2.0], [1766053620000, "MEASURED", 69, 2.0], [1766053800000, "MEASURED",
|
|
173
|
+
69, 2.0], [1766053980000, "MEASURED", 71, 2.0], [1766054160000, "MEASURED",
|
|
174
|
+
71, 2.0], [1766054340000, "MEASURED", 72, 2.0], [1766054520000, "MEASURED",
|
|
175
|
+
72, 2.0], [1766054700000, "MEASURED", 73, 2.0], [1766054880000, "MEASURED",
|
|
176
|
+
73, 2.0], [1766055060000, "MEASURED", 74, 2.0], [1766055240000, "MEASURED",
|
|
177
|
+
75, 2.0], [1766055420000, "MEASURED", 75, 2.0], [1766055600000, "MEASURED",
|
|
178
|
+
76, 2.0], [1766055780000, "MEASURED", 77, 2.0], [1766055960000, "MEASURED",
|
|
179
|
+
77, 2.0], [1766056140000, "MEASURED", 78, 2.0], [1766056320000, "MEASURED",
|
|
180
|
+
79, 2.0], [1766056500000, "MEASURED", 79, 2.0], [1766056680000, "MEASURED",
|
|
181
|
+
80, 2.0], [1766056860000, "MEASURED", 80, 2.0], [1766057040000, "MEASURED",
|
|
182
|
+
81, 2.0], [1766057220000, "MEASURED", 81, 2.0], [1766057400000, "MEASURED",
|
|
183
|
+
82, 2.0], [1766057580000, "MEASURED", 83, 2.0], [1766057760000, "MEASURED",
|
|
184
|
+
83, 2.0], [1766057940000, "MEASURED", 83, 2.0], [1766058120000, "MEASURED",
|
|
185
|
+
84, 2.0], [1766058300000, "MEASURED", 84, 2.0], [1766058480000, "MEASURED",
|
|
186
|
+
84, 2.0], [1766058660000, "MEASURED", 84, 2.0], [1766058840000, "MEASURED",
|
|
187
|
+
84, 2.0], [1766059020000, "MEASURED", 85, 2.0], [1766059200000, "MEASURED",
|
|
188
|
+
85, 2.0], [1766059380000, "MEASURED", 86, 2.0], [1766059560000, "MEASURED",
|
|
189
|
+
86, 2.0], [1766059740000, "MEASURED", 86, 2.0], [1766059920000, "MEASURED",
|
|
190
|
+
86, 2.0], [1766060100000, "MEASURED", 87, 2.0], [1766060280000, "MEASURED",
|
|
191
|
+
87, 2.0], [1766060460000, "MEASURED", 87, 2.0], [1766060640000, "MEASURED",
|
|
192
|
+
87, 2.0], [1766060820000, "MEASURED", 87, 2.0], [1766061000000, "MEASURED",
|
|
193
|
+
88, 2.0], [1766061180000, "MEASURED", 89, 2.0], [1766061360000, "MEASURED",
|
|
194
|
+
89, 2.0], [1766061540000, "MEASURED", 89, 2.0], [1766061720000, "MEASURED",
|
|
195
|
+
89, 2.0], [1766061900000, "MEASURED", 89, 2.0], [1766062080000, "MEASURED",
|
|
196
|
+
89, 2.0], [1766062260000, "MEASURED", 90, 2.0], [1766062440000, "MEASURED",
|
|
197
|
+
90, 2.0], [1766062620000, "MEASURED", 91, 2.0], [1766062800000, "MEASURED",
|
|
198
|
+
91, 2.0], [1766062980000, "MEASURED", 91, 2.0], [1766063160000, "MEASURED",
|
|
199
|
+
92, 2.0], [1766063340000, "MEASURED", 92, 2.0], [1766063520000, "MEASURED",
|
|
200
|
+
93, 2.0], [1766063700000, "MEASURED", 93, 2.0], [1766063880000, "MEASURED",
|
|
201
|
+
94, 2.0], [1766064060000, "MEASURED", 94, 2.0], [1766064240000, "MEASURED",
|
|
202
|
+
94, 2.0], [1766064420000, "MEASURED", 94, 2.0], [1766064600000, "MEASURED",
|
|
203
|
+
95, 2.0], [1766064780000, "MEASURED", 95, 2.0], [1766064960000, "MEASURED",
|
|
204
|
+
95, 2.0], [1766065140000, "MEASURED", 96, 2.0], [1766065320000, "MEASURED",
|
|
205
|
+
96, 2.0], [1766065500000, "MEASURED", 96, 2.0], [1766065680000, "MEASURED",
|
|
206
|
+
96, 2.0], [1766065860000, "MEASURED", 96, 2.0], [1766066040000, "MEASURED",
|
|
207
|
+
96, 2.0], [1766066220000, "MEASURED", 97, 2.0], [1766066400000, "MEASURED",
|
|
208
|
+
97, 2.0], [1766066580000, "MEASURED", 97, 2.0], [1766066760000, "MEASURED",
|
|
209
|
+
97, 2.0], [1766066940000, "MEASURED", 97, 2.0], [1766067120000, "MEASURED",
|
|
210
|
+
96, 2.0], [1766067300000, "MEASURED", 96, 2.0], [1766067480000, "MEASURED",
|
|
211
|
+
96, 2.0], [1766067660000, "MEASURED", 96, 2.0], [1766067840000, "MEASURED",
|
|
212
|
+
96, 2.0], [1766068020000, "MEASURED", 95, 2.0], [1766068200000, "MEASURED",
|
|
213
|
+
95, 2.0], [1766068380000, "MEASURED", 95, 2.0], [1766068560000, "MEASURED",
|
|
214
|
+
94, 2.0], [1766068740000, "MEASURED", 94, 2.0], [1766083860000, null, null,
|
|
215
|
+
2.0], [1766084040000, null, null, 2.0], [1766084220000, null, null, 2.0],
|
|
216
|
+
[1766084400000, null, null, 2.0], [1766084580000, null, null, 2.0], [1766084760000,
|
|
217
|
+
null, null, 2.0], [1766084940000, null, null, 2.0], [1766085120000, null,
|
|
218
|
+
null, 2.0], [1766085300000, null, null, 2.0], [1766085480000, null, null,
|
|
219
|
+
2.0], [1766085660000, null, null, 2.0], [1766085840000, null, null, 2.0],
|
|
220
|
+
[1766086020000, null, null, 2.0], [1766086200000, null, null, 2.0], [1766086380000,
|
|
221
|
+
null, null, 2.0], [1766086560000, null, null, 2.0], [1766086740000, null,
|
|
222
|
+
null, 2.0], [1766086920000, null, null, 2.0], [1766087100000, null, null,
|
|
223
|
+
2.0], [1766087280000, null, null, 2.0], [1766087460000, null, null, 2.0],
|
|
224
|
+
[1766087640000, null, null, 2.0], [1766087820000, null, null, 2.0], [1766088000000,
|
|
225
|
+
null, null, 2.0], [1766088180000, null, null, 2.0], [1766088360000, null,
|
|
226
|
+
null, 2.0], [1766088540000, null, null, 2.0], [1766088720000, null, null,
|
|
227
|
+
2.0], [1766088900000, null, null, 2.0], [1766089080000, null, null, 2.0],
|
|
228
|
+
[1766089260000, null, null, 2.0], [1766089440000, null, null, 2.0], [1766089620000,
|
|
229
|
+
null, null, 2.0], [1766089800000, null, null, 2.0], [1766089980000, null,
|
|
230
|
+
null, 2.0], [1766090160000, null, null, 2.0], [1766090340000, null, null,
|
|
231
|
+
2.0], [1766090520000, null, null, 2.0], [1766090700000, null, null, 2.0],
|
|
232
|
+
[1766090880000, null, null, 2.0], [1766091060000, null, null, 2.0], [1766091240000,
|
|
233
|
+
null, null, 2.0], [1766091420000, null, null, 2.0], [1766091600000, null,
|
|
234
|
+
null, 2.0], [1766091780000, null, null, 2.0], [1766091960000, null, null,
|
|
235
|
+
2.0], [1766092140000, null, null, 2.0], [1766092320000, null, null, 2.0],
|
|
236
|
+
[1766092500000, null, null, 2.0], [1766092680000, null, null, 2.0], [1766092860000,
|
|
237
|
+
null, null, 2.0], [1766093040000, null, null, 2.0], [1766093220000, null,
|
|
238
|
+
null, 2.0], [1766093400000, null, null, 2.0], [1766093580000, null, null,
|
|
239
|
+
2.0], [1766093760000, null, null, 2.0], [1766093940000, null, null, 2.0],
|
|
240
|
+
[1766094120000, null, null, 2.0], [1766094300000, null, null, 2.0], [1766094480000,
|
|
241
|
+
null, null, 2.0], [1766094660000, null, null, 2.0], [1766094840000, null,
|
|
242
|
+
null, 2.0], [1766095020000, null, null, 2.0], [1766095200000, null, null,
|
|
243
|
+
2.0], [1766095380000, null, null, 2.0], [1766095560000, null, null, 2.0],
|
|
244
|
+
[1766095740000, null, null, 2.0], [1766095920000, null, null, 2.0], [1766096100000,
|
|
245
|
+
null, null, 2.0], [1766096280000, null, null, 2.0], [1766096460000, null,
|
|
246
|
+
null, 2.0], [1766096640000, null, null, 2.0], [1766096820000, null, null,
|
|
247
|
+
2.0], [1766097000000, null, null, 2.0], [1766097180000, null, null, 2.0],
|
|
248
|
+
[1766097360000, null, null, 2.0], [1766097540000, null, null, 2.0], [1766097720000,
|
|
249
|
+
null, null, 2.0], [1766097900000, null, null, 2.0], [1766098080000, null,
|
|
250
|
+
null, 2.0], [1766098260000, null, null, 2.0], [1766098440000, null, null,
|
|
251
|
+
2.0], [1766098620000, null, null, 2.0], [1766098800000, null, null, 2.0],
|
|
252
|
+
[1766098980000, null, null, 2.0], [1766099160000, null, null, 2.0], [1766099340000,
|
|
253
|
+
null, null, 2.0], [1766099520000, null, null, 2.0], [1766099700000, null,
|
|
254
|
+
null, 2.0], [1766099880000, null, null, 2.0], [1766100060000, null, null,
|
|
255
|
+
2.0], [1766100240000, null, null, 2.0], [1766100420000, null, null, 2.0],
|
|
256
|
+
[1766100600000, null, null, 2.0], [1766100780000, null, null, 2.0], [1766100960000,
|
|
257
|
+
null, null, 2.0], [1766101140000, null, null, 2.0], [1766101320000, null,
|
|
258
|
+
null, 2.0], [1766101500000, null, null, 2.0], [1766101680000, null, null,
|
|
259
|
+
2.0], [1766101860000, null, null, 2.0], [1766102040000, null, null, 2.0],
|
|
260
|
+
[1766102220000, null, null, 2.0], [1766102400000, null, null, 2.0], [1766102580000,
|
|
261
|
+
null, null, 2.0], [1766102760000, null, null, 2.0], [1766102940000, null,
|
|
262
|
+
null, 2.0], [1766103120000, null, null, 2.0], [1766103300000, null, null,
|
|
263
|
+
2.0], [1766103480000, null, null, 2.0], [1766103660000, null, null, 2.0],
|
|
264
|
+
[1766103840000, null, null, 2.0], [1766104020000, null, null, 2.0], [1766104200000,
|
|
265
|
+
null, null, 2.0], [1766104380000, null, null, 2.0], [1766104560000, null,
|
|
266
|
+
null, 2.0], [1766104740000, null, null, 2.0], [1766104920000, null, null,
|
|
267
|
+
2.0], [1766105100000, null, null, 2.0], [1766105280000, null, null, 2.0],
|
|
268
|
+
[1766105460000, null, null, 2.0], [1766105640000, null, null, 2.0], [1766105820000,
|
|
269
|
+
null, null, 2.0], [1766106000000, null, null, 2.0], [1766106180000, "MEASURED",
|
|
270
|
+
35, 2.0], [1766106360000, "MEASURED", 34, 2.0], [1766106540000, "MEASURED",
|
|
271
|
+
34, 2.0], [1766106720000, "MEASURED", 34, 2.0], [1766106900000, "MEASURED",
|
|
272
|
+
34, 2.0], [1766107080000, "MEASURED", 33, 2.0], [1766107260000, "MEASURED",
|
|
273
|
+
33, 2.0], [1766107440000, "MEASURED", 32, 2.0], [1766107620000, "MEASURED",
|
|
274
|
+
32, 2.0], [1766107800000, "MEASURED", 31, 2.0], [1766107980000, "MEASURED",
|
|
275
|
+
31, 2.0], [1766108160000, "MEASURED", 31, 2.0], [1766108340000, "MEASURED",
|
|
276
|
+
31, 2.0], [1766108520000, "MEASURED", 30, 2.0], [1766108700000, "MEASURED",
|
|
277
|
+
30, 2.0], [1766108880000, "MEASURED", 30, 2.0], [1766109060000, "MEASURED",
|
|
278
|
+
30, 2.0], [1766109240000, "MEASURED", 30, 2.0], [1766109420000, "MEASURED",
|
|
279
|
+
30, 2.0], [1766109600000, "MEASURED", 29, 2.0], [1766109780000, "MEASURED",
|
|
280
|
+
29, 2.0], [1766109960000, "MEASURED", 29, 2.0], [1766110140000, "MEASURED",
|
|
281
|
+
29, 2.0], [1766110320000, "MEASURED", 29, 2.0], [1766110500000, "MEASURED",
|
|
282
|
+
28, 2.0], [1766110680000, "MEASURED", 28, 2.0], [1766110860000, "MEASURED",
|
|
283
|
+
28, 2.0], [1766111040000, "MEASURED", 28, 2.0], [1766111220000, "MEASURED",
|
|
284
|
+
28, 2.0], [1766111400000, "MEASURED", 28, 2.0], [1766111580000, "MEASURED",
|
|
285
|
+
27, 2.0], [1766111760000, "MEASURED", 27, 2.0], [1766111940000, "MEASURED",
|
|
286
|
+
27, 2.0], [1766112120000, "MEASURED", 27, 2.0], [1766112300000, "MEASURED",
|
|
287
|
+
27, 2.0], [1766112480000, "MEASURED", 26, 2.0], [1766112660000, "MEASURED",
|
|
288
|
+
26, 2.0], [1766112840000, "MEASURED", 26, 2.0], [1766113020000, "MEASURED",
|
|
289
|
+
26, 2.0], [1766113200000, "MEASURED", 26, 2.0], [1766113380000, "MEASURED",
|
|
290
|
+
25, 2.0], [1766113560000, "MEASURED", 25, 2.0], [1766113740000, "MEASURED",
|
|
291
|
+
25, 2.0], [1766113920000, "MEASURED", 25, 2.0], [1766114100000, "MEASURED",
|
|
292
|
+
24, 2.0], [1766114280000, "MEASURED", 24, 2.0], [1766114460000, "MEASURED",
|
|
293
|
+
24, 2.0], [1766114640000, "MEASURED", 24, 2.0], [1766114820000, "MEASURED",
|
|
294
|
+
24, 2.0], [1766115000000, "MEASURED", 24, 2.0], [1766115180000, "MEASURED",
|
|
295
|
+
24, 2.0], [1766115360000, "MEASURED", 24, 2.0], [1766115540000, "MEASURED",
|
|
296
|
+
24, 2.0], [1766115720000, "MEASURED", 23, 2.0], [1766115900000, "MEASURED",
|
|
297
|
+
23, 2.0], [1766116080000, "MEASURED", 23, 2.0], [1766116260000, "MEASURED",
|
|
298
|
+
23, 2.0], [1766116440000, "MEASURED", 23, 2.0], [1766116620000, "MEASURED",
|
|
299
|
+
22, 2.0], [1766116800000, "MEASURED", 22, 2.0], [1766116980000, "MEASURED",
|
|
300
|
+
22, 2.0], [1766117160000, "MEASURED", 22, 2.0], [1766117340000, "MEASURED",
|
|
301
|
+
22, 2.0], [1766117520000, "MEASURED", 21, 2.0], [1766117700000, "MEASURED",
|
|
302
|
+
21, 2.0], [1766117880000, "MEASURED", 21, 2.0], [1766118060000, "MEASURED",
|
|
303
|
+
21, 2.0], [1766118240000, "MEASURED", 20, 2.0], [1766118420000, "MEASURED",
|
|
304
|
+
20, 2.0], [1766118600000, "MEASURED", 20, 2.0], [1766118780000, "MEASURED",
|
|
305
|
+
20, 2.0], [1766118960000, "MEASURED", 20, 2.0], [1766119140000, "MEASURED",
|
|
306
|
+
20, 2.0], [1766119320000, "MEASURED", 19, 2.0], [1766119500000, "MEASURED",
|
|
307
|
+
19, 2.0], [1766119680000, "MEASURED", 19, 2.0], [1766119860000, "MEASURED",
|
|
308
|
+
19, 2.0], [1766120040000, "MEASURED", 19, 2.0], [1766120220000, "MEASURED",
|
|
309
|
+
19, 2.0], [1766120400000, "MEASURED", 19, 2.0], [1766120580000, "MEASURED",
|
|
310
|
+
19, 2.0], [1766120760000, "MEASURED", 19, 2.0], [1766120940000, "MEASURED",
|
|
311
|
+
19, 2.0], [1766121120000, "MEASURED", 18, 2.0], [1766121300000, "MEASURED",
|
|
312
|
+
18, 2.0], [1766121480000, "MEASURED", 18, 2.0], [1766121660000, "MEASURED",
|
|
313
|
+
18, 2.0], [1766121840000, "MEASURED", 18, 2.0], [1766122020000, "MEASURED",
|
|
314
|
+
18, 2.0], [1766122200000, "MEASURED", 18, 2.0], [1766122380000, "MEASURED",
|
|
315
|
+
18, 2.0], [1766122560000, "MEASURED", 18, 2.0], [1766122740000, "MEASURED",
|
|
316
|
+
18, 2.0], [1766122920000, "MEASURED", 18, 2.0], [1766123100000, "MEASURED",
|
|
317
|
+
18, 2.0], [1766123280000, "MEASURED", 18, 2.0], [1766123460000, "MEASURED",
|
|
318
|
+
18, 2.0], [1766123640000, "MEASURED", 18, 2.0], [1766123820000, "MEASURED",
|
|
319
|
+
18, 2.0]]}'
|
|
320
|
+
headers:
|
|
321
|
+
CF-RAY:
|
|
322
|
+
- 9b0a4923693fd930-QRO
|
|
323
|
+
Cache-Control:
|
|
324
|
+
- no-cache, no-store, private
|
|
325
|
+
Connection:
|
|
326
|
+
- keep-alive
|
|
327
|
+
Content-Type:
|
|
328
|
+
- application/json
|
|
329
|
+
Date:
|
|
330
|
+
- Fri, 19 Dec 2025 22:20:10 GMT
|
|
331
|
+
NEL:
|
|
332
|
+
- '{"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}'
|
|
333
|
+
Report-To:
|
|
334
|
+
- '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=V%2FWjj7T5kCnWOJMyV%2FGr8OhrvUE3nUWvXMLrAXEjdLUZt29WdJVmC%2FGG0cnI4qRvjEcSFKe3B%2FVk%2Fp%2B4yUFbtOv2rIf66Df%2FNJERdCDWA0yjbLrKnLcuPqHOJr2SLvX9whFe95uPs3%2BcCPiKz2l9Ek9xiQ%3D%3D"}],"group":"cf-nel","max_age":604800}'
|
|
335
|
+
Server:
|
|
336
|
+
- cloudflare
|
|
337
|
+
Set-Cookie:
|
|
338
|
+
- _cfuvid=SANITIZED; path=SANITIZED; domain=SANITIZED; HttpOnly; Secure; SameSite=SANITIZED
|
|
339
|
+
Transfer-Encoding:
|
|
340
|
+
- chunked
|
|
341
|
+
alt-svc:
|
|
342
|
+
- h3=":443"; ma=86400
|
|
343
|
+
cf-cache-status:
|
|
344
|
+
- DYNAMIC
|
|
345
|
+
pragma:
|
|
346
|
+
- no-cache
|
|
347
|
+
status:
|
|
348
|
+
code: 200
|
|
349
|
+
message: OK
|
|
350
|
+
version: 1
|
|
@@ -110,10 +110,19 @@ def test_daily_body_battery_stress_get(authed_client: Client):
|
|
|
110
110
|
def test_daily_body_battery_stress_get_no_data(authed_client: Client):
|
|
111
111
|
# Test with a date that likely has no data
|
|
112
112
|
daily_data = DailyBodyBatteryStress.get("2020-01-01", client=authed_client)
|
|
113
|
+
|
|
113
114
|
# Should return None if no data available
|
|
114
115
|
assert daily_data is None or isinstance(daily_data, DailyBodyBatteryStress)
|
|
115
116
|
|
|
116
117
|
|
|
118
|
+
@pytest.mark.vcr
|
|
119
|
+
def test_daily_body_battery_stress_get_incomplete_data(authed_client: Client):
|
|
120
|
+
daily_data = DailyBodyBatteryStress.get("2025-12-18", client=authed_client)
|
|
121
|
+
assert daily_data
|
|
122
|
+
assert all(r.level is not None for r in daily_data.body_battery_readings)
|
|
123
|
+
assert all(r.status is not None for r in daily_data.body_battery_readings)
|
|
124
|
+
|
|
125
|
+
|
|
117
126
|
@pytest.mark.vcr
|
|
118
127
|
def test_daily_body_battery_stress_list(authed_client: Client):
|
|
119
128
|
days = 3
|