otf-api 0.6.0__py3-none-any.whl → 0.6.2__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
@@ -6,7 +6,7 @@ from loguru import logger
6
6
  from .api import Otf
7
7
  from .auth import OtfUser
8
8
 
9
- __version__ = "0.6.0"
9
+ __version__ = "0.6.2"
10
10
 
11
11
 
12
12
  __all__ = ["Otf", "OtfUser"]
otf_api/models/base.py CHANGED
@@ -1,141 +1,14 @@
1
- import inspect
2
- import typing
3
- from typing import ClassVar, TypeVar
1
+ from typing import ClassVar
4
2
 
5
- from box import Box
6
3
  from pydantic import BaseModel, ConfigDict
7
4
 
8
- if typing.TYPE_CHECKING:
9
- from pydantic.main import IncEx
10
5
 
11
- T = TypeVar("T", bound="OtfItemBase")
12
-
13
-
14
- class BetterDumperMixin:
15
- """A better dumper for Pydantic models that includes properties in the dumped data. Must be mixed
16
- into a Pydantic model, as it overrides the `model_dump` method.
17
-
18
- Includes support for nested models, and has an option to not include properties when dumping.
19
- """
20
-
21
- def get_properties(self) -> list[str]:
22
- """Get the properties of the model."""
23
- cls = type(self)
24
-
25
- properties: list[str] = []
26
- methods = inspect.getmembers(self, lambda f: not (inspect.isroutine(f)))
27
- for prop_name, _ in methods:
28
- if hasattr(cls, prop_name) and isinstance(getattr(cls, prop_name), property):
29
- properties.append(prop_name)
30
-
31
- return properties
32
-
33
- @typing.overload
34
- def model_dump(
35
- self,
36
- *,
37
- mode: typing.Literal["json", "python"] | str = "python",
38
- include: "IncEx" = None,
39
- exclude: "IncEx" = None,
40
- by_alias: bool = False,
41
- exclude_unset: bool = False,
42
- exclude_defaults: bool = False,
43
- exclude_none: bool = False,
44
- round_trip: bool = False,
45
- warnings: bool = True,
46
- include_properties: bool = True,
47
- ) -> Box[str, typing.Any]: ...
48
-
49
- @typing.overload
50
- def model_dump(
51
- self,
52
- *,
53
- mode: typing.Literal["json", "python"] | str = "python",
54
- include: "IncEx" = None,
55
- exclude: "IncEx" = None,
56
- by_alias: bool = False,
57
- exclude_unset: bool = False,
58
- exclude_defaults: bool = False,
59
- exclude_none: bool = False,
60
- round_trip: bool = False,
61
- warnings: bool = True,
62
- include_properties: bool = False,
63
- ) -> dict[str, typing.Any]: ...
64
-
65
- def model_dump(
66
- self,
67
- *,
68
- mode: typing.Literal["json", "python"] | str = "python",
69
- include: "IncEx" = None,
70
- exclude: "IncEx" = None,
71
- by_alias: bool = False,
72
- exclude_unset: bool = False,
73
- exclude_defaults: bool = False,
74
- exclude_none: bool = False,
75
- round_trip: bool = False,
76
- warnings: bool = True,
77
- include_properties: bool = True,
78
- ) -> dict[str, typing.Any] | Box[str, typing.Any]:
79
- """Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump
80
-
81
- Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
82
-
83
- Args:
84
- mode: The mode in which `to_python` should run.
85
- If mode is 'json', the dictionary will only contain JSON serializable types.
86
- If mode is 'python', the dictionary may contain any Python objects.
87
- include: A list of fields to include in the output.
88
- exclude: A list of fields to exclude from the output.
89
- by_alias: Whether to use the field's alias in the dictionary key if defined.
90
- exclude_unset: Whether to exclude fields that are unset or None from the output.
91
- exclude_defaults: Whether to exclude fields that are set to their default value from the output.
92
- exclude_none: Whether to exclude fields that have a value of `None` from the output.
93
- round_trip: Whether to enable serialization and deserialization round-trip support.
94
- warnings: Whether to log warnings when invalid fields are encountered.
95
- include_properties: Whether to include properties in the dumped data.
96
-
97
- Returns:
98
- A dictionary representation of the model. Will be a `Box` if `include_properties` is `True`, otherwise a
99
- regular dictionary.
100
-
101
- """
102
- dumped_data = typing.cast(BaseModel, super()).model_dump(
103
- mode=mode,
104
- include=include,
105
- exclude=exclude,
106
- by_alias=by_alias,
107
- exclude_unset=exclude_unset,
108
- exclude_defaults=exclude_defaults,
109
- exclude_none=exclude_none,
110
- round_trip=round_trip,
111
- warnings=warnings,
112
- )
113
-
114
- if not include_properties:
115
- return dumped_data
116
-
117
- properties = self.get_properties()
118
-
119
- # set properties to their values
120
- for prop_name in properties:
121
- dumped_data[prop_name] = getattr(self, prop_name)
122
-
123
- # if the property is a Pydantic model, dump it as well
124
- for k, v in dumped_data.items():
125
- if issubclass(type(getattr(self, k)), BaseModel):
126
- dumped_data[k] = getattr(self, k).model_dump()
127
- elif hasattr(v, "model_dump"):
128
- dumped_data[k] = v.model_dump()
129
-
130
- return Box(dumped_data)
131
-
132
-
133
- class OtfItemBase(BetterDumperMixin, BaseModel):
134
- model_config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True, extra="forbid")
6
+ class OtfItemBase(BaseModel):
7
+ model_config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True, extra="allow")
135
8
 
136
9
 
137
10
  class OtfListBase(BaseModel):
138
- model_config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True, extra="forbid")
11
+ model_config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True, extra="allow")
139
12
  collection_field: ClassVar[str] = "data"
140
13
 
141
14
  @property
@@ -5,6 +5,8 @@ from enum import Enum
5
5
  import pint
6
6
  from pydantic import BaseModel, ConfigDict, Field, field_validator
7
7
 
8
+ from otf_api.models.base import OtfItemBase, OtfListBase
9
+
8
10
  ureg = pint.UnitRegistry()
9
11
 
10
12
  DEFAULT_WEIGHT_DIVIDERS = [55.0, 70.0, 85.0, 100.0, 115.0, 130.0, 145.0, 160.0, 175.0, 190.0, 205.0]
@@ -98,7 +100,7 @@ def get_body_fat_percent_dividers_female(age: int) -> list[float]:
98
100
  return [0.0, 0.0, 0.0, 0.0]
99
101
 
100
102
 
101
- class LeanBodyMass(BaseModel):
103
+ class LeanBodyMass(OtfItemBase):
102
104
  model_config: ConfigDict = ConfigDict(extra="ignore")
103
105
  left_arm: float = Field(..., alias="lbmOfLeftArm")
104
106
  left_leg: float = Field(..., alias="lbmOfLeftLeg")
@@ -107,7 +109,7 @@ class LeanBodyMass(BaseModel):
107
109
  trunk: float = Field(..., alias="lbmOfTrunk")
108
110
 
109
111
 
110
- class LeanBodyMassPercent(BaseModel):
112
+ class LeanBodyMassPercent(OtfItemBase):
111
113
  model_config: ConfigDict = ConfigDict(extra="ignore")
112
114
  left_arm: float = Field(..., alias="lbmPercentOfLeftArm")
113
115
  left_leg: float = Field(..., alias="lbmPercentOfLeftLeg")
@@ -116,7 +118,7 @@ class LeanBodyMassPercent(BaseModel):
116
118
  trunk: float = Field(..., alias="lbmPercentOfTrunk")
117
119
 
118
120
 
119
- class BodyFatMass(BaseModel):
121
+ class BodyFatMass(OtfItemBase):
120
122
  model_config: ConfigDict = ConfigDict(extra="ignore")
121
123
  control: float = Field(..., alias="bfmControl")
122
124
  left_arm: float = Field(..., alias="bfmOfLeftArm")
@@ -126,7 +128,7 @@ class BodyFatMass(BaseModel):
126
128
  trunk: float = Field(..., alias="bfmOfTrunk")
127
129
 
128
130
 
129
- class BodyFatMassPercent(BaseModel):
131
+ class BodyFatMassPercent(OtfItemBase):
130
132
  model_config: ConfigDict = ConfigDict(extra="ignore")
131
133
  left_arm: float = Field(..., alias="bfmPercentOfLeftArm")
132
134
  left_leg: float = Field(..., alias="bfmPercentOfLeftLeg")
@@ -135,7 +137,7 @@ class BodyFatMassPercent(BaseModel):
135
137
  trunk: float = Field(..., alias="bfmPercentOfTrunk")
136
138
 
137
139
 
138
- class TotalBodyWeight(BaseModel):
140
+ class TotalBodyWeight(OtfItemBase):
139
141
  model_config: ConfigDict = ConfigDict(extra="ignore")
140
142
  right_arm: float = Field(..., alias="tbwOfRightArm")
141
143
  left_arm: float = Field(..., alias="tbwOfLeftArm")
@@ -144,7 +146,7 @@ class TotalBodyWeight(BaseModel):
144
146
  left_leg: float = Field(..., alias="tbwOfLeftLeg")
145
147
 
146
148
 
147
- class IntraCellularWater(BaseModel):
149
+ class IntraCellularWater(OtfItemBase):
148
150
  model_config: ConfigDict = ConfigDict(extra="ignore")
149
151
  right_arm: float = Field(..., alias="icwOfRightArm")
150
152
  left_arm: float = Field(..., alias="icwOfLeftArm")
@@ -153,7 +155,7 @@ class IntraCellularWater(BaseModel):
153
155
  left_leg: float = Field(..., alias="icwOfLeftLeg")
154
156
 
155
157
 
156
- class ExtraCellularWater(BaseModel):
158
+ class ExtraCellularWater(OtfItemBase):
157
159
  model_config: ConfigDict = ConfigDict(extra="ignore")
158
160
  right_arm: float = Field(..., alias="ecwOfRightArm")
159
161
  left_arm: float = Field(..., alias="ecwOfLeftArm")
@@ -162,7 +164,7 @@ class ExtraCellularWater(BaseModel):
162
164
  left_leg: float = Field(..., alias="ecwOfLeftLeg")
163
165
 
164
166
 
165
- class ExtraCellularWaterOverTotalBodyWater(BaseModel):
167
+ class ExtraCellularWaterOverTotalBodyWater(OtfItemBase):
166
168
  model_config: ConfigDict = ConfigDict(extra="ignore")
167
169
  right_arm: float = Field(..., alias="ecwOverTBWOfRightArm")
168
170
  left_arm: float = Field(..., alias="ecwOverTBWOfLeftArm")
@@ -171,7 +173,7 @@ class ExtraCellularWaterOverTotalBodyWater(BaseModel):
171
173
  left_leg: float = Field(..., alias="ecwOverTBWOfLeftLeg")
172
174
 
173
175
 
174
- class BodyCompositionData(BaseModel):
176
+ class BodyCompositionData(OtfItemBase):
175
177
  member_uuid: str = Field(..., alias="memberUUId")
176
178
  member_id: str = Field(..., alias="memberId")
177
179
  scan_result_uuid: str = Field(..., alias="scanResultUUId")
@@ -300,5 +302,5 @@ class BodyCompositionData(BaseModel):
300
302
  )
301
303
 
302
304
 
303
- class BodyCompositionList(BaseModel):
305
+ class BodyCompositionList(OtfListBase):
304
306
  data: list[BodyCompositionData]
@@ -1,19 +1,21 @@
1
1
  from datetime import datetime
2
2
  from typing import Any
3
3
 
4
- from pydantic import BaseModel, Field
4
+ from pydantic import Field
5
5
 
6
+ from otf_api.models.base import OtfItemBase
6
7
 
7
- class MemberProfile(BaseModel):
8
+
9
+ class MemberProfile(OtfItemBase):
8
10
  is_latest_agreement_signed: bool = Field(..., alias="isLatestAgreementSigned")
9
11
 
10
12
 
11
- class StudioProfiles(BaseModel):
13
+ class StudioProfiles(OtfItemBase):
12
14
  studio_id: int = Field(..., alias="studioId")
13
15
  is_franchise_agreement_enabled: int = Field(..., alias="isFranchiseAgreementEnabled")
14
16
 
15
17
 
16
- class HomeStudio(BaseModel):
18
+ class HomeStudio(OtfItemBase):
17
19
  studio_uuid: str = Field(..., alias="studioUUId")
18
20
  studio_name: str = Field(..., alias="studioName")
19
21
  description: str
@@ -28,7 +30,7 @@ class HomeStudio(BaseModel):
28
30
  studio_profiles: StudioProfiles = Field(..., alias="studioProfiles")
29
31
 
30
32
 
31
- class MemberService(BaseModel):
33
+ class MemberService(OtfItemBase):
32
34
  member_service_id: int = Field(..., alias="memberServiceId")
33
35
  member_service_uuid: str = Field(..., alias="memberServiceUUId")
34
36
  service_name: str = Field(..., alias="serviceName")
@@ -49,13 +51,13 @@ class MemberService(BaseModel):
49
51
  is_deleted: bool = Field(..., alias="isDeleted")
50
52
 
51
53
 
52
- class ServiceItem(BaseModel):
54
+ class ServiceItem(OtfItemBase):
53
55
  service_id: int = Field(..., alias="serviceId")
54
56
  name: str
55
57
  member_service: MemberService = Field(..., alias="MemberService")
56
58
 
57
59
 
58
- class Member(BaseModel):
60
+ class Member(OtfItemBase):
59
61
  member_id: int = Field(..., alias="memberId")
60
62
  member_uuid: str = Field(..., alias="memberUUId")
61
63
  cognito_id: str = Field(..., alias="cognitoId")
@@ -107,7 +109,7 @@ class Member(BaseModel):
107
109
  notes: str
108
110
 
109
111
 
110
- class Studio(BaseModel):
112
+ class Studio(OtfItemBase):
111
113
  studio_uuid: str = Field(..., alias="studioUUId")
112
114
  studio_name: str = Field(..., alias="studioName")
113
115
  description: str
@@ -121,12 +123,12 @@ class Studio(BaseModel):
121
123
  cr_waitlist_flag_last_updated: datetime = Field(..., alias="crWaitlistFlagLastUpdated")
122
124
 
123
125
 
124
- class Location(BaseModel):
126
+ class Location(OtfItemBase):
125
127
  location_id: int = Field(..., alias="locationId")
126
128
  location_uuid: str = Field(..., alias="locationUUId")
127
129
 
128
130
 
129
- class Coach(BaseModel):
131
+ class Coach(OtfItemBase):
130
132
  coach_uuid: str = Field(..., alias="coachUUId")
131
133
  first_name: str = Field(..., alias="firstName")
132
134
  last_name: str = Field(..., alias="lastName")
@@ -134,7 +136,7 @@ class Coach(BaseModel):
134
136
  name: str
135
137
 
136
138
 
137
- class Class(BaseModel):
139
+ class Class(OtfItemBase):
138
140
  class_id: int = Field(..., alias="classId")
139
141
  class_uuid: str = Field(..., alias="classUUId")
140
142
  mbo_studio_id: int = Field(..., alias="mboStudioId")
@@ -175,16 +177,16 @@ class Class(BaseModel):
175
177
  attributes: dict[str, Any]
176
178
 
177
179
 
178
- class Class1(BaseModel):
180
+ class Class1(OtfItemBase):
179
181
  mbo_studio_id: int = Field(..., alias="mboStudioId")
180
182
  studio_uuid: str = Field(..., alias="studioUUId")
181
183
 
182
184
 
183
- class CustomData(BaseModel):
185
+ class CustomData(OtfItemBase):
184
186
  otf_class: Class1 = Field(..., alias="class")
185
187
 
186
188
 
187
- class SavedBooking(BaseModel):
189
+ class SavedBooking(OtfItemBase):
188
190
  class_booking_id: int = Field(..., alias="classBookingId")
189
191
  class_booking_uuid: str = Field(..., alias="classBookingUUId")
190
192
  studio_id: int = Field(..., alias="studioId")
@@ -211,19 +213,19 @@ class SavedBooking(BaseModel):
211
213
  attributes: dict[str, Any]
212
214
 
213
215
 
214
- class FieldModel(BaseModel):
216
+ class FieldModel(OtfItemBase):
215
217
  xsi_nil: str = Field(..., alias="xsiNil")
216
218
 
217
219
 
218
- class FacilitySquareFeet(BaseModel):
220
+ class FacilitySquareFeet(OtfItemBase):
219
221
  field_: FieldModel
220
222
 
221
223
 
222
- class TreatmentRooms(BaseModel):
224
+ class TreatmentRooms(OtfItemBase):
223
225
  field_: FieldModel
224
226
 
225
227
 
226
- class Location1(BaseModel):
228
+ class Location1(OtfItemBase):
227
229
  site_id: str | Any = Field(..., alias="siteId")
228
230
  business_description: str | Any = Field(..., alias="businessDescription")
229
231
  additional_image_ur_ls: str | Any = Field(..., alias="additionalImageUrLs")
@@ -247,38 +249,38 @@ class Location1(BaseModel):
247
249
  longitude: str
248
250
 
249
251
 
250
- class MaxCapacity(BaseModel):
252
+ class MaxCapacity(OtfItemBase):
251
253
  field_: FieldModel | Any
252
254
 
253
255
 
254
- class WebCapacity(BaseModel):
256
+ class WebCapacity(OtfItemBase):
255
257
  field_: FieldModel | Any
256
258
 
257
259
 
258
- class TotalBookedWaitlist(BaseModel):
260
+ class TotalBookedWaitlist(OtfItemBase):
259
261
  field_: FieldModel | Any
260
262
 
261
263
 
262
- class WebBooked(BaseModel):
264
+ class WebBooked(OtfItemBase):
263
265
  field_: FieldModel | Any
264
266
 
265
267
 
266
- class SemesterId(BaseModel):
268
+ class SemesterId(OtfItemBase):
267
269
  field_: FieldModel | Any
268
270
 
269
271
 
270
- class Program(BaseModel):
272
+ class Program(OtfItemBase):
271
273
  id: str
272
274
  name: str
273
275
  schedule_type: str = Field(..., alias="scheduleType")
274
276
  cancel_offset: str = Field(..., alias="cancelOffset")
275
277
 
276
278
 
277
- class DefaultTimeLength(BaseModel):
279
+ class DefaultTimeLength(OtfItemBase):
278
280
  field_: FieldModel
279
281
 
280
282
 
281
- class SessionType(BaseModel):
283
+ class SessionType(OtfItemBase):
282
284
  default_time_length: DefaultTimeLength = Field(..., alias="defaultTimeLength")
283
285
  program_id: str = Field(..., alias="programId")
284
286
  num_deducted: str = Field(..., alias="numDeducted")
@@ -289,7 +291,7 @@ class SessionType(BaseModel):
289
291
  available_for_add_on: str = Field(..., alias="availableForAddOn")
290
292
 
291
293
 
292
- class ClassDescription(BaseModel):
294
+ class ClassDescription(OtfItemBase):
293
295
  id: str
294
296
  name: str
295
297
  description: str
@@ -300,7 +302,7 @@ class ClassDescription(BaseModel):
300
302
  session_type: SessionType = Field(..., alias="sessionType")
301
303
 
302
304
 
303
- class Staff(BaseModel):
305
+ class Staff(OtfItemBase):
304
306
  email: str
305
307
  mobile_phone: str = Field(..., alias="mobilePhone")
306
308
  state: str
@@ -318,25 +320,25 @@ class Staff(BaseModel):
318
320
  is_male: str = Field(..., alias="isMale")
319
321
 
320
322
 
321
- class AgreementDate(BaseModel):
323
+ class AgreementDate(OtfItemBase):
322
324
  field_: FieldModel
323
325
 
324
326
 
325
- class ReleasedBy(BaseModel):
327
+ class ReleasedBy(OtfItemBase):
326
328
  field_: FieldModel
327
329
 
328
330
 
329
- class Liability(BaseModel):
331
+ class Liability(OtfItemBase):
330
332
  is_released: str = Field(..., alias="isReleased")
331
333
  agreement_date: AgreementDate = Field(..., alias="agreementDate")
332
334
  released_by: ReleasedBy = Field(..., alias="releasedBy")
333
335
 
334
336
 
335
- class FirstAppointmentDate(BaseModel):
337
+ class FirstAppointmentDate(OtfItemBase):
336
338
  field_: FieldModel
337
339
 
338
340
 
339
- class Client(BaseModel):
341
+ class Client(OtfItemBase):
340
342
  notes: str
341
343
  mobile_provider: str = Field(..., alias="mobileProvider")
342
344
  appointment_gender_preference: str = Field(..., alias="appointmentGenderPreference")
@@ -369,7 +371,7 @@ class Client(BaseModel):
369
371
  member_uuid: str = Field(..., alias="memberUUId")
370
372
 
371
373
 
372
- class MboClass(BaseModel):
374
+ class MboClass(OtfItemBase):
373
375
  class_schedule_id: str = Field(..., alias="classScheduleId")
374
376
  location: Location1
375
377
  max_capacity: MaxCapacity = Field(..., alias="maxCapacity")
@@ -394,12 +396,12 @@ class MboClass(BaseModel):
394
396
  client: Client
395
397
 
396
398
 
397
- class MboResponseItem(BaseModel):
399
+ class MboResponseItem(OtfItemBase):
398
400
  class_booking_uuid: str | Any = Field(..., alias="classBookingUUId")
399
401
  action: str | Any
400
402
  otf_class: MboClass | Any = Field(..., alias="class")
401
403
 
402
404
 
403
- class BookClass(BaseModel):
405
+ class BookClass(OtfItemBase):
404
406
  saved_bookings: list[SavedBooking] = Field(..., alias="savedBookings")
405
407
  mbo_response: list[MboResponseItem] = Field(..., alias="mboResponse")
@@ -1,9 +1,11 @@
1
1
  from datetime import datetime
2
2
 
3
- from pydantic import BaseModel, Field
3
+ from pydantic import Field
4
4
 
5
+ from otf_api.models.base import OtfItemBase
5
6
 
6
- class Studio(BaseModel):
7
+
8
+ class Studio(OtfItemBase):
7
9
  studio_uuid: str = Field(..., alias="studioUUId")
8
10
  studio_name: str = Field(..., alias="studioName")
9
11
  description: str
@@ -17,7 +19,7 @@ class Studio(BaseModel):
17
19
  cr_waitlist_flag_last_updated: datetime = Field(..., alias="crWaitlistFlagLastUpdated")
18
20
 
19
21
 
20
- class Coach(BaseModel):
22
+ class Coach(OtfItemBase):
21
23
  coach_uuid: str = Field(..., alias="coachUUId")
22
24
  name: str
23
25
  first_name: str = Field(..., alias="firstName")
@@ -25,7 +27,7 @@ class Coach(BaseModel):
25
27
  mbo_coach_id: int = Field(..., alias="mboCoachId")
26
28
 
27
29
 
28
- class Class(BaseModel):
30
+ class Class(OtfItemBase):
29
31
  class_uuid: str = Field(..., alias="classUUId")
30
32
  name: str
31
33
  description: str
@@ -40,7 +42,7 @@ class Class(BaseModel):
40
42
  coach: Coach
41
43
 
42
44
 
43
- class HomeStudio(BaseModel):
45
+ class HomeStudio(OtfItemBase):
44
46
  studio_uuid: str = Field(..., alias="studioUUId")
45
47
  studio_name: str = Field(..., alias="studioName")
46
48
  description: str
@@ -54,7 +56,7 @@ class HomeStudio(BaseModel):
54
56
  cr_waitlist_flag_last_updated: datetime = Field(..., alias="crWaitlistFlagLastUpdated")
55
57
 
56
58
 
57
- class Member(BaseModel):
59
+ class Member(OtfItemBase):
58
60
  member_id: int = Field(..., alias="memberId")
59
61
  member_uuid: str = Field(..., alias="memberUUId")
60
62
  email: str
@@ -67,7 +69,7 @@ class Member(BaseModel):
67
69
  home_studio: HomeStudio = Field(..., alias="homeStudio")
68
70
 
69
71
 
70
- class CancelBooking(BaseModel):
72
+ class CancelBooking(OtfItemBase):
71
73
  class_booking_id: int = Field(..., alias="classBookingId")
72
74
  class_booking_uuid: str = Field(..., alias="classBookingUUId")
73
75
  studio_id: int = Field(..., alias="studioId")
@@ -1,9 +1,9 @@
1
1
  from datetime import datetime
2
- from typing import Any
2
+ from typing import Any, ClassVar
3
3
 
4
4
  from pydantic import Field
5
5
 
6
- from otf_api.models.base import OtfItemBase
6
+ from otf_api.models.base import OtfItemBase, OtfListBase
7
7
 
8
8
 
9
9
  class MetricEntry(OtfItemBase):
@@ -64,5 +64,6 @@ class ChallengeTrackerDetail(OtfItemBase):
64
64
  challenge_histories: list[ChallengeHistory] = Field(..., alias="ChallengeHistories")
65
65
 
66
66
 
67
- class ChallengeTrackerDetailList(OtfItemBase):
67
+ class ChallengeTrackerDetailList(OtfListBase):
68
+ collection_field: ClassVar[str] = "details"
68
69
  details: list[ChallengeTrackerDetail]
@@ -1,8 +1,9 @@
1
1
  from datetime import datetime
2
+ from typing import ClassVar
2
3
 
3
4
  from pydantic import Field
4
5
 
5
- from otf_api.models.base import OtfItemBase
6
+ from otf_api.models.base import OtfItemBase, OtfListBase
6
7
 
7
8
 
8
9
  class Location(OtfItemBase):
@@ -94,7 +95,8 @@ class FavoriteStudio(OtfItemBase):
94
95
  studio_location: StudioLocation = Field(..., alias="studioLocation")
95
96
 
96
97
 
97
- class FavoriteStudioList(OtfItemBase):
98
+ class FavoriteStudioList(OtfListBase):
99
+ collection_field: ClassVar[str] = "studios"
98
100
  studios: list[FavoriteStudio]
99
101
 
100
102
  @property
@@ -1,6 +1,8 @@
1
1
  from enum import Enum
2
2
 
3
- from pydantic import BaseModel, Field
3
+ from pydantic import Field
4
+
5
+ from otf_api.models.base import OtfItemBase
4
6
 
5
7
 
6
8
  class StatsTime(str, Enum):
@@ -19,20 +21,20 @@ class StatsType(str, Enum):
19
21
  All = "allStats"
20
22
 
21
23
 
22
- class OutStudioMixin(BaseModel):
24
+ class OutStudioMixin(OtfItemBase):
23
25
  walking_distance: float = Field(..., alias="walkingDistance")
24
26
  running_distance: float = Field(..., alias="runningDistance")
25
27
  cycling_distance: float = Field(..., alias="cyclingDistance")
26
28
 
27
29
 
28
- class InStudioMixin(BaseModel):
30
+ class InStudioMixin(OtfItemBase):
29
31
  treadmill_distance: float = Field(..., alias="treadmillDistance")
30
32
  treadmill_elevation_gained: float = Field(..., alias="treadmillElevationGained")
31
33
  rower_distance: float = Field(..., alias="rowerDistance")
32
34
  rower_watt: float = Field(..., alias="rowerWatt")
33
35
 
34
36
 
35
- class BaseStatsData(BaseModel):
37
+ class BaseStatsData(OtfItemBase):
36
38
  calories: float
37
39
  splat_point: float = Field(..., alias="splatPoint")
38
40
  total_black_zone: float = Field(..., alias="totalBlackZone")
@@ -56,7 +58,7 @@ class AllStatsData(OutStudioMixin, InStudioMixin, BaseStatsData):
56
58
  pass
57
59
 
58
60
 
59
- class OutStudioTimeStats(BaseModel):
61
+ class OutStudioTimeStats(OtfItemBase):
60
62
  last_year: OutStudioStatsData = Field(..., alias="lastYear")
61
63
  this_year: OutStudioStatsData = Field(..., alias="thisYear")
62
64
  last_month: OutStudioStatsData = Field(..., alias="lastMonth")
@@ -66,7 +68,7 @@ class OutStudioTimeStats(BaseModel):
66
68
  all_time: OutStudioStatsData = Field(..., alias="allTime")
67
69
 
68
70
 
69
- class InStudioTimeStats(BaseModel):
71
+ class InStudioTimeStats(OtfItemBase):
70
72
  last_year: InStudioStatsData = Field(..., alias="lastYear")
71
73
  this_year: InStudioStatsData = Field(..., alias="thisYear")
72
74
  last_month: InStudioStatsData = Field(..., alias="lastMonth")
@@ -76,7 +78,7 @@ class InStudioTimeStats(BaseModel):
76
78
  all_time: InStudioStatsData = Field(..., alias="allTime")
77
79
 
78
80
 
79
- class AllStatsTimeStats(BaseModel):
81
+ class AllStatsTimeStats(OtfItemBase):
80
82
  last_year: AllStatsData = Field(..., alias="lastYear")
81
83
  this_year: AllStatsData = Field(..., alias="thisYear")
82
84
  last_month: AllStatsData = Field(..., alias="lastMonth")
@@ -86,7 +88,7 @@ class AllStatsTimeStats(BaseModel):
86
88
  all_time: AllStatsData = Field(..., alias="allTime")
87
89
 
88
90
 
89
- class StatsResponse(BaseModel):
91
+ class StatsResponse(OtfItemBase):
90
92
  all_stats: AllStatsTimeStats = Field(..., alias="allStats")
91
93
  in_studio: InStudioTimeStats = Field(..., alias="inStudio")
92
94
  out_studio: OutStudioTimeStats = Field(..., alias="outStudio")
@@ -101,7 +101,7 @@ class MemberDetail(OtfItemBase):
101
101
  state: None
102
102
  postal_code: None = Field(..., alias="postalCode")
103
103
  phone_number: str = Field(..., alias="phoneNumber")
104
- home_phone: str = Field(..., alias="homePhone")
104
+ home_phone: str | None = Field(..., alias="homePhone")
105
105
  work_phone: None = Field(..., alias="workPhone")
106
106
  phone_type: None = Field(..., alias="phoneType")
107
107
  birth_day: date | str = Field(..., alias="birthDay")
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
 
3
3
  from pydantic import Field
4
4
 
5
- from otf_api.models.base import OtfItemBase
5
+ from otf_api.models.base import OtfItemBase, OtfListBase
6
6
 
7
7
 
8
8
  class Location(OtfItemBase):
@@ -131,5 +131,5 @@ class MemberPurchase(OtfItemBase):
131
131
  studio: Studio
132
132
 
133
133
 
134
- class MemberPurchaseList(OtfItemBase):
134
+ class MemberPurchaseList(OtfListBase):
135
135
  data: list[MemberPurchase]
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
 
3
3
  from pydantic import Field
4
4
 
5
- from otf_api.models.base import OtfItemBase
5
+ from otf_api.models.base import OtfItemBase, OtfListBase
6
6
 
7
7
 
8
8
  class WorkoutType(OtfItemBase):
@@ -37,5 +37,5 @@ class OutOfStudioWorkoutHistory(OtfItemBase):
37
37
  max_heartrate: int = Field(..., alias="maxHeartrate")
38
38
 
39
39
 
40
- class OutOfStudioWorkoutHistoryList(OtfItemBase):
40
+ class OutOfStudioWorkoutHistoryList(OtfListBase):
41
41
  data: list[OutOfStudioWorkoutHistory]
@@ -1,7 +1,9 @@
1
- from pydantic import BaseModel, Field
1
+ from pydantic import Field
2
2
 
3
+ from otf_api.models.base import OtfItemBase
3
4
 
4
- class ZoneTimeMinutes(BaseModel):
5
+
6
+ class ZoneTimeMinutes(OtfItemBase):
5
7
  gray: int
6
8
  blue: int
7
9
  green: int
@@ -9,7 +11,7 @@ class ZoneTimeMinutes(BaseModel):
9
11
  red: int
10
12
 
11
13
 
12
- class HeartRate(BaseModel):
14
+ class HeartRate(OtfItemBase):
13
15
  max_hr: int
14
16
  peak_hr: int
15
17
  peak_hr_percent: int
@@ -17,19 +19,19 @@ class HeartRate(BaseModel):
17
19
  avg_hr_percent: int
18
20
 
19
21
 
20
- class PerformanceMetricFloat(BaseModel):
22
+ class PerformanceMetricFloat(OtfItemBase):
21
23
  display_value: float
22
24
  display_unit: str
23
25
  metric_value: float
24
26
 
25
27
 
26
- class PerformanceMetricString(BaseModel):
28
+ class PerformanceMetricString(OtfItemBase):
27
29
  display_value: str
28
30
  display_unit: str
29
31
  metric_value: str
30
32
 
31
33
 
32
- class BaseEquipment(BaseModel):
34
+ class BaseEquipment(OtfItemBase):
33
35
  avg_pace: PerformanceMetricString
34
36
  avg_speed: PerformanceMetricFloat
35
37
  max_pace: PerformanceMetricString
@@ -50,12 +52,12 @@ class Rower(BaseEquipment):
50
52
  max_cadence: PerformanceMetricFloat
51
53
 
52
54
 
53
- class EquipmentData(BaseModel):
55
+ class EquipmentData(OtfItemBase):
54
56
  treadmill: Treadmill
55
57
  rower: Rower
56
58
 
57
59
 
58
- class Details(BaseModel):
60
+ class Details(OtfItemBase):
59
61
  calories_burned: int
60
62
  splat_points: int
61
63
  step_count: int
@@ -65,12 +67,12 @@ class Details(BaseModel):
65
67
  equipment_data: EquipmentData
66
68
 
67
69
 
68
- class Class(BaseModel):
70
+ class Class(OtfItemBase):
69
71
  starts_at_local: str
70
72
  name: str
71
73
 
72
74
 
73
- class PerformanceSummaryDetail(BaseModel):
75
+ class PerformanceSummaryDetail(OtfItemBase):
74
76
  id: str
75
77
  details: Details
76
78
  ratable: bool
@@ -1,6 +1,8 @@
1
+ from typing import ClassVar
2
+
1
3
  from pydantic import Field
2
4
 
3
- from otf_api.models.base import OtfItemBase
5
+ from otf_api.models.base import OtfItemBase, OtfListBase
4
6
 
5
7
 
6
8
  class ZoneTimeMinutes(OtfItemBase):
@@ -34,6 +36,7 @@ class Class(OtfItemBase):
34
36
  ot_base_class_uuid: str | None = None
35
37
  starts_at_local: str
36
38
  name: str | None = None
39
+ type: str | None = None
37
40
  coach: Coach
38
41
  studio: Studio
39
42
 
@@ -63,5 +66,6 @@ class PerformanceSummaryEntry(OtfItemBase):
63
66
  ratings: Ratings | None = None
64
67
 
65
68
 
66
- class PerformanceSummaryList(OtfItemBase):
69
+ class PerformanceSummaryList(OtfListBase):
70
+ collection_field: ClassVar[str] = "summaries"
67
71
  summaries: list[PerformanceSummaryEntry]
@@ -1,8 +1,9 @@
1
1
  from datetime import datetime
2
+ from typing import ClassVar
2
3
 
3
4
  from pydantic import Field
4
5
 
5
- from otf_api.models.base import OtfItemBase
6
+ from otf_api.models.base import OtfItemBase, OtfListBase
6
7
 
7
8
 
8
9
  class Country(OtfItemBase):
@@ -107,5 +108,6 @@ class Pagination(OtfItemBase):
107
108
  total_pages: int = Field(..., alias="totalPages")
108
109
 
109
110
 
110
- class StudioDetailList(OtfItemBase):
111
+ class StudioDetailList(OtfListBase):
112
+ collection_field: ClassVar[str] = "studios"
111
113
  studios: list[StudioDetail]
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
 
3
3
  from pydantic import Field
4
4
 
5
- from otf_api.models.base import OtfItemBase
5
+ from otf_api.models.base import OtfItemBase, OtfListBase
6
6
 
7
7
 
8
8
  class Currency(OtfItemBase):
@@ -53,5 +53,5 @@ class StudioService(OtfItemBase):
53
53
  studio: Studio
54
54
 
55
55
 
56
- class StudioServiceList(OtfItemBase):
56
+ class StudioServiceList(OtfListBase):
57
57
  data: list[StudioService]
@@ -25,6 +25,14 @@ class TreadData(OtfItemBase):
25
25
  agg_tread_distance: int = Field(..., alias="aggTreadDistance")
26
26
 
27
27
 
28
+ class RowData(OtfItemBase):
29
+ row_speed: float = Field(..., alias="rowSpeed")
30
+ row_pps: float = Field(..., alias="rowPps")
31
+ row_Spm: float = Field(..., alias="rowSpm")
32
+ agg_row_distance: int = Field(..., alias="aggRowDistance")
33
+ row_pace: int = Field(..., alias="rowPace")
34
+
35
+
28
36
  class TelemetryItem(OtfItemBase):
29
37
  relative_timestamp: int = Field(..., alias="relativeTimestamp")
30
38
  hr: int
@@ -36,6 +44,7 @@ class TelemetryItem(OtfItemBase):
36
44
  description="The timestamp of the telemetry item, calculated from the class start time and relative timestamp.",
37
45
  )
38
46
  tread_data: TreadData | None = Field(None, alias="treadData")
47
+ row_data: RowData | None = Field(None, alias="rowData")
39
48
 
40
49
 
41
50
  class Telemetry(OtfItemBase):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: otf-api
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: Python OrangeTheory Fitness API Client
5
5
  License: MIT
6
6
  Author: Jessica Smith
@@ -18,7 +18,7 @@ Classifier: Topic :: Internet :: WWW/HTTP
18
18
  Classifier: Topic :: Software Development :: Libraries
19
19
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
20
20
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
- Requires-Dist: aiohttp (==3.8.*)
21
+ Requires-Dist: aiohttp (==3.10.*)
22
22
  Requires-Dist: humanize (>=4.9.0,<5.0.0)
23
23
  Requires-Dist: inflection (==0.5.*)
24
24
  Requires-Dist: loguru (==0.7.2)
@@ -26,7 +26,6 @@ Requires-Dist: pendulum (>=3.0.0,<4.0.0)
26
26
  Requires-Dist: pint (==0.24.*)
27
27
  Requires-Dist: pycognito (==2024.5.1)
28
28
  Requires-Dist: pydantic (==2.7.3)
29
- Requires-Dist: python-box (>=7.2.0,<8.0.0)
30
29
  Project-URL: Documentation, https://otf-api.readthedocs.io/en/stable/
31
30
  Description-Content-Type: text/markdown
32
31
 
@@ -0,0 +1,35 @@
1
+ otf_api/__init__.py,sha256=z4nKmmBKrL1BuMh3E_emGRQUPyotvOREIXf5RTnHzU4,237
2
+ otf_api/api.py,sha256=QlRHXDwzbB97aCfacb_9FVox-5AuPLMweRQAZkz-EE0,34885
3
+ otf_api/auth.py,sha256=XzwLSi5M3DyG7bE7DmWAzXF2y6fkJyAZxHUA9lpW25M,10231
4
+ otf_api/models/__init__.py,sha256=3GHBOirQA4yu06cgD9pYmCU8u8_F9nxNHeSXDuFpe5A,1428
5
+ otf_api/models/base.py,sha256=gsMf3XGKqc68CRC-Mp3ARdnXKCpbWWGttZ8pfUwuEu0,664
6
+ otf_api/models/responses/__init__.py,sha256=xxwz-JwRd0upmI0VNdvInbAm2FOQvPo3pS0SEhWfkI4,1947
7
+ otf_api/models/responses/body_composition_list.py,sha256=N1amk4sWzgiBFmnCUUlMGSwOh_XGucqW_8MvE0XsRKY,12271
8
+ otf_api/models/responses/book_class.py,sha256=N3KydWoLOYpkG87O4qMqaBH27oHm3PwCzC60jCXUfHo,15517
9
+ otf_api/models/responses/bookings.py,sha256=XwW6blHpw9imtXRnQJYahUgfrAeOcGZqfYE-oJZ8510,8467
10
+ otf_api/models/responses/cancel_booking.py,sha256=nrvNwhlSw3tbd4qw0Jbgf0-OTjW1Qjg_ynNvC8fWPJQ,3905
11
+ otf_api/models/responses/challenge_tracker_content.py,sha256=KKpSWyyg3viN0vf1Sg2zTMlMZExLe3I6wowmUPWvRCA,1423
12
+ otf_api/models/responses/challenge_tracker_detail.py,sha256=2tHJTN2Mu8WenanuGa-P4Gijd7qbwI-jQlwPNqfhv2Q,3119
13
+ otf_api/models/responses/classes.py,sha256=VxesbFyfRhohwkjiclqTtMPl8bNc5PJajveTHtDBQ2A,4731
14
+ otf_api/models/responses/enums.py,sha256=Au8XhD-4T8ljiueUykFDc6Qz7kOoTlJ_kiDEx7nLVLM,1191
15
+ otf_api/models/responses/favorite_studios.py,sha256=Ho6K_qhkp_MyS8xGiYBp3DeBdcL7xQh6_ZpaKW8QwTY,5071
16
+ otf_api/models/responses/latest_agreement.py,sha256=aE8hbWE4Pgguw4Itah7a1SqwOLpJ6t9oODFwLQ8Wzo0,774
17
+ otf_api/models/responses/lifetime_stats.py,sha256=n8pZOwvc2boGa98oAde4coJNjmv7V4Ekt3olTj28BUk,3387
18
+ otf_api/models/responses/member_detail.py,sha256=qgP_gaiIi6Jr5SI7RSrj8l9p6aCbVK0fJX2LgI5Gazk,6031
19
+ otf_api/models/responses/member_membership.py,sha256=_z301T9DrdQW9vIgnx_LeZmkRhvMVhkxrn_v6DDfCUk,995
20
+ otf_api/models/responses/member_purchases.py,sha256=ddKC8NFVwksNMSJWco-Ekiy7SmqFGkU8nmWV_5Ur0pA,6098
21
+ otf_api/models/responses/out_of_studio_workout_history.py,sha256=Nl2KGgErkI0rMpIYD8xisFZO_vp_Ffgflx2putIKebU,1722
22
+ otf_api/models/responses/performance_summary_detail.py,sha256=U7GbVet_klwv7Joc8DiBJw4tjb3OmjoT19KGxorrNYo,1637
23
+ otf_api/models/responses/performance_summary_list.py,sha256=JDJoQEYx9llg43YjZc7AeMatUNJ6Ah40MjoVZt0-dkQ,1354
24
+ otf_api/models/responses/studio_detail.py,sha256=-ZCTCJ3MovI4ChHspvE2pG4OblvuZR_wAfpg5GNBa7U,5096
25
+ otf_api/models/responses/studio_services.py,sha256=cnnSljjOLauWAdvbf3ujKfXkrCvBsQGCXoBTARhmIqQ,1849
26
+ otf_api/models/responses/telemetry.py,sha256=MTI9fV9LniWU73xRfV_ZcdQeaeDLuaYMcQgL239lEAI,2012
27
+ otf_api/models/responses/telemetry_hr_history.py,sha256=vDcLb4wTHVBw8O0mGblUujHfJegkflOCWW-bnTXNCI0,763
28
+ otf_api/models/responses/telemetry_max_hr.py,sha256=xKxH0fIlOqFyZv8UW98XsxF-GMoIs9gnCTAbu88ZQtg,266
29
+ otf_api/models/responses/total_classes.py,sha256=WrKkWbq0eK8J0RC4qhZ5kmXnv_ZTDbyzsoRm7XKGlss,288
30
+ otf_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ otf_api-0.6.2.dist-info/AUTHORS.md,sha256=FcNWMxpe8KDuTq4Qau0SUXsabQwGs9TGnMp1WkXRnj8,123
32
+ otf_api-0.6.2.dist-info/LICENSE,sha256=UaPT9ynYigC3nX8n22_rC37n-qmTRKLFaHrtUwF9ktE,1071
33
+ otf_api-0.6.2.dist-info/METADATA,sha256=0tZaD7tUe0X0oziRVennPiFXE1NhoLHXYZOeWXGhvGI,1989
34
+ otf_api-0.6.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
35
+ otf_api-0.6.2.dist-info/RECORD,,
@@ -1,35 +0,0 @@
1
- otf_api/__init__.py,sha256=eRrcOgzcFV7KIhf6KwQ5AnvOaGfAam3AKbP01hAFOys,237
2
- otf_api/api.py,sha256=QlRHXDwzbB97aCfacb_9FVox-5AuPLMweRQAZkz-EE0,34885
3
- otf_api/auth.py,sha256=XzwLSi5M3DyG7bE7DmWAzXF2y6fkJyAZxHUA9lpW25M,10231
4
- otf_api/models/__init__.py,sha256=3GHBOirQA4yu06cgD9pYmCU8u8_F9nxNHeSXDuFpe5A,1428
5
- otf_api/models/base.py,sha256=FrYzMVA4-EWhaKwzem8bEAzRu_jK-RTCkDj5ihTSkZM,5442
6
- otf_api/models/responses/__init__.py,sha256=xxwz-JwRd0upmI0VNdvInbAm2FOQvPo3pS0SEhWfkI4,1947
7
- otf_api/models/responses/body_composition_list.py,sha256=RTC5bQpmMDUKqFl0nGFExdDxfnbOAGoBLWunjpOym80,12193
8
- otf_api/models/responses/book_class.py,sha256=bWURKEjLZWPzwu3HNP2zUmHWo7q7h6_z43a9KTST0Ec,15413
9
- otf_api/models/responses/bookings.py,sha256=XwW6blHpw9imtXRnQJYahUgfrAeOcGZqfYE-oJZ8510,8467
10
- otf_api/models/responses/cancel_booking.py,sha256=dmC5OP97Dy4qYT0l1KHYIitqSCo6M6Yqa0QztjgG_xQ,3859
11
- otf_api/models/responses/challenge_tracker_content.py,sha256=KKpSWyyg3viN0vf1Sg2zTMlMZExLe3I6wowmUPWvRCA,1423
12
- otf_api/models/responses/challenge_tracker_detail.py,sha256=o0y_ETfHmR1QhoOmvd83P6lfMZUPIwPlnS1V_po0dkE,3048
13
- otf_api/models/responses/classes.py,sha256=VxesbFyfRhohwkjiclqTtMPl8bNc5PJajveTHtDBQ2A,4731
14
- otf_api/models/responses/enums.py,sha256=Au8XhD-4T8ljiueUykFDc6Qz7kOoTlJ_kiDEx7nLVLM,1191
15
- otf_api/models/responses/favorite_studios.py,sha256=C5JSyiNijm6HQEBVrV9vPfZexSWQ1IlN0E3Ag0GeP_0,4982
16
- otf_api/models/responses/latest_agreement.py,sha256=aE8hbWE4Pgguw4Itah7a1SqwOLpJ6t9oODFwLQ8Wzo0,774
17
- otf_api/models/responses/lifetime_stats.py,sha256=3nWjXJoIcTV_R-Q-3SXo63Uj2xjkFtNXmzj_jPcZPyo,3339
18
- otf_api/models/responses/member_detail.py,sha256=WG_GjS_7mZQ72d5rgu7e1dc3e4fVaR5HRlxFtbJfct8,6024
19
- otf_api/models/responses/member_membership.py,sha256=_z301T9DrdQW9vIgnx_LeZmkRhvMVhkxrn_v6DDfCUk,995
20
- otf_api/models/responses/member_purchases.py,sha256=JoTk3hYjsq4rXogVivZxeFaM-j3gIChmIAGVldOU7rE,6085
21
- otf_api/models/responses/out_of_studio_workout_history.py,sha256=FwdnmTgFrMtQ8PngsmCv3UroWj3kDnQg6KfGLievoaU,1709
22
- otf_api/models/responses/performance_summary_detail.py,sha256=H5yWxGShR4uiXvY2OaniENburTGM7DKQjN7gvF3MG6g,1585
23
- otf_api/models/responses/performance_summary_list.py,sha256=R__tsXGz5tVX5gfoRoVUNK4UP2pXRoK5jdSyHABsDXs,1234
24
- otf_api/models/responses/studio_detail.py,sha256=CJBCsi4SMs_W5nrWE4hfCs1ugJ5t7GrH80hTv7Ie3eg,5007
25
- otf_api/models/responses/studio_services.py,sha256=mFDClPtU0HCk5fb19gjGKpt2F8n8kto7sj1pE_l4RdQ,1836
26
- otf_api/models/responses/telemetry.py,sha256=8dl8FKLeyb6jtqsZT7XD4JzXBMLlami448-Jt0tFbSY,1663
27
- otf_api/models/responses/telemetry_hr_history.py,sha256=vDcLb4wTHVBw8O0mGblUujHfJegkflOCWW-bnTXNCI0,763
28
- otf_api/models/responses/telemetry_max_hr.py,sha256=xKxH0fIlOqFyZv8UW98XsxF-GMoIs9gnCTAbu88ZQtg,266
29
- otf_api/models/responses/total_classes.py,sha256=WrKkWbq0eK8J0RC4qhZ5kmXnv_ZTDbyzsoRm7XKGlss,288
30
- otf_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- otf_api-0.6.0.dist-info/AUTHORS.md,sha256=FcNWMxpe8KDuTq4Qau0SUXsabQwGs9TGnMp1WkXRnj8,123
32
- otf_api-0.6.0.dist-info/LICENSE,sha256=UaPT9ynYigC3nX8n22_rC37n-qmTRKLFaHrtUwF9ktE,1071
33
- otf_api-0.6.0.dist-info/METADATA,sha256=lzG11-AQbcrEr5whF8QiBWSeJljHCG3V2OL_I1hDl6M,2031
34
- otf_api-0.6.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
35
- otf_api-0.6.0.dist-info/RECORD,,