otf-api 0.13.2__py3-none-any.whl → 0.14.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.
otf_api/__init__.py CHANGED
@@ -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"]
otf_api/api/client.py CHANGED
@@ -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(
otf_api/auth/auth.py CHANGED
@@ -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
@@ -1,26 +1,26 @@
1
- otf_api/__init__.py,sha256=B8xq2bcHRV-z-pluFbo3Ow-FBAYO4jG5hq6wll9FhqE,1150
1
+ otf_api/__init__.py,sha256=gg7_JvYNdWRmAD0TtUR0XXwcfH_erUEdWRYsPfH2un0,1150
2
2
  otf_api/cache.py,sha256=m4xUBhaS0MkcZypon1jjfhJzZPRQBE5Fto4_RMReXZ0,4311
3
3
  otf_api/exceptions.py,sha256=b6ZdH1dtYyUfXSupdVGGni6d66qqhzD0SGzyuty89gM,2174
4
4
  otf_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  otf_api/api/__init__.py,sha256=YC6bwYiAN6BSE7sqbxr2l34vwSdZPMGDv3wwPIQ_S3o,51
6
6
  otf_api/api/_compat.py,sha256=vWMC6kC3tK9qoXwnU5AgbQie-dhYAkkUI-hmq_4nf7Q,3512
7
7
  otf_api/api/api.py,sha256=yda8RObOMd_lBWbqlAAUZ3dTwGhdEYsfGQJDiphp6Eo,2633
8
- otf_api/api/client.py,sha256=o533H-nYweRcosBEYmm3U-7ivkpGDF7jElM9iIhK7E8,8157
8
+ otf_api/api/client.py,sha256=wiHryvEWgdZVfjvX_3WoBCYe_OAf_kOj6yk1S4lxUcM,8734
9
9
  otf_api/api/utils.py,sha256=mNDUrz6d8b8KqTaUr5fGGGejy6bq9HHLs9LS8ibbfW4,9926
10
10
  otf_api/api/bookings/__init__.py,sha256=ocHSZXV4nnkZhjpjBX76iKHCQ21_ZL5hV4YKgUR0Wwg,62
11
11
  otf_api/api/bookings/booking_api.py,sha256=VdEX5WF3TIV5V_1n2DclBPqxhXQysNqyxJxeR6c05UM,22124
12
12
  otf_api/api/bookings/booking_client.py,sha256=qYaEomexGWP2N_WdWePMN7BR8aIKEpO71g5J0KaVfAc,4244
13
13
  otf_api/api/members/__init__.py,sha256=6mkeMiATRsNQTYQ37P7k6SWf9RZ9T5QY9-_r1sS1-vY,59
14
14
  otf_api/api/members/member_api.py,sha256=5FAPbRN_Dv3mLC1AmxcErqF1d1ypL5zVEn1u7gDbTZA,7232
15
- otf_api/api/members/member_client.py,sha256=d6v6vexmtiedw1-lXLMobbN8tTmRT-zHq7VzdJb5wDE,4528
15
+ otf_api/api/members/member_client.py,sha256=-rEGnbBrwbeZf41bIxwj0sdciMmTi90qJHfvrD_npXI,4515
16
16
  otf_api/api/studios/__init__.py,sha256=vPir509hQOJL7uJ4yBCOHgooXVnXs6N5RlWs1tN54Uk,59
17
17
  otf_api/api/studios/studio_api.py,sha256=sn1jBebe4u-wE1VkHp2W96beUOFwHdiGzVSmnGNPZjg,6813
18
- otf_api/api/studios/studio_client.py,sha256=KWc4CF-2387WDUFYpMtIUm3KyPj1JdelCn7RH9L1FBI,4707
18
+ otf_api/api/studios/studio_client.py,sha256=7KFbf3n7_zUKdmSZevYeYch9ovJ21pXIamvNMrlSyH4,4694
19
19
  otf_api/api/workouts/__init__.py,sha256=GPb2cEsAxoaiJIP8Finrk9x9vUeL9NXA9iz2eya9HYk,62
20
- otf_api/api/workouts/workout_api.py,sha256=prlqDFF4VXuzC7SRPpmD_yeZuMAp-dnfaSa52I4SM9o,13215
21
- otf_api/api/workouts/workout_client.py,sha256=MvEWbhPXywpQMSdsBSGCYBIR65TJjdqgb7T0Bc8H8D0,6762
20
+ otf_api/api/workouts/workout_api.py,sha256=6h-ErOOfGRcQ2a3NaOyvbCYfWuHCteugaqNWQwZ7UHY,13374
21
+ otf_api/api/workouts/workout_client.py,sha256=GA8jYCOp313uDMwhNUvmX5G4NMS3LarJCPkM-dJbTuM,6736
22
22
  otf_api/auth/__init__.py,sha256=uTvFTNQVvfogTN_-4D3bRSundAf2enUJ5ji6PwO0xm8,104
23
- otf_api/auth/auth.py,sha256=67-RXDla3rVm5vmlyPEOqPOF5kecJiEznVmq0gSz3M0,16448
23
+ otf_api/auth/auth.py,sha256=N7PRohWlN4TMf6xWkD3LQTPaztGYqPFKgpHYMhzfZV8,17031
24
24
  otf_api/auth/user.py,sha256=OChRG0EhZ63vEtT_Sg3NmXWmOD1vZcILuHhRXlwaG0I,2156
25
25
  otf_api/auth/utils.py,sha256=YBxqg2h59u4V1ij5kgqJDyKh0gtgOlXrSZdpAKSdelY,3954
26
26
  otf_api/models/__init__.py,sha256=P0IjxRUPIfzUI-e3VDMpipJeWr6BlypWAED2ovnZw-w,1545
@@ -52,8 +52,8 @@ otf_api/models/workouts/out_of_studio_workout_history.py,sha256=-BKp-MnIp_5-U2KW
52
52
  otf_api/models/workouts/performance_summary.py,sha256=R1p-g1L4XWWEiBYaGtX5JFvoS3Z6bzQrsPIfTQHDqyM,3464
53
53
  otf_api/models/workouts/telemetry.py,sha256=rKsmLbsOVUxUXH439zxxIEWYGTohKNemqrtMamAl5cA,3465
54
54
  otf_api/models/workouts/workout.py,sha256=_KIR9fLI4LgUlS02Q5SNauHd4aOqJI9H4uaFKf-xJOU,4580
55
- otf_api-0.13.2.dist-info/licenses/LICENSE,sha256=UaPT9ynYigC3nX8n22_rC37n-qmTRKLFaHrtUwF9ktE,1071
56
- otf_api-0.13.2.dist-info/METADATA,sha256=ABfr_86oOf234G_WSqA06txQG2igkLdAx7KaNhabQFs,2162
57
- otf_api-0.13.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
58
- otf_api-0.13.2.dist-info/top_level.txt,sha256=KAhYg1X2YG0LkTuVRhUV1I_AReNZUVNdEan7cp0pEE4,8
59
- otf_api-0.13.2.dist-info/RECORD,,
55
+ otf_api-0.14.0.dist-info/licenses/LICENSE,sha256=UaPT9ynYigC3nX8n22_rC37n-qmTRKLFaHrtUwF9ktE,1071
56
+ otf_api-0.14.0.dist-info/METADATA,sha256=Ut4IOCHQto6qCo9cd-bmUpbmw-dqHLXDss4gQU8cqSU,2162
57
+ otf_api-0.14.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
58
+ otf_api-0.14.0.dist-info/top_level.txt,sha256=KAhYg1X2YG0LkTuVRhUV1I_AReNZUVNdEan7cp0pEE4,8
59
+ otf_api-0.14.0.dist-info/RECORD,,