otf-api 0.6.1__tar.gz → 0.6.3__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 (36) hide show
  1. {otf_api-0.6.1 → otf_api-0.6.3}/PKG-INFO +1 -1
  2. {otf_api-0.6.1 → otf_api-0.6.3}/pyproject.toml +1 -1
  3. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/__init__.py +1 -1
  4. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/__init__.py +0 -2
  5. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/__init__.py +1 -2
  6. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/body_composition_list.py +12 -10
  7. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/book_class.py +51 -49
  8. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/bookings.py +0 -66
  9. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/cancel_booking.py +11 -9
  10. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/challenge_tracker_detail.py +8 -7
  11. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/classes.py +2 -32
  12. otf_api-0.6.3/src/otf_api/models/responses/enums.py +23 -0
  13. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/favorite_studios.py +4 -2
  14. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/lifetime_stats.py +10 -8
  15. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/member_detail.py +7 -7
  16. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/member_purchases.py +5 -5
  17. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/out_of_studio_workout_history.py +2 -2
  18. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/performance_summary_detail.py +12 -10
  19. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/performance_summary_list.py +5 -2
  20. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/studio_detail.py +6 -4
  21. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/studio_services.py +2 -2
  22. otf_api-0.6.1/src/otf_api/models/responses/enums.py +0 -52
  23. {otf_api-0.6.1 → otf_api-0.6.3}/AUTHORS.md +0 -0
  24. {otf_api-0.6.1 → otf_api-0.6.3}/LICENSE +0 -0
  25. {otf_api-0.6.1 → otf_api-0.6.3}/README.md +0 -0
  26. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/api.py +0 -0
  27. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/auth.py +0 -0
  28. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/base.py +0 -0
  29. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/challenge_tracker_content.py +0 -0
  30. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/latest_agreement.py +0 -0
  31. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/member_membership.py +0 -0
  32. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/telemetry.py +0 -0
  33. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/telemetry_hr_history.py +0 -0
  34. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/telemetry_max_hr.py +0 -0
  35. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/models/responses/total_classes.py +0 -0
  36. {otf_api-0.6.1 → otf_api-0.6.3}/src/otf_api/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: otf-api
3
- Version: 0.6.1
3
+ Version: 0.6.3
4
4
  Summary: Python OrangeTheory Fitness API Client
5
5
  License: MIT
6
6
  Author: Jessica Smith
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "otf-api"
3
- version = "0.6.1"
3
+ version = "0.6.3"
4
4
  description = "Python OrangeTheory Fitness API Client"
5
5
  authors = ["Jessica Smith <j.smith.git1@gmail.com>"]
6
6
  license = "MIT"
@@ -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.1"
9
+ __version__ = "0.6.3"
10
10
 
11
11
 
12
12
  __all__ = ["Otf", "OtfUser"]
@@ -11,7 +11,6 @@ from .responses import (
11
11
  DoW,
12
12
  EquipmentType,
13
13
  FavoriteStudioList,
14
- HistoryClassStatus,
15
14
  LatestAgreement,
16
15
  MemberDetail,
17
16
  MemberMembership,
@@ -45,7 +44,6 @@ __all__ = [
45
44
  "DoW",
46
45
  "EquipmentType",
47
46
  "FavoriteStudioList",
48
- "HistoryClassStatus",
49
47
  "LatestAgreement",
50
48
  "MemberDetail",
51
49
  "MemberMembership",
@@ -5,7 +5,7 @@ from .cancel_booking import CancelBooking
5
5
  from .challenge_tracker_content import ChallengeTrackerContent
6
6
  from .challenge_tracker_detail import ChallengeTrackerDetailList
7
7
  from .classes import ClassType, DoW, OtfClassList
8
- from .enums import ChallengeType, EquipmentType, HistoryClassStatus
8
+ from .enums import ChallengeType, EquipmentType
9
9
  from .favorite_studios import FavoriteStudioList
10
10
  from .latest_agreement import LatestAgreement
11
11
  from .lifetime_stats import StatsResponse, StatsTime
@@ -35,7 +35,6 @@ __all__ = [
35
35
  "DoW",
36
36
  "EquipmentType",
37
37
  "FavoriteStudioList",
38
- "HistoryClassStatus",
39
38
  "LatestAgreement",
40
39
  "MemberDetail",
41
40
  "MemberMembership",
@@ -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")
@@ -68,16 +70,16 @@ class Member(BaseModel):
68
70
  first_name: str = Field(..., alias="firstName")
69
71
  last_name: str = Field(..., alias="lastName")
70
72
  email: str
71
- profile_picture_url: None = Field(..., alias="profilePictureUrl")
73
+ profile_picture_url: str | None = Field(..., alias="profilePictureUrl")
72
74
  alternate_emails: None = Field(..., alias="alternateEmails")
73
- address_line1: None = Field(..., alias="addressLine1")
74
- address_line2: None = Field(..., alias="addressLine2")
75
- city: None
76
- state: None
77
- postal_code: None = Field(..., alias="postalCode")
75
+ address_line1: str | None = Field(..., alias="addressLine1")
76
+ address_line2: str | None = Field(..., alias="addressLine2")
77
+ city: str | None
78
+ state: str | None
79
+ postal_code: str | None = Field(..., alias="postalCode")
78
80
  phone_number: str = Field(..., alias="phoneNumber")
79
81
  home_phone: str = Field(..., alias="homePhone")
80
- work_phone: None = Field(..., alias="workPhone")
82
+ work_phone: str | None = Field(..., alias="workPhone")
81
83
  phone_type: None = Field(..., alias="phoneType")
82
84
  birth_day: str = Field(..., alias="birthDay")
83
85
  cc_last4: str = Field(..., alias="ccLast4")
@@ -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")
@@ -193,13 +195,13 @@ class SavedBooking(BaseModel):
193
195
  member_id: int = Field(..., alias="memberId")
194
196
  mbo_member_id: str = Field(..., alias="mboMemberId")
195
197
  mbo_class_id: int = Field(..., alias="mboClassId")
196
- mbo_visit_id: None = Field(..., alias="mboVisitId")
197
- mbo_waitlist_entry_id: None = Field(..., alias="mboWaitlistEntryId")
198
- mbo_sync_message: None = Field(..., alias="mboSyncMessage")
198
+ mbo_visit_id: int | None = Field(..., alias="mboVisitId")
199
+ mbo_waitlist_entry_id: int | None = Field(..., alias="mboWaitlistEntryId")
200
+ mbo_sync_message: str | None = Field(..., alias="mboSyncMessage")
199
201
  status: str
200
202
  booked_date: datetime = Field(..., alias="bookedDate")
201
- checked_in_date: None = Field(..., alias="checkedInDate")
202
- cancelled_date: None = Field(..., alias="cancelledDate")
203
+ checked_in_date: datetime | None = Field(..., alias="checkedInDate")
204
+ cancelled_date: datetime | None = Field(..., alias="cancelledDate")
203
205
  created_by: str | None = Field(None, alias="createdBy")
204
206
  created_date: datetime | None = Field(None, alias="createdDate")
205
207
  updated_by: str | None = Field(None, alias="updatedBy")
@@ -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,12 +371,12 @@ 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")
376
378
  web_capacity: WebCapacity = Field(..., alias="webCapacity")
377
- total_booked: None = Field(..., alias="totalBooked")
379
+ total_booked: int | None = Field(..., alias="totalBooked")
378
380
  total_booked_waitlist: TotalBookedWaitlist = Field(..., alias="totalBookedWaitlist")
379
381
  web_booked: WebBooked = Field(..., alias="webBooked")
380
382
  semester_id: SemesterId = Field(..., alias="semesterId")
@@ -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")
@@ -2,7 +2,6 @@ from datetime import datetime
2
2
  from enum import Enum
3
3
  from typing import ClassVar
4
4
 
5
- from inflection import humanize
6
5
  from pydantic import Field
7
6
 
8
7
  from otf_api.models.base import OtfItemBase, OtfListBase
@@ -17,10 +16,6 @@ class StudioStatus(str, Enum):
17
16
  TEMP_CLOSED = "Temporarily Closed"
18
17
  PERM_CLOSED = "Permanently Closed"
19
18
 
20
- @classmethod
21
- def all_statuses(cls) -> list[str]:
22
- return list(cls.__members__.values())
23
-
24
19
 
25
20
  class BookingStatus(str, Enum):
26
21
  CheckedIn = "Checked In"
@@ -34,46 +29,6 @@ class BookingStatus(str, Enum):
34
29
  CheckinRequested = "Checkin Requested"
35
30
  CheckinCancelled = "Checkin Cancelled"
36
31
 
37
- @classmethod
38
- def get_from_key_insensitive(cls, key: str) -> "BookingStatus":
39
- lcase_to_actual = {item.lower(): item for item in cls._member_map_}
40
- val = cls.__members__.get(lcase_to_actual[key.lower()])
41
- if not val:
42
- raise ValueError(f"Invalid BookingStatus: {key}")
43
- return val
44
-
45
- @classmethod
46
- def get_case_insensitive(cls, value: str) -> str:
47
- lcase_to_actual = {item.value.lower(): item.value for item in cls}
48
- return lcase_to_actual[value.lower()]
49
-
50
- @classmethod
51
- def all_statuses(cls) -> list[str]:
52
- return list(cls.__members__.values())
53
-
54
-
55
- class BookingStatusCli(str, Enum):
56
- """Flipped enum so that the CLI does not have values with spaces"""
57
-
58
- CheckedIn = "CheckedIn"
59
- CancelCheckinPending = "CancelCheckinPending"
60
- CancelCheckinRequested = "CancelCheckinRequested"
61
- Cancelled = "Cancelled"
62
- LateCancelled = "LateCancelled"
63
- Booked = "Booked"
64
- Waitlisted = "Waitlisted"
65
- CheckinPending = "CheckinPending"
66
- CheckinRequested = "CheckinRequested"
67
- CheckinCancelled = "CheckinCancelled"
68
-
69
- @classmethod
70
- def to_standard_case_insensitive(cls, key: str) -> BookingStatus:
71
- lcase_to_actual = {item.lower(): item for item in cls._member_map_}
72
- val = cls.__members__.get(lcase_to_actual[key.lower()])
73
- if not val:
74
- raise ValueError(f"Invalid BookingStatus: {key}")
75
- return BookingStatus(val)
76
-
77
32
  @classmethod
78
33
  def get_case_insensitive(cls, value: str) -> str:
79
34
  lcase_to_actual = {item.value.lower(): item.value for item in cls}
@@ -162,23 +117,6 @@ class OtfClass(OtfItemBase, OtfClassTimeMixin):
162
117
  location: Location
163
118
  virtual_class: bool | None = Field(None, alias="virtualClass")
164
119
 
165
- @classmethod
166
- def attr_to_column_header(cls, attr: str) -> str:
167
- attr_map = {k: humanize(k) for k in cls.model_fields}
168
- overrides = {
169
- "day_of_week": "Class DoW",
170
- "date": "Class Date",
171
- "time": "Class Time",
172
- "duration": "Class Duration",
173
- "name": "Class Name",
174
- "is_home_studio": "Home Studio",
175
- "is_booked": "Booked",
176
- }
177
-
178
- attr_map.update(overrides)
179
-
180
- return attr_map.get(attr, attr)
181
-
182
120
 
183
121
  class Member(OtfItemBase):
184
122
  member_uuid: str = Field(alias="memberUUId")
@@ -216,10 +154,6 @@ class Booking(OtfItemBase):
216
154
  otf_class: OtfClass = Field(alias="class")
217
155
  is_home_studio: bool | None = Field(None, description="Custom helper field to determine if at home studio")
218
156
 
219
- @property
220
- def id_val(self) -> str:
221
- return self.class_booking_id
222
-
223
157
 
224
158
  class BookingList(OtfListBase):
225
159
  collection_field: ClassVar[str] = "bookings"
@@ -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")
@@ -77,11 +79,11 @@ class CancelBooking(BaseModel):
77
79
  mbo_member_id: str = Field(..., alias="mboMemberId")
78
80
  mbo_class_id: int = Field(..., alias="mboClassId")
79
81
  mbo_visit_id: int = Field(..., alias="mboVisitId")
80
- mbo_waitlist_entry_id: None = Field(..., alias="mboWaitlistEntryId")
82
+ mbo_waitlist_entry_id: int | None = Field(..., alias="mboWaitlistEntryId")
81
83
  mbo_sync_message: str = Field(..., alias="mboSyncMessage")
82
84
  status: str
83
85
  booked_date: datetime = Field(..., alias="bookedDate")
84
- checked_in_date: None = Field(..., alias="checkedInDate")
86
+ checked_in_date: datetime | None = Field(..., alias="checkedInDate")
85
87
  cancelled_date: datetime = Field(..., alias="cancelledDate")
86
88
  created_by: str = Field(..., alias="createdBy")
87
89
  created_date: datetime = Field(..., alias="createdDate")
@@ -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):
@@ -22,15 +22,15 @@ class BenchmarkHistory(OtfItemBase):
22
22
  date_created: datetime = Field(..., alias="DateCreated")
23
23
  date_updated: datetime = Field(..., alias="DateUpdated")
24
24
  class_time: datetime = Field(..., alias="ClassTime")
25
- challenge_sub_category_id: None = Field(..., alias="ChallengeSubCategoryId")
25
+ challenge_sub_category_id: int | None = Field(..., alias="ChallengeSubCategoryId")
26
26
  class_id: int = Field(..., alias="ClassId")
27
27
  substitute_id: int | None = Field(..., alias="SubstituteId")
28
28
  weight_lbs: int = Field(..., alias="WeightLBS")
29
29
  class_name: str = Field(..., alias="ClassName")
30
30
  coach_name: str = Field(..., alias="CoachName")
31
31
  coach_image_url: str = Field(..., alias="CoachImageUrl")
32
- workout_type_id: None = Field(..., alias="WorkoutTypeId")
33
- workout_id: None = Field(..., alias="WorkoutId")
32
+ workout_type_id: int | None = Field(..., alias="WorkoutTypeId")
33
+ workout_id: int | None = Field(..., alias="WorkoutId")
34
34
  linked_challenges: list[Any] = Field(
35
35
  ..., alias="LinkedChallenges"
36
36
  ) # not sure what this will be, never seen it before
@@ -50,7 +50,7 @@ class ChallengeHistory(OtfItemBase):
50
50
 
51
51
  class ChallengeTrackerDetail(OtfItemBase):
52
52
  challenge_category_id: int = Field(..., alias="ChallengeCategoryId")
53
- challenge_sub_category_id: None = Field(..., alias="ChallengeSubCategoryId")
53
+ challenge_sub_category_id: int | None = Field(..., alias="ChallengeSubCategoryId")
54
54
  equipment_id: int = Field(..., alias="EquipmentId")
55
55
  equipment_name: str = Field(..., alias="EquipmentName")
56
56
  metric_entry: MetricEntry = Field(..., alias="MetricEntry")
@@ -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]
@@ -18,8 +18,8 @@ class DoW(str, Enum):
18
18
  sunday = "sunday"
19
19
 
20
20
  @classmethod
21
- def get_case_insensitive(cls, value: str) -> str:
22
- lcase_to_actual = {item.value.lower(): item.value for item in cls}
21
+ def get_case_insensitive(cls, value: str) -> "DoW":
22
+ lcase_to_actual = {item.value.lower(): item for item in cls}
23
23
  return lcase_to_actual[value.lower()]
24
24
 
25
25
 
@@ -34,38 +34,12 @@ class ClassType(str, Enum):
34
34
  VIP_CLASS = "VIP Class"
35
35
  OTHER = "Other"
36
36
 
37
- @classmethod
38
- def all_statuses(cls) -> list[str]:
39
- return list(cls.__members__.values())
40
-
41
- @classmethod
42
- def get_from_key_insensitive(cls, key: str) -> "ClassType":
43
- lcase_to_actual = {item.lower(): item for item in cls._member_map_}
44
- val = cls.__members__.get(lcase_to_actual[key.lower()])
45
- if not val:
46
- raise ValueError(f"Invalid ClassType: {key}")
47
- return val
48
-
49
37
  @classmethod
50
38
  def get_case_insensitive(cls, value: str) -> str:
51
39
  lcase_to_actual = {item.value.lower(): item.value for item in cls}
52
40
  return lcase_to_actual[value.lower()]
53
41
 
54
42
 
55
- class ClassTypeCli(str, Enum):
56
- """Flipped enum so that the CLI does not have values with spaces"""
57
-
58
- ORANGE_60_MIN_2G = "Orange_60_Min_2G"
59
- TREAD_50 = "Tread_50"
60
- STRENGTH_50 = "Strength_50"
61
- ORANGE_3G = "Orange_3G"
62
- ORANGE_60_TORNADO = "Orange_60_Tornado"
63
- ORANGE_TORNADO = "Orange_Tornado"
64
- ORANGE_90_MIN_3G = "Orange_90_Min_3G"
65
- VIP_CLASS = "VIP_Class"
66
- OTHER = "Other"
67
-
68
-
69
43
  class Address(OtfItemBase):
70
44
  line1: str
71
45
  city: str
@@ -163,10 +137,6 @@ class OtfClass(OtfItemBase, OtfClassTimeMixin):
163
137
  def has_availability(self) -> bool:
164
138
  return not self.full
165
139
 
166
- @property
167
- def id_val(self) -> str:
168
- return self.ot_class_uuid
169
-
170
140
  @property
171
141
  def day_of_week_enum(self) -> DoW:
172
142
  dow = self.starts_at_local.strftime("%A")
@@ -0,0 +1,23 @@
1
+ from enum import Enum
2
+
3
+
4
+ class EquipmentType(int, Enum):
5
+ Treadmill = 2
6
+ Strider = 3
7
+ Rower = 4
8
+ Bike = 5
9
+ WeightFloor = 6
10
+ PowerWalker = 7
11
+
12
+
13
+ class ChallengeType(int, Enum):
14
+ Other = 0
15
+ DriTri = 2
16
+ MarathonMonth = 5
17
+ HellWeek = 52
18
+ Mayhem = 58
19
+ TwelveDaysOfFitness = 63
20
+ Transformation = 64
21
+ RemixInSix = 65
22
+ Push = 66
23
+ BackAtIt = 84
@@ -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")
@@ -93,16 +93,16 @@ class MemberDetail(OtfItemBase):
93
93
  first_name: str = Field(..., alias="firstName")
94
94
  last_name: str = Field(..., alias="lastName")
95
95
  email: str
96
- profile_picture_url: None = Field(..., alias="profilePictureUrl")
96
+ profile_picture_url: str | None = Field(..., alias="profilePictureUrl")
97
97
  alternate_emails: None = Field(..., alias="alternateEmails")
98
- address_line1: None = Field(..., alias="addressLine1")
99
- address_line2: None = Field(..., alias="addressLine2")
100
- city: None
101
- state: None
102
- postal_code: None = Field(..., alias="postalCode")
98
+ address_line1: str | None = Field(..., alias="addressLine1")
99
+ address_line2: str | None = Field(..., alias="addressLine2")
100
+ city: str | None
101
+ state: str | None
102
+ postal_code: str | None = Field(..., alias="postalCode")
103
103
  phone_number: str = Field(..., alias="phoneNumber")
104
104
  home_phone: str | None = Field(..., alias="homePhone")
105
- work_phone: None = Field(..., alias="workPhone")
105
+ work_phone: str | None = Field(..., alias="workPhone")
106
106
  phone_type: None = Field(..., alias="phoneType")
107
107
  birth_day: date | str = Field(..., alias="birthDay")
108
108
  cc_last4: str = Field(..., alias="ccLast4")
@@ -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):
@@ -44,7 +44,7 @@ class StudioLocation(OtfItemBase):
44
44
  bill_to_country_id: int = Field(..., alias="billToCountryId")
45
45
  bill_to_country: str = Field(..., alias="billToCountry")
46
46
  ship_to_address: str = Field(..., alias="shipToAddress")
47
- ship_to_address2: None = Field(..., alias="shipToAddress2")
47
+ ship_to_address2: str | None = Field(..., alias="shipToAddress2")
48
48
  ship_to_city: str = Field(..., alias="shipToCity")
49
49
  ship_to_state: str = Field(..., alias="shipToState")
50
50
  ship_to_postal_code: str = Field(..., alias="shipToPostalCode")
@@ -52,7 +52,7 @@ class StudioLocation(OtfItemBase):
52
52
  ship_to_country_id: int = Field(..., alias="shipToCountryId")
53
53
  ship_to_country: str = Field(..., alias="shipToCountry")
54
54
  physical_address: str = Field(..., alias="physicalAddress")
55
- physical_address2: None = Field(..., alias="physicalAddress2")
55
+ physical_address2: str | None = Field(..., alias="physicalAddress2")
56
56
  physical_city: str = Field(..., alias="physicalCity")
57
57
  physical_state: str = Field(..., alias="physicalState")
58
58
  physical_postal_code: str = Field(..., alias="physicalPostalCode")
@@ -120,7 +120,7 @@ class MemberPurchase(OtfItemBase):
120
120
  status: str
121
121
  member_service_id: int | None = Field(..., alias="memberServiceId")
122
122
  member_membership_id: int | None = Field(..., alias="memberMembershipId")
123
- member_fee_id: None = Field(..., alias="memberFeeId")
123
+ member_fee_id: int | None = Field(..., alias="memberFeeId")
124
124
  pos_contract_id: int | None = Field(..., alias="posContractId")
125
125
  pos_product_id: int = Field(..., alias="posProductId")
126
126
  pos_description_id: int | None = Field(..., alias="posDescriptionId")
@@ -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):
@@ -64,5 +66,6 @@ class PerformanceSummaryEntry(OtfItemBase):
64
66
  ratings: Ratings | None = None
65
67
 
66
68
 
67
- class PerformanceSummaryList(OtfItemBase):
69
+ class PerformanceSummaryList(OtfListBase):
70
+ collection_field: ClassVar[str] = "summaries"
68
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):
@@ -34,8 +35,8 @@ class Language(OtfItemBase):
34
35
 
35
36
  class StudioLocationLocalized(OtfItemBase):
36
37
  language: Language
37
- studio_name: None = Field(..., alias="studioName")
38
- studio_address: None = Field(..., alias="studioAddress")
38
+ studio_name: str | None = Field(..., alias="studioName")
39
+ studio_address: str | None = Field(..., alias="studioAddress")
39
40
 
40
41
 
41
42
  class StudioProfiles(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]
@@ -1,52 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class EquipmentType(int, Enum):
5
- Treadmill = 2
6
- Strider = 3
7
- Rower = 4
8
- Bike = 5
9
- WeightFloor = 6
10
- PowerWalker = 7
11
-
12
-
13
- class ChallengeType(int, Enum):
14
- Other = 0
15
- DriTri = 2
16
- MarathonMonth = 5
17
- HellWeek = 52
18
- Mayhem = 58
19
- TwelveDaysOfFitness = 63
20
- Transformation = 64
21
- RemixInSix = 65
22
- Push = 66
23
- BackAtIt = 84
24
-
25
-
26
- class HistoryBookingStatus(str, Enum):
27
- Attended = "Attended"
28
- Cancelled = "Cancelled"
29
- LateCancelled = "Late Cancelled"
30
-
31
- @classmethod
32
- def all_statuses(cls) -> list[str]:
33
- return list(cls.__members__.values())
34
-
35
-
36
- class HistoryClassStatus(str, Enum):
37
- CheckedIn = "Checked In"
38
- CancelCheckinPending = "Cancel Checkin Pending"
39
- CancelCheckinRequested = "Cancel Checkin Requested"
40
- LateCancelled = "Late Cancelled"
41
- Booked = "Booked"
42
- Waitlisted = "Waitlisted"
43
- CheckinPending = "Checkin Pending"
44
- CheckinRequested = "Checkin Requested"
45
- CheckinCancelled = "Checkin Cancelled"
46
- Pending = "Pending"
47
- Confirmed = "Confirmed"
48
- Requested = "Requested"
49
-
50
- @classmethod
51
- def all_statuses(cls) -> list[str]:
52
- return list(cls.__members__.values())
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes