sweatstack 0.46.0__py3-none-any.whl → 0.47.0__py3-none-any.whl
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.
- sweatstack/client.py +67 -2
- sweatstack/openapi_schemas.py +8 -1
- sweatstack/schemas.py +1 -1
- {sweatstack-0.46.0.dist-info → sweatstack-0.47.0.dist-info}/METADATA +1 -1
- {sweatstack-0.46.0.dist-info → sweatstack-0.47.0.dist-info}/RECORD +7 -7
- {sweatstack-0.46.0.dist-info → sweatstack-0.47.0.dist-info}/WHEEL +0 -0
- {sweatstack-0.46.0.dist-info → sweatstack-0.47.0.dist-info}/entry_points.txt +0 -0
sweatstack/client.py
CHANGED
|
@@ -16,7 +16,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
|
16
16
|
from importlib.metadata import version
|
|
17
17
|
from io import BytesIO
|
|
18
18
|
from pathlib import Path
|
|
19
|
-
from typing import Any, Generator, get_type_hints, List, Literal
|
|
19
|
+
from typing import Any, Dict, Generator, get_type_hints, List, Literal
|
|
20
20
|
from urllib.parse import parse_qs, urlparse
|
|
21
21
|
|
|
22
22
|
import httpx
|
|
@@ -25,7 +25,8 @@ from platformdirs import user_data_dir
|
|
|
25
25
|
|
|
26
26
|
from .constants import DEFAULT_URL
|
|
27
27
|
from .schemas import (
|
|
28
|
-
ActivityDetails, ActivitySummary, Metric, Sport,
|
|
28
|
+
ActivityDetails, ActivitySummary, BackfillStatus, Metric, Sport,
|
|
29
|
+
TraceDetails, UserInfoResponse, UserSummary
|
|
29
30
|
)
|
|
30
31
|
from .utils import decode_jwt_body, make_dataframe_streamlit_compatible
|
|
31
32
|
|
|
@@ -1230,6 +1231,67 @@ class Client(OAuth2Mixin, DelegationMixin, TokenStorageMixin):
|
|
|
1230
1231
|
|
|
1231
1232
|
return self._get_user_by_id(user_id)
|
|
1232
1233
|
|
|
1234
|
+
def _parse_backfill_line(self, line: str) -> BackfillStatus | None:
|
|
1235
|
+
"""Parse a single NDJSON line from backfill status stream."""
|
|
1236
|
+
try:
|
|
1237
|
+
return BackfillStatus.model_validate_json(line)
|
|
1238
|
+
except Exception:
|
|
1239
|
+
pass
|
|
1240
|
+
return None
|
|
1241
|
+
|
|
1242
|
+
def watch_backfill_status(self, *, auto_reconnect: bool = False) -> Generator[BackfillStatus, None, None]:
|
|
1243
|
+
"""Watches backfill status from the activities backfill-status endpoint.
|
|
1244
|
+
|
|
1245
|
+
This method connects to the backfill status event stream and yields
|
|
1246
|
+
backfill_loaded_until timestamps as they are received. The connection
|
|
1247
|
+
automatically closes after 60 seconds, but can be configured to auto-reconnect.
|
|
1248
|
+
|
|
1249
|
+
Args:
|
|
1250
|
+
auto_reconnect: Whether to automatically reconnect when the connection
|
|
1251
|
+
closes and continue receiving updates. Defaults to False.
|
|
1252
|
+
|
|
1253
|
+
Yields:
|
|
1254
|
+
BackfillStatus: A BackfillStatus object for each received message.
|
|
1255
|
+
|
|
1256
|
+
Raises:
|
|
1257
|
+
HTTPStatusError: If the API request fails.
|
|
1258
|
+
"""
|
|
1259
|
+
while True:
|
|
1260
|
+
try:
|
|
1261
|
+
with self._http_client() as client:
|
|
1262
|
+
with client.stream("GET", "/api/v1/activities/backfill-status") as response:
|
|
1263
|
+
self._raise_for_status(response)
|
|
1264
|
+
|
|
1265
|
+
for line in response.iter_lines():
|
|
1266
|
+
if line.strip():
|
|
1267
|
+
parsed = self._parse_backfill_line(line)
|
|
1268
|
+
if parsed:
|
|
1269
|
+
yield parsed
|
|
1270
|
+
|
|
1271
|
+
except httpx.RequestError:
|
|
1272
|
+
if not auto_reconnect:
|
|
1273
|
+
raise
|
|
1274
|
+
time.sleep(1)
|
|
1275
|
+
if not auto_reconnect:
|
|
1276
|
+
break
|
|
1277
|
+
|
|
1278
|
+
def get_backfill_status(self) -> BackfillStatus:
|
|
1279
|
+
"""Gets the current backfill status from the activities backfill-status endpoint.
|
|
1280
|
+
|
|
1281
|
+
This method connects to the backfill status event stream and returns
|
|
1282
|
+
the first backfill_loaded_until timestamp received.
|
|
1283
|
+
|
|
1284
|
+
Returns:
|
|
1285
|
+
BackfillStatus: A BackfillStatus object containing the current backfill status.
|
|
1286
|
+
|
|
1287
|
+
Raises:
|
|
1288
|
+
HTTPStatusError: If the API request fails.
|
|
1289
|
+
ValueError: If no status message is received.
|
|
1290
|
+
"""
|
|
1291
|
+
for status in self.watch_backfill_status(auto_reconnect=False):
|
|
1292
|
+
return status
|
|
1293
|
+
raise ValueError("No backfill status received")
|
|
1294
|
+
|
|
1233
1295
|
|
|
1234
1296
|
_default_client = Client()
|
|
1235
1297
|
|
|
@@ -1276,6 +1338,9 @@ _generate_singleton_methods(
|
|
|
1276
1338
|
"get_userinfo",
|
|
1277
1339
|
"whoami",
|
|
1278
1340
|
|
|
1341
|
+
"get_backfill_status",
|
|
1342
|
+
"watch_backfill_status",
|
|
1343
|
+
|
|
1279
1344
|
"get_activities",
|
|
1280
1345
|
|
|
1281
1346
|
"get_activity",
|
sweatstack/openapi_schemas.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: openapi.json
|
|
3
|
-
# timestamp: 2025-08-
|
|
3
|
+
# timestamp: 2025-08-07T11:42:52+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -36,6 +36,12 @@ class Prompt(Enum):
|
|
|
36
36
|
select_account = 'select_account'
|
|
37
37
|
|
|
38
38
|
|
|
39
|
+
class BackfillStatus(BaseModel):
|
|
40
|
+
backfill_loaded_until: Optional[datetime] = Field(
|
|
41
|
+
..., title='Backfill Loaded Until'
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
39
45
|
class BodyAddEmailPartialsAddEmailPost(BaseModel):
|
|
40
46
|
email: EmailStr = Field(..., title='Email')
|
|
41
47
|
|
|
@@ -664,6 +670,7 @@ class BodyLoginPostLoginPost(BaseModel):
|
|
|
664
670
|
email: EmailStr = Field(..., title='Email')
|
|
665
671
|
password: SecretStr = Field(..., title='Password')
|
|
666
672
|
tz: Tz = Field(..., title='Tz')
|
|
673
|
+
state: Optional[str] = Field(None, title='State')
|
|
667
674
|
|
|
668
675
|
|
|
669
676
|
class BodyRegisterPostRegisterPost(BaseModel):
|
sweatstack/schemas.py
CHANGED
|
@@ -2,7 +2,7 @@ from enum import Enum
|
|
|
2
2
|
from typing import List, Union
|
|
3
3
|
|
|
4
4
|
from .openapi_schemas import (
|
|
5
|
-
ActivityDetails, ActivitySummary, Metric, Scope, Sport,
|
|
5
|
+
ActivityDetails, ActivitySummary, BackfillStatus, Metric, Scope, Sport,
|
|
6
6
|
TraceDetails, UserInfoResponse, UserSummary
|
|
7
7
|
)
|
|
8
8
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
sweatstack/__init__.py,sha256=tiVfgKlswRPaDMEy0gA7u8rveqEYZTA_kyB9lJ3J6Sc,21
|
|
2
2
|
sweatstack/cli.py,sha256=N1NWOgEZR2yaJvIXxo9qvp_jFlypZYb0nujpbVNYQ6A,720
|
|
3
|
-
sweatstack/client.py,sha256=
|
|
3
|
+
sweatstack/client.py,sha256=31iiErq1nWk-zFgApTN_iCWn7an7bB3VOBygGZgAOJ8,49517
|
|
4
4
|
sweatstack/constants.py,sha256=fGO6ksOv5HeISv9lHRoYm4besW1GTveXS8YD3K0ljg0,41
|
|
5
5
|
sweatstack/ipython_init.py,sha256=OtBB9dQvyLXklD4kA2x1swaVtU9u73fG4V4-zz4YRAg,139
|
|
6
6
|
sweatstack/jupyterlab_oauth2_startup.py,sha256=YcjXvzeZ459vL_dCkFi1IxX_RNAu80ZX9rwa0OXJfTM,1023
|
|
7
|
-
sweatstack/openapi_schemas.py,sha256=
|
|
7
|
+
sweatstack/openapi_schemas.py,sha256=VvquBdbssdB9D1KeJYQCx51hy1Df4SS0PjzGWXcUaew,46221
|
|
8
8
|
sweatstack/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
sweatstack/schemas.py,sha256=
|
|
9
|
+
sweatstack/schemas.py,sha256=44sXrNCYR0qtDsH8sUKR8df9zpcVA-TimkinXJBesOg,3683
|
|
10
10
|
sweatstack/streamlit.py,sha256=_PER03s0dYu5eF1MZdewPDqSvYHqMr0lZLu_EnGit3Y,13257
|
|
11
11
|
sweatstack/sweatshell.py,sha256=MYLNcWbOdceqKJ3S0Pe8dwHXEeYsGJNjQoYUXpMTftA,333
|
|
12
12
|
sweatstack/utils.py,sha256=AwHRdC1ziOZ5o9RBIB21Uxm-DoClVRAJSVvgsmSmvps,1801
|
|
13
13
|
sweatstack/Sweat Stack examples/Getting started.ipynb,sha256=k2hiSffWecoQ0VxjdpDcgFzBXDQiYEebhnAYlu8cgX8,6335204
|
|
14
|
-
sweatstack-0.
|
|
15
|
-
sweatstack-0.
|
|
16
|
-
sweatstack-0.
|
|
17
|
-
sweatstack-0.
|
|
14
|
+
sweatstack-0.47.0.dist-info/METADATA,sha256=UuRlROP5y90JVM6eopj0PklP0WvdkB1TWxy6RwALrS0,852
|
|
15
|
+
sweatstack-0.47.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
sweatstack-0.47.0.dist-info/entry_points.txt,sha256=kCzOUQI3dqbTpEYqtgYDeiKFaqaA7BMlV6D24BMzCFU,208
|
|
17
|
+
sweatstack-0.47.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|