sweatstack 0.32.0__py3-none-any.whl → 0.34.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 CHANGED
@@ -115,7 +115,7 @@ class OAuth2Mixin:
115
115
  data=token_data,
116
116
  )
117
117
  try:
118
- response.raise_for_status()
118
+ self._raise_for_status(response)
119
119
  except httpx.HTTPStatusError as e:
120
120
  raise Exception(f"SweatStack Python login failed. Please try again.") from e
121
121
  token_response = response.json()
@@ -142,7 +142,7 @@ class DelegationMixin:
142
142
  "/api/v1/oauth/delegated-token",
143
143
  json={"sub": user_id},
144
144
  )
145
- response.raise_for_status()
145
+ self._raise_for_status(response)
146
146
 
147
147
  return response.json()
148
148
 
@@ -156,7 +156,7 @@ class DelegationMixin:
156
156
  response = client.get(
157
157
  "/api/v1/oauth/principal-token",
158
158
  )
159
- response.raise_for_status()
159
+ self._raise_for_status(response)
160
160
  return response.json()
161
161
 
162
162
  def switch_back(self):
@@ -207,7 +207,7 @@ class Client(OAuth2Mixin, DelegationMixin):
207
207
  },
208
208
  )
209
209
 
210
- response.raise_for_status()
210
+ self._raise_for_status(response)
211
211
  return response.json()["access_token"]
212
212
 
213
213
  def _check_token_expiry(self, token: str) -> str:
@@ -287,6 +287,12 @@ class Client(OAuth2Mixin, DelegationMixin):
287
287
  with httpx.Client(base_url=self.url, headers=headers) as client:
288
288
  yield client
289
289
 
290
+ def _raise_for_status(self, response: httpx.Response):
291
+ if response.status_code == 422:
292
+ raise ValueError(response.json())
293
+ else:
294
+ response.raise_for_status()
295
+
290
296
  def _enums_to_strings(self, values: list[Enum | str]) -> list[str]:
291
297
  return [value.value if isinstance(value, Enum) else value for value in values]
292
298
 
@@ -320,7 +326,7 @@ class Client(OAuth2Mixin, DelegationMixin):
320
326
  url="/api/v1/activities/",
321
327
  params=params,
322
328
  )
323
- response.raise_for_status()
329
+ self._raise_for_status(response)
324
330
  activities = response.json()
325
331
  for activity in activities:
326
332
  yield ActivitySummary.model_validate(activity)
@@ -386,7 +392,7 @@ class Client(OAuth2Mixin, DelegationMixin):
386
392
  def get_activity(self, activity_id: str) -> ActivityDetails:
387
393
  with self._http_client() as client:
388
394
  response = client.get(url=f"/api/v1/activities/{activity_id}")
389
- response.raise_for_status()
395
+ self._raise_for_status(response)
390
396
  return ActivityDetails.model_validate(response.json())
391
397
 
392
398
  def get_activity_data(
@@ -403,8 +409,7 @@ class Client(OAuth2Mixin, DelegationMixin):
403
409
  url=f"/api/v1/activities/{activity_id}/data",
404
410
  params=params,
405
411
  )
406
-
407
- response.raise_for_status()
412
+ self._raise_for_status(response)
408
413
 
409
414
  df = pd.read_parquet(BytesIO(response.content))
410
415
  return self._postprocess_dataframe(df)
@@ -412,7 +417,7 @@ class Client(OAuth2Mixin, DelegationMixin):
412
417
  def get_activity_mean_max(
413
418
  self,
414
419
  activity_id: str,
415
- metric: Metric | str,
420
+ metric: Literal[Metric.power, Metric.speed] | Literal["power", "speed"],
416
421
  adaptive_sampling: bool = False,
417
422
  ) -> pd.DataFrame:
418
423
  metric = self._enums_to_strings([metric])[0]
@@ -424,7 +429,7 @@ class Client(OAuth2Mixin, DelegationMixin):
424
429
  "adaptive_sampling": adaptive_sampling,
425
430
  },
426
431
  )
427
- response.raise_for_status()
432
+ self._raise_for_status(response)
428
433
  df = pd.read_parquet(BytesIO(response.content))
429
434
  return self._postprocess_dataframe(df)
430
435
 
@@ -438,7 +443,7 @@ class Client(OAuth2Mixin, DelegationMixin):
438
443
 
439
444
  def get_latest_activity_mean_max(
440
445
  self,
441
- metric: Metric | str,
446
+ metric: Literal[Metric.power, Metric.speed] | Literal["power", "speed"],
442
447
  sport: Sport | str | None = None,
443
448
  adaptive_sampling: bool = False,
444
449
  ) -> pd.DataFrame:
@@ -453,7 +458,7 @@ class Client(OAuth2Mixin, DelegationMixin):
453
458
  start: date | str,
454
459
  end: date | str | None = None,
455
460
  metrics: list[Metric | str] | None = None,
456
- adaptive_sampling_on: Literal["power", "speed"] | None = None,
461
+ adaptive_sampling_on: Literal[Metric.power, Metric.speed] | Literal["power", "speed"] | None = None,
457
462
  ) -> pd.DataFrame:
458
463
  if sport and sports:
459
464
  raise ValueError("Cannot specify both sport and sports")
@@ -462,26 +467,23 @@ class Client(OAuth2Mixin, DelegationMixin):
462
467
  elif sports is None:
463
468
  sports = []
464
469
 
465
- sports = self._enums_to_strings(sports)
466
- metrics = self._enums_to_strings(metrics)
467
-
468
470
  params = {
469
- "sports": sports,
470
- "start": start,
471
+ "sports": self._enums_to_strings(sports),
472
+ "start": start
471
473
  }
472
474
  if end is not None:
473
475
  params["end"] = end
474
476
  if metrics is not None:
475
- params["metrics"] = metrics
477
+ params["metrics"] = self._enums_to_strings(metrics)
476
478
  if adaptive_sampling_on is not None:
477
- params["adaptive_sampling_on"] = adaptive_sampling_on
479
+ params["adaptive_sampling_on"] = self._enums_to_strings([adaptive_sampling_on])[0]
478
480
 
479
481
  with self._http_client() as client:
480
482
  response = client.get(
481
483
  url="/api/v1/activities/longitudinal-data",
482
484
  params=params,
483
485
  )
484
- response.raise_for_status()
486
+ self._raise_for_status(response)
485
487
 
486
488
  df = pd.read_parquet(BytesIO(response.content))
487
489
  return self._postprocess_dataframe(df)
@@ -490,7 +492,7 @@ class Client(OAuth2Mixin, DelegationMixin):
490
492
  self,
491
493
  *,
492
494
  sport: Sport | str,
493
- metric: Metric | str,
495
+ metric: Literal[Metric.power, Metric.speed] | Literal["power", "speed"],
494
496
  date: date | str | None = None,
495
497
  window_days: int | None = None,
496
498
  ) -> pd.DataFrame:
@@ -511,7 +513,7 @@ class Client(OAuth2Mixin, DelegationMixin):
511
513
  url="/api/v1/activities/longitudinal-mean-max",
512
514
  params=params,
513
515
  )
514
- response.raise_for_status()
516
+ self._raise_for_status(response)
515
517
 
516
518
  df = pd.read_parquet(BytesIO(response.content))
517
519
  return self._postprocess_dataframe(df)
@@ -546,7 +548,7 @@ class Client(OAuth2Mixin, DelegationMixin):
546
548
  url="/api/v1/traces/",
547
549
  params=params,
548
550
  )
549
- response.raise_for_status()
551
+ self._raise_for_status(response)
550
552
  traces = response.json()
551
553
  for trace in traces:
552
554
  yield TraceDetails.model_validate(trace)
@@ -645,7 +647,7 @@ class Client(OAuth2Mixin, DelegationMixin):
645
647
  "tags": tags,
646
648
  },
647
649
  )
648
- response.raise_for_status()
650
+ self._raise_for_status(response)
649
651
  return TraceDetails.model_validate(response.json())
650
652
 
651
653
  def get_sports(self, only_root: bool = False) -> list[Sport]:
@@ -654,7 +656,7 @@ class Client(OAuth2Mixin, DelegationMixin):
654
656
  url="/api/v1/profile/sports/",
655
657
  params={"only_root": only_root},
656
658
  )
657
- response.raise_for_status()
659
+ self._raise_for_status(response)
658
660
  return [Sport(sport) for sport in response.json()]
659
661
 
660
662
  def get_tags(self) -> list[str]:
@@ -662,7 +664,7 @@ class Client(OAuth2Mixin, DelegationMixin):
662
664
  response = client.get(
663
665
  url="/api/v1/profile/tags/",
664
666
  )
665
- response.raise_for_status()
667
+ self._raise_for_status(response)
666
668
  return response.json()
667
669
 
668
670
  def get_users(self) -> list[UserSummary]:
@@ -670,7 +672,7 @@ class Client(OAuth2Mixin, DelegationMixin):
670
672
  response = client.get(
671
673
  url="/api/v1/users/",
672
674
  )
673
- response.raise_for_status()
675
+ self._raise_for_status(response)
674
676
  return [UserSummary.model_validate(user) for user in response.json()]
675
677
 
676
678
  _default_client = Client()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sweatstack
3
- Version: 0.32.0
3
+ Version: 0.34.0
4
4
  Summary: The official Python client for SweatStack
5
5
  Author-email: Aart Goossens <aart@gssns.io>
6
6
  Requires-Python: >=3.9
@@ -1,6 +1,6 @@
1
1
  sweatstack/__init__.py,sha256=tiVfgKlswRPaDMEy0gA7u8rveqEYZTA_kyB9lJ3J6Sc,21
2
2
  sweatstack/cli.py,sha256=N1NWOgEZR2yaJvIXxo9qvp_jFlypZYb0nujpbVNYQ6A,720
3
- sweatstack/client.py,sha256=HrB_kVapWrl5D3FWHaLdvNt9KO5Xh-jS_OKKT7-uqBM,24467
3
+ sweatstack/client.py,sha256=7i9BLZBz67OrERtbS9h3R5h6GHYmco7kbvs0GZdc1C4,24913
4
4
  sweatstack/constants.py,sha256=fGO6ksOv5HeISv9lHRoYm4besW1GTveXS8YD3K0ljg0,41
5
5
  sweatstack/ipython_init.py,sha256=zBGUlMFkdpLvsNpOpwrNaKRUpUZhzaICvH8ODJgMPcI,229
6
6
  sweatstack/jupyterlab_oauth2_startup.py,sha256=eZ6xi0Sa4hO4vUanimq0SqjduHtiywCURSDNWk_I-7s,1200
@@ -11,7 +11,7 @@ sweatstack/streamlit.py,sha256=gsgiIDW-INGTvF24ANnX5LJ17ZxnvXx95sjSmtcTlnY,8062
11
11
  sweatstack/sweatshell.py,sha256=MYLNcWbOdceqKJ3S0Pe8dwHXEeYsGJNjQoYUXpMTftA,333
12
12
  sweatstack/utils.py,sha256=3K97OSWQy5KZ97QiBbW4Kx1wDGxwyA96ZWpwIbkcQZc,2090
13
13
  sweatstack/Sweat Stack examples/Getting started.ipynb,sha256=k2hiSffWecoQ0VxjdpDcgFzBXDQiYEebhnAYlu8cgX8,6335204
14
- sweatstack-0.32.0.dist-info/METADATA,sha256=H4irGGWTmukppSnU2kohAsCNDprC9fIUw7EijMpbus8,775
15
- sweatstack-0.32.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- sweatstack-0.32.0.dist-info/entry_points.txt,sha256=kCzOUQI3dqbTpEYqtgYDeiKFaqaA7BMlV6D24BMzCFU,208
17
- sweatstack-0.32.0.dist-info/RECORD,,
14
+ sweatstack-0.34.0.dist-info/METADATA,sha256=GA_2D0iHIbNZL7n03qMS80a_yyzkROtNPD2qxWzC5JE,775
15
+ sweatstack-0.34.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ sweatstack-0.34.0.dist-info/entry_points.txt,sha256=kCzOUQI3dqbTpEYqtgYDeiKFaqaA7BMlV6D24BMzCFU,208
17
+ sweatstack-0.34.0.dist-info/RECORD,,