sweatstack 0.38.0__tar.gz → 0.40.1__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.
- {sweatstack-0.38.0 → sweatstack-0.40.1}/PKG-INFO +1 -1
- {sweatstack-0.38.0 → sweatstack-0.40.1}/pyproject.toml +1 -1
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/client.py +13 -14
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/openapi_schemas.py +8 -1
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/streamlit.py +5 -5
- {sweatstack-0.38.0 → sweatstack-0.40.1}/.gitignore +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/.python-version +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/DEVELOPMENT.md +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/Makefile +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/README.md +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/playground/.ipynb_checkpoints/Untitled-checkpoint.ipynb +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/playground/README.md +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/playground/Sweat Stack examples/Getting started.ipynb +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/playground/Untitled.ipynb +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/playground/hello.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/playground/pyproject.toml +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/Sweat Stack examples/Getting started.ipynb +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/__init__.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/cli.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/constants.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/ipython_init.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/jupyterlab_oauth2_startup.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/py.typed +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/schemas.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/sweatshell.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/utils.py +0 -0
- {sweatstack-0.38.0 → sweatstack-0.40.1}/uv.lock +0 -0
|
@@ -444,7 +444,7 @@ class Client(OAuth2Mixin, DelegationMixin):
|
|
|
444
444
|
tags: list[str] | None = None,
|
|
445
445
|
limit: int = 100,
|
|
446
446
|
as_dataframe: bool = False,
|
|
447
|
-
) ->
|
|
447
|
+
) -> list[ActivitySummary] | pd.DataFrame:
|
|
448
448
|
"""Gets a list of activities based on specified filters.
|
|
449
449
|
|
|
450
450
|
Args:
|
|
@@ -456,28 +456,27 @@ class Client(OAuth2Mixin, DelegationMixin):
|
|
|
456
456
|
as_dataframe: Whether to return results as a pandas DataFrame. Defaults to False.
|
|
457
457
|
|
|
458
458
|
Returns:
|
|
459
|
-
Either a
|
|
459
|
+
Either a list of ActivitySummary objects or a pandas DataFrame containing
|
|
460
460
|
the activities data, depending on the value of as_dataframe.
|
|
461
461
|
|
|
462
462
|
Raises:
|
|
463
463
|
HTTPStatusError: If the API request fails.
|
|
464
464
|
"""
|
|
465
|
-
|
|
465
|
+
activities = list(self._get_activities_generator(
|
|
466
466
|
start=start,
|
|
467
467
|
end=end,
|
|
468
468
|
sports=sports,
|
|
469
469
|
tags=tags,
|
|
470
470
|
limit=limit,
|
|
471
|
-
)
|
|
471
|
+
))
|
|
472
472
|
if as_dataframe:
|
|
473
|
-
df = pd.DataFrame([activity.model_dump() for activity in
|
|
474
|
-
df = df.set_index(df["start"].rename("timestamp"))
|
|
473
|
+
df = pd.DataFrame([activity.model_dump() for activity in activities])
|
|
475
474
|
df = self._normalize_dataframe_column(df, "summary")
|
|
476
475
|
df = self._normalize_dataframe_column(df, "laps")
|
|
477
476
|
df = self._normalize_dataframe_column(df, "traces")
|
|
478
477
|
return self._postprocess_dataframe(df)
|
|
479
478
|
else:
|
|
480
|
-
return
|
|
479
|
+
return activities
|
|
481
480
|
|
|
482
481
|
def get_latest_activity(
|
|
483
482
|
self,
|
|
@@ -502,7 +501,7 @@ class Client(OAuth2Mixin, DelegationMixin):
|
|
|
502
501
|
StopIteration: If no activities match the filters.
|
|
503
502
|
HTTPStatusError: If the API request fails.
|
|
504
503
|
"""
|
|
505
|
-
return next(self.
|
|
504
|
+
return next(self._get_activities_generator(
|
|
506
505
|
start=start,
|
|
507
506
|
end=end,
|
|
508
507
|
sports=[sport] if sport is not None else None,
|
|
@@ -841,7 +840,7 @@ class Client(OAuth2Mixin, DelegationMixin):
|
|
|
841
840
|
tags: list[str] | None = None,
|
|
842
841
|
limit: int = 100,
|
|
843
842
|
as_dataframe: bool = False,
|
|
844
|
-
) ->
|
|
843
|
+
) -> list[TraceDetails] | pd.DataFrame:
|
|
845
844
|
"""Gets a list of traces based on specified filters.
|
|
846
845
|
|
|
847
846
|
Args:
|
|
@@ -853,23 +852,23 @@ class Client(OAuth2Mixin, DelegationMixin):
|
|
|
853
852
|
as_dataframe: Whether to return results as a pandas DataFrame. Defaults to False.
|
|
854
853
|
|
|
855
854
|
Returns:
|
|
856
|
-
Either a
|
|
855
|
+
Either a list of TraceDetails objects or a pandas DataFrame containing
|
|
857
856
|
the traces data, depending on the value of as_dataframe.
|
|
858
857
|
|
|
859
858
|
Raises:
|
|
860
859
|
HTTPStatusError: If the API request fails.
|
|
861
860
|
"""
|
|
862
|
-
|
|
861
|
+
traces = list(self._get_traces_generator(
|
|
863
862
|
start=start,
|
|
864
863
|
end=end,
|
|
865
864
|
sports=sports,
|
|
866
865
|
tags=tags,
|
|
867
866
|
limit=limit,
|
|
868
|
-
)
|
|
867
|
+
))
|
|
869
868
|
if not as_dataframe:
|
|
870
|
-
return
|
|
869
|
+
return traces
|
|
871
870
|
|
|
872
|
-
data = pd.DataFrame([trace.model_dump() for trace in
|
|
871
|
+
data = pd.DataFrame([trace.model_dump() for trace in traces])
|
|
873
872
|
|
|
874
873
|
if "activity" in data.columns:
|
|
875
874
|
data = self._normalize_dataframe_column(data, "activity")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: openapi.json
|
|
3
|
-
# timestamp: 2025-04-
|
|
3
|
+
# timestamp: 2025-04-11T08:42:56+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -332,6 +332,8 @@ class Lap(BaseModel):
|
|
|
332
332
|
start: datetime = Field(..., title='Start')
|
|
333
333
|
end: datetime = Field(..., title='End')
|
|
334
334
|
duration: timedelta = Field(..., title='Duration')
|
|
335
|
+
start_local: datetime = Field(..., title='Start Local')
|
|
336
|
+
end_local: datetime = Field(..., title='End Local')
|
|
335
337
|
|
|
336
338
|
|
|
337
339
|
class ActivityDetails(BaseModel):
|
|
@@ -347,6 +349,8 @@ class ActivityDetails(BaseModel):
|
|
|
347
349
|
traces: Optional[List[TraceDetails]] = Field(None, title='Traces')
|
|
348
350
|
distance: Optional[float] = Field(None, title='Distance')
|
|
349
351
|
duration: timedelta = Field(..., title='Duration')
|
|
352
|
+
start_local: datetime = Field(..., title='Start Local')
|
|
353
|
+
end_local: datetime = Field(..., title='End Local')
|
|
350
354
|
|
|
351
355
|
|
|
352
356
|
class ActivitySummary(BaseModel):
|
|
@@ -361,6 +365,8 @@ class ActivitySummary(BaseModel):
|
|
|
361
365
|
laps: Optional[List[Lap]] = Field(None, title='Laps')
|
|
362
366
|
traces: Optional[List[TraceDetails]] = Field(None, title='Traces')
|
|
363
367
|
duration: timedelta = Field(..., title='Duration')
|
|
368
|
+
start_local: datetime = Field(..., title='Start Local')
|
|
369
|
+
end_local: datetime = Field(..., title='End Local')
|
|
364
370
|
|
|
365
371
|
|
|
366
372
|
class TraceDetails(BaseModel):
|
|
@@ -376,6 +382,7 @@ class TraceDetails(BaseModel):
|
|
|
376
382
|
lap: Optional[Lap] = None
|
|
377
383
|
activity: Optional[ActivitySummary] = None
|
|
378
384
|
sport: Optional[Sport] = None
|
|
385
|
+
timestamp_local: datetime = Field(..., title='Timestamp Local')
|
|
379
386
|
|
|
380
387
|
|
|
381
388
|
ActivityDetails.model_rebuild()
|
|
@@ -15,7 +15,7 @@ import httpx
|
|
|
15
15
|
from .client import Client
|
|
16
16
|
from .constants import DEFAULT_URL
|
|
17
17
|
from .schemas import Metric, Scope, Sport
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
|
|
20
20
|
class StreamlitAuth:
|
|
21
21
|
def __init__(
|
|
@@ -253,7 +253,7 @@ class StreamlitAuth:
|
|
|
253
253
|
selected_activity = st.selectbox(
|
|
254
254
|
"Select an activity",
|
|
255
255
|
activities,
|
|
256
|
-
format_func=lambda activity: f"{activity.start.date().isoformat()} {
|
|
256
|
+
format_func=lambda activity: f"{activity.start.date().isoformat()} {activity.sport.display_name()}",
|
|
257
257
|
)
|
|
258
258
|
return selected_activity
|
|
259
259
|
|
|
@@ -272,7 +272,7 @@ class StreamlitAuth:
|
|
|
272
272
|
Sport or list[Sport]: The selected sport or list of sports, depending on allow_multiple.
|
|
273
273
|
|
|
274
274
|
Note:
|
|
275
|
-
Sports are displayed in a human-readable format using the
|
|
275
|
+
Sports are displayed in a human-readable format using the display_name function.
|
|
276
276
|
"""
|
|
277
277
|
if only_available:
|
|
278
278
|
sports = self.client.get_sports(only_root)
|
|
@@ -286,13 +286,13 @@ class StreamlitAuth:
|
|
|
286
286
|
selected_sport = st.multiselect(
|
|
287
287
|
"Select sports",
|
|
288
288
|
sports,
|
|
289
|
-
format_func=
|
|
289
|
+
format_func=lambda sport: sport.display_name(),
|
|
290
290
|
)
|
|
291
291
|
else:
|
|
292
292
|
selected_sport = st.selectbox(
|
|
293
293
|
"Select a sport",
|
|
294
294
|
sports,
|
|
295
|
-
format_func=
|
|
295
|
+
format_func=lambda sport: sport.display_name(),
|
|
296
296
|
)
|
|
297
297
|
return selected_sport
|
|
298
298
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sweatstack-0.38.0 → sweatstack-0.40.1}/playground/.ipynb_checkpoints/Untitled-checkpoint.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
{sweatstack-0.38.0 → sweatstack-0.40.1}/playground/Sweat Stack examples/Getting started.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sweatstack-0.38.0 → sweatstack-0.40.1}/src/sweatstack/Sweat Stack examples/Getting started.ipynb
RENAMED
|
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
|