otf-api 0.13.2__tar.gz → 0.14.0__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.
Files changed (65) hide show
  1. {otf_api-0.13.2/src/otf_api.egg-info → otf_api-0.14.0}/PKG-INFO +1 -1
  2. {otf_api-0.13.2 → otf_api-0.14.0}/pyproject.toml +3 -4
  3. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/__init__.py +1 -1
  4. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/client.py +15 -0
  5. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/members/member_client.py +1 -1
  6. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/studios/studio_client.py +1 -1
  7. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/workouts/workout_api.py +3 -2
  8. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/workouts/workout_client.py +2 -2
  9. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/auth/auth.py +14 -0
  10. {otf_api-0.13.2 → otf_api-0.14.0/src/otf_api.egg-info}/PKG-INFO +1 -1
  11. {otf_api-0.13.2 → otf_api-0.14.0}/LICENSE +0 -0
  12. {otf_api-0.13.2 → otf_api-0.14.0}/README.md +0 -0
  13. {otf_api-0.13.2 → otf_api-0.14.0}/setup.cfg +0 -0
  14. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/__init__.py +0 -0
  15. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/_compat.py +0 -0
  16. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/api.py +0 -0
  17. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/bookings/__init__.py +0 -0
  18. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/bookings/booking_api.py +0 -0
  19. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/bookings/booking_client.py +0 -0
  20. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/members/__init__.py +0 -0
  21. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/members/member_api.py +0 -0
  22. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/studios/__init__.py +0 -0
  23. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/studios/studio_api.py +0 -0
  24. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/utils.py +0 -0
  25. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/api/workouts/__init__.py +0 -0
  26. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/auth/__init__.py +0 -0
  27. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/auth/user.py +0 -0
  28. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/auth/utils.py +0 -0
  29. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/cache.py +0 -0
  30. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/exceptions.py +0 -0
  31. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/__init__.py +0 -0
  32. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/base.py +0 -0
  33. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/bookings/__init__.py +0 -0
  34. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/bookings/bookings.py +0 -0
  35. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/bookings/bookings_v2.py +0 -0
  36. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/bookings/classes.py +0 -0
  37. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/bookings/enums.py +0 -0
  38. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/bookings/filters.py +0 -0
  39. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/bookings/ratings.py +0 -0
  40. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/members/__init__.py +0 -0
  41. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/members/member_detail.py +0 -0
  42. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/members/member_membership.py +0 -0
  43. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/members/member_purchases.py +0 -0
  44. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/members/notifications.py +0 -0
  45. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/mixins.py +0 -0
  46. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/studios/__init__.py +0 -0
  47. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/studios/enums.py +0 -0
  48. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/studios/studio_detail.py +0 -0
  49. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/studios/studio_services.py +0 -0
  50. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/__init__.py +0 -0
  51. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/body_composition_list.py +0 -0
  52. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/challenge_tracker_content.py +0 -0
  53. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/challenge_tracker_detail.py +0 -0
  54. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/enums.py +0 -0
  55. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/lifetime_stats.py +0 -0
  56. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/out_of_studio_workout_history.py +0 -0
  57. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/performance_summary.py +0 -0
  58. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/telemetry.py +0 -0
  59. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/models/workouts/workout.py +0 -0
  60. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api/py.typed +0 -0
  61. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api.egg-info/SOURCES.txt +0 -0
  62. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api.egg-info/dependency_links.txt +0 -0
  63. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api.egg-info/requires.txt +0 -0
  64. {otf_api-0.13.2 → otf_api-0.14.0}/src/otf_api.egg-info/top_level.txt +0 -0
  65. {otf_api-0.13.2 → otf_api-0.14.0}/tests/test_filters.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otf-api
3
- Version: 0.13.2
3
+ Version: 0.14.0
4
4
  Summary: Python OrangeTheory Fitness API Client
5
5
  Author-email: Jessica Smith <j.smith.git1@gmail.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "otf-api"
3
- version = "0.13.2"
3
+ version = "0.14.0"
4
4
  description = "Python OrangeTheory Fitness API Client"
5
5
  authors = [{ name = "Jessica Smith", email = "j.smith.git1@gmail.com" }]
6
6
  requires-python = ">=3.11"
@@ -39,7 +39,6 @@ Documentation = "https://otf-api.readthedocs.io/en/stable/"
39
39
  dev = [
40
40
  "build==1.2.1",
41
41
  "bump-my-version>=0.23.0,<0.24",
42
- "mypy==1.10.0",
43
42
  "mypy-boto3-cognito-identity>=1.38.0",
44
43
  "mypy-boto3-cognito-idp>=1.35.93,<2",
45
44
  "pre-commit==3.7.1",
@@ -51,7 +50,7 @@ dev = [
51
50
  docs = [
52
51
  "autodoc-pydantic>=2.2.0",
53
52
  "furo>=2024.8.6",
54
- "sphinx==8.3.0",
53
+ "sphinx>=8.3.0",
55
54
  "sphinx-autobuild==2024.10.3",
56
55
  "sphinx-autodoc-typehints==3.2.0",
57
56
  "sphinx-autodoc2==0.5.0",
@@ -72,5 +71,5 @@ default-groups = ["dev"]
72
71
  pythonpath = ["src"]
73
72
 
74
73
  [build-system]
75
- requires = ["setuptools >= 61.0"]
74
+ requires = ["setuptools >= 80.0"]
76
75
  build-backend = "setuptools.build_meta"
@@ -36,7 +36,7 @@ def _setup_logging() -> None:
36
36
 
37
37
  _setup_logging()
38
38
 
39
- __version__ = "0.13.2"
39
+ __version__ = "0.14.0"
40
40
 
41
41
 
42
42
  __all__ = ["Otf", "OtfUser", "models"]
@@ -49,6 +49,21 @@ class OtfClient:
49
49
  )
50
50
  atexit.register(self.session.close)
51
51
 
52
+ def __getstate__(self):
53
+ """Get the state of the OtfClient instance for serialization."""
54
+ state = self.__dict__.copy()
55
+ # Remove circular references
56
+ state.pop("session", None)
57
+ return state
58
+
59
+ def __setstate__(self, state): # noqa
60
+ """Set the state of the OtfClient instance from serialized data."""
61
+ self.__dict__.update(state)
62
+ self.session = httpx.Client(
63
+ headers=HEADERS, auth=self.user.httpx_auth, timeout=httpx.Timeout(20.0, connect=60.0)
64
+ )
65
+ atexit.register(self.session.close)
66
+
52
67
  def _build_request(
53
68
  self,
54
69
  method: str,
@@ -14,7 +14,7 @@ class MemberClient:
14
14
  self.client = client
15
15
  self.member_uuid = client.member_uuid
16
16
 
17
- @CACHE.memoize(expire=600, tag="member_detail", ignore=(0,))
17
+ @CACHE.memoize(expire=600, tag="member_detail")
18
18
  def get_member_detail(self) -> dict:
19
19
  """Retrieve raw member details."""
20
20
  return self.client.default_request(
@@ -15,7 +15,7 @@ class StudioClient:
15
15
  self.client = client
16
16
  self.member_uuid = client.member_uuid
17
17
 
18
- @CACHE.memoize(expire=600, tag="studio_detail", ignore=(0,))
18
+ @CACHE.memoize(expire=600, tag="studio_detail")
19
19
  def get_studio_detail(self, studio_uuid: str) -> dict:
20
20
  """Retrieve raw studio details."""
21
21
  return self.client.default_request("GET", f"/mobile/v1/studios/{studio_uuid}")["data"]
@@ -242,13 +242,14 @@ class WorkoutApi:
242
242
  return workout
243
243
 
244
244
  def get_workouts(
245
- self, start_date: date | str | None = None, end_date: date | str | None = None
245
+ self, start_date: date | str | None = None, end_date: date | str | None = None, max_data_points: int = 150
246
246
  ) -> list[models.Workout]:
247
247
  """Get the member's workouts, using the new bookings endpoint and the performance summary endpoint.
248
248
 
249
249
  Args:
250
250
  start_date (date | str | None): The start date for the workouts. If None, defaults to 30 days ago.
251
251
  end_date (date | str | None): The end date for the workouts. If None, defaults to today.
252
+ max_data_points (int): The maximum number of data points to return for the telemetry. Default is 150.
252
253
 
253
254
  Returns:
254
255
  list[Workout]: The member's workouts.
@@ -265,7 +266,7 @@ class WorkoutApi:
265
266
  bookings_dict = {b.workout.id: b for b in bookings if b.workout}
266
267
 
267
268
  perf_summaries_dict = self.client.get_perf_summaries_threaded(list(bookings_dict.keys()))
268
- telemetry_dict = self.client.get_telemetry_threaded(list(perf_summaries_dict.keys()))
269
+ telemetry_dict = self.client.get_telemetry_threaded(list(perf_summaries_dict.keys()), max_data_points)
269
270
  perf_summary_to_class_uuid_map = self.client.get_perf_summary_to_class_uuid_mapping()
270
271
 
271
272
  workouts: list[models.Workout] = []
@@ -43,7 +43,7 @@ class WorkoutClient:
43
43
  params = {"limit": limit} if limit else {}
44
44
  return self.performance_summary_request("GET", "/v1/performance-summaries", params=params)
45
45
 
46
- @CACHE.memoize(expire=600, tag="performance_summary", ignore=(0,))
46
+ @CACHE.memoize(expire=600, tag="performance_summary")
47
47
  def get_performance_summary(self, performance_summary_id: str) -> dict:
48
48
  """Retrieve raw performance summary data."""
49
49
  return self.performance_summary_request("GET", f"/v1/performance-summaries/{performance_summary_id}")
@@ -54,7 +54,7 @@ class WorkoutClient:
54
54
  "history"
55
55
  ]
56
56
 
57
- @CACHE.memoize(expire=600, tag="telemetry", ignore=(0,))
57
+ @CACHE.memoize(expire=600, tag="telemetry")
58
58
  def get_telemetry(self, performance_summary_id: str, max_data_points: int = 150) -> dict:
59
59
  """Retrieve raw telemetry data."""
60
60
  return self.telemetry_request(
@@ -340,6 +340,20 @@ class OtfCognito(Cognito):
340
340
  self.device_group_key = device_metadata.get("DeviceGroupKey", self.device_group_key)
341
341
  CACHE.write_device_data_to_cache(self.device_metadata)
342
342
 
343
+ def __getstate__(self):
344
+ """Get the state of the object for pickling."""
345
+ state = self.__dict__.copy()
346
+ del state["idp_client"]
347
+ del state["id_client"]
348
+ return state
349
+
350
+ def __setstate__(self, state): # noqa
351
+ """Set the state of the object from a pickled state."""
352
+ self.__dict__.update(state)
353
+ self.idp_client = Session().client("cognito-idp", config=BOTO_CONFIG, region_name=REGION) # type: ignore
354
+
355
+ self.id_client = Session().client("cognito-identity", config=BOTO_CONFIG, region_name=REGION) # type: ignore
356
+
343
357
 
344
358
  class HttpxCognitoAuth(httpx.Auth):
345
359
  http_header: str = "Authorization"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otf-api
3
- Version: 0.13.2
3
+ Version: 0.14.0
4
4
  Summary: Python OrangeTheory Fitness API Client
5
5
  Author-email: Jessica Smith <j.smith.git1@gmail.com>
6
6
  License-Expression: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes