otf-api 0.2.2__py3-none-any.whl → 0.3.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 +12 -67
- otf_api/api.py +794 -36
- otf_api/cli/__init__.py +4 -0
- otf_api/cli/_utilities.py +60 -0
- otf_api/cli/app.py +177 -0
- otf_api/cli/bookings.py +231 -0
- otf_api/cli/prompts.py +162 -0
- otf_api/models/__init__.py +4 -8
- otf_api/models/auth.py +18 -12
- otf_api/models/base.py +205 -2
- otf_api/models/responses/__init__.py +6 -14
- otf_api/models/responses/body_composition_list.py +304 -0
- otf_api/models/responses/book_class.py +405 -0
- otf_api/models/responses/bookings.py +211 -37
- otf_api/models/responses/cancel_booking.py +93 -0
- otf_api/models/responses/challenge_tracker_content.py +6 -6
- otf_api/models/responses/challenge_tracker_detail.py +6 -6
- otf_api/models/responses/classes.py +205 -7
- otf_api/models/responses/enums.py +0 -35
- otf_api/models/responses/favorite_studios.py +5 -5
- otf_api/models/responses/latest_agreement.py +2 -2
- otf_api/models/responses/lifetime_stats.py +92 -0
- otf_api/models/responses/member_detail.py +17 -12
- otf_api/models/responses/member_membership.py +2 -2
- otf_api/models/responses/member_purchases.py +9 -9
- otf_api/models/responses/out_of_studio_workout_history.py +4 -4
- otf_api/models/responses/performance_summary_detail.py +1 -1
- otf_api/models/responses/performance_summary_list.py +13 -13
- otf_api/models/responses/studio_detail.py +10 -10
- otf_api/models/responses/studio_services.py +8 -8
- otf_api/models/responses/telemetry.py +6 -6
- otf_api/models/responses/telemetry_hr_history.py +6 -6
- otf_api/models/responses/telemetry_max_hr.py +3 -3
- otf_api/models/responses/total_classes.py +2 -2
- otf_api/models/responses/workouts.py +4 -4
- otf_api-0.3.0.dist-info/METADATA +55 -0
- otf_api-0.3.0.dist-info/RECORD +42 -0
- otf_api-0.3.0.dist-info/entry_points.txt +3 -0
- otf_api/__version__.py +0 -1
- otf_api/classes_api.py +0 -44
- otf_api/member_api.py +0 -380
- otf_api/performance_api.py +0 -54
- otf_api/studios_api.py +0 -96
- otf_api/telemetry_api.py +0 -95
- otf_api-0.2.2.dist-info/METADATA +0 -284
- otf_api-0.2.2.dist-info/RECORD +0 -38
- {otf_api-0.2.2.dist-info → otf_api-0.3.0.dist-info}/AUTHORS.md +0 -0
- {otf_api-0.2.2.dist-info → otf_api-0.3.0.dist-info}/LICENSE +0 -0
- {otf_api-0.2.2.dist-info → otf_api-0.3.0.dist-info}/WHEEL +0 -0
@@ -1,13 +1,89 @@
|
|
1
1
|
from datetime import datetime
|
2
|
+
from enum import Enum
|
3
|
+
from typing import ClassVar
|
2
4
|
|
5
|
+
from inflection import humanize
|
3
6
|
from pydantic import Field
|
7
|
+
from rich.style import Style
|
8
|
+
from rich.styled import Styled
|
9
|
+
from rich.table import Table
|
4
10
|
|
5
|
-
from otf_api.models.base import
|
11
|
+
from otf_api.models.base import OtfItemBase, OtfListBase
|
12
|
+
from otf_api.models.responses.classes import OtfClassTimeMixin
|
6
13
|
|
7
|
-
from .enums import BookingStatus, StudioStatus
|
8
14
|
|
15
|
+
class StudioStatus(str, Enum):
|
16
|
+
OTHER = "OTHER"
|
17
|
+
ACTIVE = "Active"
|
18
|
+
INACTIVE = "Inactive"
|
19
|
+
COMING_SOON = "Coming Soon"
|
20
|
+
TEMP_CLOSED = "Temporarily Closed"
|
21
|
+
PERM_CLOSED = "Permanently Closed"
|
9
22
|
|
10
|
-
|
23
|
+
@classmethod
|
24
|
+
def all_statuses(cls) -> list[str]:
|
25
|
+
return list(cls.__members__.values())
|
26
|
+
|
27
|
+
|
28
|
+
class BookingStatus(str, Enum):
|
29
|
+
CheckedIn = "Checked In"
|
30
|
+
CancelCheckinPending = "Cancel Checkin Pending"
|
31
|
+
CancelCheckinRequested = "Cancel Checkin Requested"
|
32
|
+
Cancelled = "Cancelled"
|
33
|
+
LateCancelled = "Late Cancelled"
|
34
|
+
Booked = "Booked"
|
35
|
+
Waitlisted = "Waitlisted"
|
36
|
+
CheckinPending = "Checkin Pending"
|
37
|
+
CheckinRequested = "Checkin Requested"
|
38
|
+
CheckinCancelled = "Checkin Cancelled"
|
39
|
+
|
40
|
+
@classmethod
|
41
|
+
def get_from_key_insensitive(cls, key: str) -> "BookingStatus":
|
42
|
+
lcase_to_actual = {item.lower(): item for item in cls._member_map_}
|
43
|
+
val = cls.__members__.get(lcase_to_actual[key.lower()])
|
44
|
+
if not val:
|
45
|
+
raise ValueError(f"Invalid BookingStatus: {key}")
|
46
|
+
return val
|
47
|
+
|
48
|
+
@classmethod
|
49
|
+
def get_case_insensitive(cls, value: str) -> str:
|
50
|
+
lcase_to_actual = {item.value.lower(): item.value for item in cls}
|
51
|
+
return lcase_to_actual[value.lower()]
|
52
|
+
|
53
|
+
@classmethod
|
54
|
+
def all_statuses(cls) -> list[str]:
|
55
|
+
return list(cls.__members__.values())
|
56
|
+
|
57
|
+
|
58
|
+
class BookingStatusCli(str, Enum):
|
59
|
+
"""Flipped enum so that the CLI does not have values with spaces"""
|
60
|
+
|
61
|
+
CheckedIn = "CheckedIn"
|
62
|
+
CancelCheckinPending = "CancelCheckinPending"
|
63
|
+
CancelCheckinRequested = "CancelCheckinRequested"
|
64
|
+
Cancelled = "Cancelled"
|
65
|
+
LateCancelled = "LateCancelled"
|
66
|
+
Booked = "Booked"
|
67
|
+
Waitlisted = "Waitlisted"
|
68
|
+
CheckinPending = "CheckinPending"
|
69
|
+
CheckinRequested = "CheckinRequested"
|
70
|
+
CheckinCancelled = "CheckinCancelled"
|
71
|
+
|
72
|
+
@classmethod
|
73
|
+
def to_standard_case_insensitive(cls, key: str) -> BookingStatus:
|
74
|
+
lcase_to_actual = {item.lower(): item for item in cls._member_map_}
|
75
|
+
val = cls.__members__.get(lcase_to_actual[key.lower()])
|
76
|
+
if not val:
|
77
|
+
raise ValueError(f"Invalid BookingStatus: {key}")
|
78
|
+
return BookingStatus(val)
|
79
|
+
|
80
|
+
@classmethod
|
81
|
+
def get_case_insensitive(cls, value: str) -> str:
|
82
|
+
lcase_to_actual = {item.value.lower(): item.value for item in cls}
|
83
|
+
return lcase_to_actual[value.lower()]
|
84
|
+
|
85
|
+
|
86
|
+
class Location(OtfItemBase):
|
11
87
|
address_one: str = Field(alias="address1")
|
12
88
|
address_two: str | None = Field(alias="address2")
|
13
89
|
city: str
|
@@ -21,30 +97,30 @@ class Location(OtfBaseModel):
|
|
21
97
|
state: str | None = None
|
22
98
|
|
23
99
|
|
24
|
-
class Coach(
|
100
|
+
class Coach(OtfItemBase):
|
25
101
|
coach_uuid: str = Field(alias="coachUUId")
|
26
102
|
name: str
|
27
103
|
first_name: str = Field(alias="firstName")
|
28
104
|
last_name: str = Field(alias="lastName")
|
29
|
-
image_url: str = Field(alias="imageUrl")
|
30
|
-
profile_picture_url: str | None = Field(None, alias="profilePictureUrl")
|
105
|
+
image_url: str = Field(alias="imageUrl", exclude=True)
|
106
|
+
profile_picture_url: str | None = Field(None, alias="profilePictureUrl", exclude=True)
|
31
107
|
|
32
108
|
|
33
|
-
class Currency(
|
109
|
+
class Currency(OtfItemBase):
|
34
110
|
currency_alphabetic_code: str = Field(alias="currencyAlphabeticCode")
|
35
111
|
|
36
112
|
|
37
|
-
class DefaultCurrency(
|
113
|
+
class DefaultCurrency(OtfItemBase):
|
38
114
|
currency_id: int = Field(alias="currencyId")
|
39
115
|
currency: Currency
|
40
116
|
|
41
117
|
|
42
|
-
class StudioLocationCountry(
|
118
|
+
class StudioLocationCountry(OtfItemBase):
|
43
119
|
country_currency_code: str = Field(alias="countryCurrencyCode")
|
44
120
|
default_currency: DefaultCurrency = Field(alias="defaultCurrency")
|
45
121
|
|
46
122
|
|
47
|
-
class StudioLocation(
|
123
|
+
class StudioLocation(OtfItemBase):
|
48
124
|
latitude: float = Field(alias="latitude")
|
49
125
|
longitude: float = Field(alias="longitude")
|
50
126
|
phone_number: str = Field(alias="phoneNumber")
|
@@ -53,33 +129,33 @@ class StudioLocation(OtfBaseModel):
|
|
53
129
|
physical_address2: str | None = Field(alias="physicalAddress2")
|
54
130
|
physical_state: str = Field(alias="physicalState")
|
55
131
|
physical_postal_code: str = Field(alias="physicalPostalCode")
|
56
|
-
physical_region: str = Field(alias="physicalRegion")
|
57
|
-
physical_country_id: int = Field(alias="physicalCountryId")
|
132
|
+
physical_region: str = Field(alias="physicalRegion", exclude=True)
|
133
|
+
physical_country_id: int = Field(alias="physicalCountryId", exclude=True)
|
58
134
|
physical_country: str = Field(alias="physicalCountry")
|
59
|
-
country: StudioLocationCountry = Field(alias="country")
|
135
|
+
country: StudioLocationCountry = Field(alias="country", exclude=True)
|
60
136
|
|
61
137
|
|
62
|
-
class Studio(
|
138
|
+
class Studio(OtfItemBase):
|
63
139
|
studio_uuid: str = Field(alias="studioUUId")
|
64
140
|
studio_name: str = Field(alias="studioName")
|
65
|
-
description: str
|
66
|
-
contact_email: str = Field(alias="contactEmail")
|
141
|
+
description: str | None = None
|
142
|
+
contact_email: str = Field(alias="contactEmail", exclude=True)
|
67
143
|
status: StudioStatus
|
68
|
-
logo_url: str | None = Field(alias="logoUrl")
|
144
|
+
logo_url: str | None = Field(alias="logoUrl", exclude=True)
|
69
145
|
time_zone: str = Field(alias="timeZone")
|
70
|
-
mbo_studio_id: int = Field(alias="mboStudioId")
|
146
|
+
mbo_studio_id: int = Field(alias="mboStudioId", exclude=True)
|
71
147
|
studio_id: int = Field(alias="studioId")
|
72
148
|
allows_cr_waitlist: bool | None = Field(None, alias="allowsCRWaitlist")
|
73
|
-
cr_waitlist_flag_last_updated: datetime = Field(alias="crWaitlistFlagLastUpdated")
|
74
|
-
studio_location: StudioLocation = Field(alias="studioLocation")
|
149
|
+
cr_waitlist_flag_last_updated: datetime = Field(alias="crWaitlistFlagLastUpdated", exclude=True)
|
150
|
+
studio_location: StudioLocation = Field(alias="studioLocation", exclude=True)
|
75
151
|
|
76
152
|
|
77
|
-
class OtfClass(
|
153
|
+
class OtfClass(OtfItemBase, OtfClassTimeMixin):
|
78
154
|
class_uuid: str = Field(alias="classUUId")
|
79
155
|
name: str
|
80
|
-
description: str
|
81
|
-
|
82
|
-
|
156
|
+
description: str | None = Field(None, exclude=True)
|
157
|
+
starts_at_local: datetime = Field(alias="startDateTime")
|
158
|
+
ends_at_local: datetime = Field(alias="endDateTime")
|
83
159
|
is_available: bool = Field(alias="isAvailable")
|
84
160
|
is_cancelled: bool = Field(alias="isCancelled")
|
85
161
|
program_name: str = Field(alias="programName")
|
@@ -89,42 +165,140 @@ class OtfClass(OtfBaseModel):
|
|
89
165
|
location: Location
|
90
166
|
virtual_class: bool | None = Field(None, alias="virtualClass")
|
91
167
|
|
168
|
+
@classmethod
|
169
|
+
def attr_to_column_header(cls, attr: str) -> str:
|
170
|
+
attr_map = {k: humanize(k) for k in cls.model_fields}
|
171
|
+
overrides = {
|
172
|
+
"day_of_week": "Class DoW",
|
173
|
+
"date": "Class Date",
|
174
|
+
"time": "Class Time",
|
175
|
+
"duration": "Class Duration",
|
176
|
+
"name": "Class Name",
|
177
|
+
"is_home_studio": "Home Studio",
|
178
|
+
"is_booked": "Booked",
|
179
|
+
}
|
180
|
+
|
181
|
+
attr_map.update(overrides)
|
182
|
+
|
183
|
+
return attr_map.get(attr, attr)
|
184
|
+
|
92
185
|
|
93
|
-
class Member(
|
186
|
+
class Member(OtfItemBase):
|
94
187
|
member_uuid: str = Field(alias="memberUUId")
|
95
188
|
first_name: str = Field(alias="firstName")
|
96
189
|
last_name: str = Field(alias="lastName")
|
97
190
|
email: str
|
98
191
|
phone_number: str = Field(alias="phoneNumber")
|
99
192
|
gender: str
|
100
|
-
cc_last_4: str = Field(alias="ccLast4")
|
193
|
+
cc_last_4: str = Field(alias="ccLast4", exclude=True)
|
101
194
|
|
102
195
|
|
103
|
-
class Booking(
|
196
|
+
class Booking(OtfItemBase):
|
104
197
|
class_booking_id: int = Field(alias="classBookingId")
|
105
198
|
class_booking_uuid: str = Field(alias="classBookingUUId")
|
106
199
|
studio_id: int = Field(alias="studioId")
|
107
200
|
class_id: int = Field(alias="classId")
|
108
201
|
is_intro: bool = Field(alias="isIntro")
|
109
202
|
member_id: int = Field(alias="memberId")
|
110
|
-
mbo_member_id: str = Field(alias="mboMemberId")
|
111
|
-
mbo_class_id: int = Field(alias="mboClassId")
|
112
|
-
mbo_visit_id: int | None = Field(None, alias="mboVisitId")
|
113
|
-
mbo_waitlist_entry_id: int | None = Field(alias="mboWaitlistEntryId")
|
114
|
-
mbo_sync_message: str | None = Field(alias="mboSyncMessage")
|
203
|
+
mbo_member_id: str = Field(alias="mboMemberId", exclude=True)
|
204
|
+
mbo_class_id: int = Field(alias="mboClassId", exclude=True)
|
205
|
+
mbo_visit_id: int | None = Field(None, alias="mboVisitId", exclude=True)
|
206
|
+
mbo_waitlist_entry_id: int | None = Field(alias="mboWaitlistEntryId", exclude=True)
|
207
|
+
mbo_sync_message: str | None = Field(alias="mboSyncMessage", exclude=True)
|
115
208
|
status: BookingStatus
|
116
209
|
booked_date: datetime | None = Field(None, alias="bookedDate")
|
117
210
|
checked_in_date: datetime | None = Field(alias="checkedInDate")
|
118
211
|
cancelled_date: datetime | None = Field(alias="cancelledDate")
|
119
|
-
created_by: str = Field(alias="createdBy")
|
212
|
+
created_by: str = Field(alias="createdBy", exclude=True)
|
120
213
|
created_date: datetime = Field(alias="createdDate")
|
121
|
-
updated_by: str = Field(alias="updatedBy")
|
214
|
+
updated_by: str = Field(alias="updatedBy", exclude=True)
|
122
215
|
updated_date: datetime = Field(alias="updatedDate")
|
123
216
|
is_deleted: bool = Field(alias="isDeleted")
|
124
|
-
member: Member
|
217
|
+
member: Member = Field(exclude=True)
|
125
218
|
waitlist_position: int | None = Field(None, alias="waitlistPosition")
|
126
|
-
|
219
|
+
otf_class: OtfClass = Field(alias="class")
|
220
|
+
is_home_studio: bool | None = Field(None, description="Custom helper field to determine if at home studio")
|
127
221
|
|
222
|
+
@property
|
223
|
+
def id_val(self) -> str:
|
224
|
+
return self.class_booking_id
|
128
225
|
|
129
|
-
|
226
|
+
@property
|
227
|
+
def sidebar_data(self) -> Table:
|
228
|
+
data = {
|
229
|
+
"date": self.otf_class.date,
|
230
|
+
"class_name": self.otf_class.name,
|
231
|
+
"description": self.otf_class.description,
|
232
|
+
"class_id": self.id_val,
|
233
|
+
"studio_address": self.otf_class.studio.studio_location.physical_address,
|
234
|
+
"coach_name": self.otf_class.coach.name,
|
235
|
+
}
|
236
|
+
|
237
|
+
table = Table(expand=True, show_header=False, show_footer=False)
|
238
|
+
table.add_column("Key", style="cyan", ratio=1)
|
239
|
+
table.add_column("Value", style="magenta", ratio=2)
|
240
|
+
|
241
|
+
for key, value in data.items():
|
242
|
+
if value is False:
|
243
|
+
table.add_row(key, Styled(str(value), style="red"))
|
244
|
+
else:
|
245
|
+
table.add_row(key, str(value))
|
246
|
+
|
247
|
+
return table
|
248
|
+
|
249
|
+
def get_style(self, is_selected: bool = False) -> Style:
|
250
|
+
style = super().get_style(is_selected)
|
251
|
+
if self.status == BookingStatus.Cancelled:
|
252
|
+
style = Style(color="red")
|
253
|
+
elif self.status == BookingStatus.Waitlisted:
|
254
|
+
style = Style(color="yellow")
|
255
|
+
elif self.status == BookingStatus.CheckedIn and is_selected:
|
256
|
+
style = Style(color="blue", strike=True)
|
257
|
+
elif self.status == BookingStatus.CheckedIn:
|
258
|
+
style = Style(color="grey58")
|
259
|
+
|
260
|
+
return style
|
261
|
+
|
262
|
+
@classmethod
|
263
|
+
def attr_to_column_header(cls, attr: str) -> str:
|
264
|
+
if attr.startswith("otf_class"):
|
265
|
+
return OtfClass.attr_to_column_header(attr.split(".")[-1])
|
266
|
+
|
267
|
+
attr_map = {k: humanize(k) for k in cls.model_fields}
|
268
|
+
overrides = {
|
269
|
+
"day_of_week": "Class DoW",
|
270
|
+
"date": "Class Date",
|
271
|
+
"time": "Class Time",
|
272
|
+
"duration": "Class Duration",
|
273
|
+
"name": "Class Name",
|
274
|
+
"is_home_studio": "Home Studio",
|
275
|
+
"is_booked": "Booked",
|
276
|
+
}
|
277
|
+
|
278
|
+
attr_map.update(overrides)
|
279
|
+
|
280
|
+
return attr_map.get(attr, attr)
|
281
|
+
|
282
|
+
|
283
|
+
class BookingList(OtfListBase):
|
284
|
+
collection_field: ClassVar[str] = "bookings"
|
130
285
|
bookings: list[Booking]
|
286
|
+
|
287
|
+
@staticmethod
|
288
|
+
def show_bookings_columns() -> list[str]:
|
289
|
+
return [
|
290
|
+
"otf_class.day_of_week",
|
291
|
+
"otf_class.date",
|
292
|
+
"otf_class.time",
|
293
|
+
"otf_class.duration",
|
294
|
+
"otf_class.name",
|
295
|
+
"status",
|
296
|
+
"otf_class.studio.studio_name",
|
297
|
+
"is_home_studio",
|
298
|
+
]
|
299
|
+
|
300
|
+
def to_table(self, columns: list[str] | None = None) -> Table:
|
301
|
+
if not columns:
|
302
|
+
columns = self.show_bookings_columns()
|
303
|
+
|
304
|
+
return super().to_table(columns)
|
@@ -0,0 +1,93 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
|
3
|
+
from pydantic import BaseModel, Field
|
4
|
+
|
5
|
+
|
6
|
+
class Studio(BaseModel):
|
7
|
+
studio_uuid: str = Field(..., alias="studioUUId")
|
8
|
+
studio_name: str = Field(..., alias="studioName")
|
9
|
+
description: str
|
10
|
+
contact_email: str = Field(..., alias="contactEmail")
|
11
|
+
status: str
|
12
|
+
logo_url: str = Field(..., alias="logoUrl")
|
13
|
+
time_zone: str = Field(..., alias="timeZone")
|
14
|
+
mbo_studio_id: int = Field(..., alias="mboStudioId")
|
15
|
+
studio_id: int = Field(..., alias="studioId")
|
16
|
+
allows_cr_waitlist: bool = Field(..., alias="allowsCRWaitlist")
|
17
|
+
cr_waitlist_flag_last_updated: datetime = Field(..., alias="crWaitlistFlagLastUpdated")
|
18
|
+
|
19
|
+
|
20
|
+
class Coach(BaseModel):
|
21
|
+
coach_uuid: str = Field(..., alias="coachUUId")
|
22
|
+
name: str
|
23
|
+
first_name: str = Field(..., alias="firstName")
|
24
|
+
last_name: str = Field(..., alias="lastName")
|
25
|
+
mbo_coach_id: int = Field(..., alias="mboCoachId")
|
26
|
+
|
27
|
+
|
28
|
+
class Class(BaseModel):
|
29
|
+
class_uuid: str = Field(..., alias="classUUId")
|
30
|
+
name: str
|
31
|
+
description: str
|
32
|
+
start_date_time: datetime = Field(..., alias="startDateTime")
|
33
|
+
end_date_time: datetime = Field(..., alias="endDateTime")
|
34
|
+
is_available: bool = Field(..., alias="isAvailable")
|
35
|
+
is_cancelled: bool = Field(..., alias="isCancelled")
|
36
|
+
total_booked: int = Field(..., alias="totalBooked")
|
37
|
+
mbo_class_id: int = Field(..., alias="mboClassId")
|
38
|
+
mbo_studio_id: int = Field(..., alias="mboStudioId")
|
39
|
+
studio: Studio
|
40
|
+
coach: Coach
|
41
|
+
|
42
|
+
|
43
|
+
class HomeStudio(BaseModel):
|
44
|
+
studio_uuid: str = Field(..., alias="studioUUId")
|
45
|
+
studio_name: str = Field(..., alias="studioName")
|
46
|
+
description: str
|
47
|
+
contact_email: str = Field(..., alias="contactEmail")
|
48
|
+
status: str
|
49
|
+
logo_url: str = Field(..., alias="logoUrl")
|
50
|
+
time_zone: str = Field(..., alias="timeZone")
|
51
|
+
mbo_studio_id: int = Field(..., alias="mboStudioId")
|
52
|
+
studio_id: int = Field(..., alias="studioId")
|
53
|
+
allows_cr_waitlist: bool = Field(..., alias="allowsCRWaitlist")
|
54
|
+
cr_waitlist_flag_last_updated: datetime = Field(..., alias="crWaitlistFlagLastUpdated")
|
55
|
+
|
56
|
+
|
57
|
+
class Member(BaseModel):
|
58
|
+
member_id: int = Field(..., alias="memberId")
|
59
|
+
member_uuid: str = Field(..., alias="memberUUId")
|
60
|
+
email: str
|
61
|
+
phone_number: str = Field(..., alias="phoneNumber")
|
62
|
+
first_name: str = Field(..., alias="firstName")
|
63
|
+
last_name: str = Field(..., alias="lastName")
|
64
|
+
mbo_id: str = Field(..., alias="mboId")
|
65
|
+
cc_last4: str = Field(..., alias="ccLast4")
|
66
|
+
mbo_studio_id: int = Field(..., alias="mboStudioId")
|
67
|
+
home_studio: HomeStudio = Field(..., alias="homeStudio")
|
68
|
+
|
69
|
+
|
70
|
+
class CancelBooking(BaseModel):
|
71
|
+
class_booking_id: int = Field(..., alias="classBookingId")
|
72
|
+
class_booking_uuid: str = Field(..., alias="classBookingUUId")
|
73
|
+
studio_id: int = Field(..., alias="studioId")
|
74
|
+
class_id: int = Field(..., alias="classId")
|
75
|
+
is_intro: bool = Field(..., alias="isIntro")
|
76
|
+
member_id: int = Field(..., alias="memberId")
|
77
|
+
mbo_member_id: str = Field(..., alias="mboMemberId")
|
78
|
+
mbo_class_id: int = Field(..., alias="mboClassId")
|
79
|
+
mbo_visit_id: int = Field(..., alias="mboVisitId")
|
80
|
+
mbo_waitlist_entry_id: None = Field(..., alias="mboWaitlistEntryId")
|
81
|
+
mbo_sync_message: str = Field(..., alias="mboSyncMessage")
|
82
|
+
status: str
|
83
|
+
booked_date: datetime = Field(..., alias="bookedDate")
|
84
|
+
checked_in_date: None = Field(..., alias="checkedInDate")
|
85
|
+
cancelled_date: datetime = Field(..., alias="cancelledDate")
|
86
|
+
created_by: str = Field(..., alias="createdBy")
|
87
|
+
created_date: datetime = Field(..., alias="createdDate")
|
88
|
+
updated_by: str = Field(..., alias="updatedBy")
|
89
|
+
updated_date: datetime = Field(..., alias="updatedDate")
|
90
|
+
is_deleted: bool = Field(..., alias="isDeleted")
|
91
|
+
otf_class: Class = Field(..., alias="class")
|
92
|
+
member: Member
|
93
|
+
continue_retry: bool = Field(..., alias="continueRetry")
|
@@ -1,15 +1,15 @@
|
|
1
1
|
from pydantic import Field
|
2
2
|
|
3
|
-
from otf_api.models.base import
|
3
|
+
from otf_api.models.base import OtfItemBase
|
4
4
|
|
5
5
|
|
6
|
-
class Year(
|
6
|
+
class Year(OtfItemBase):
|
7
7
|
year: str = Field(..., alias="Year")
|
8
8
|
is_participated: bool = Field(..., alias="IsParticipated")
|
9
9
|
in_progress: bool = Field(..., alias="InProgress")
|
10
10
|
|
11
11
|
|
12
|
-
class Program(
|
12
|
+
class Program(OtfItemBase):
|
13
13
|
challenge_category_id: int = Field(..., alias="ChallengeCategoryId")
|
14
14
|
challenge_sub_category_id: int = Field(..., alias="ChallengeSubCategoryId")
|
15
15
|
challenge_name: str = Field(..., alias="ChallengeName")
|
@@ -17,7 +17,7 @@ class Program(OtfBaseModel):
|
|
17
17
|
logo_url: str = Field(..., alias="LogoUrl")
|
18
18
|
|
19
19
|
|
20
|
-
class Challenge(
|
20
|
+
class Challenge(OtfItemBase):
|
21
21
|
challenge_category_id: int = Field(..., alias="ChallengeCategoryId")
|
22
22
|
challenge_sub_category_id: int = Field(..., alias="ChallengeSubCategoryId")
|
23
23
|
challenge_name: str = Field(..., alias="ChallengeName")
|
@@ -25,14 +25,14 @@ class Challenge(OtfBaseModel):
|
|
25
25
|
logo_url: str = Field(..., alias="LogoUrl")
|
26
26
|
|
27
27
|
|
28
|
-
class Benchmark(
|
28
|
+
class Benchmark(OtfItemBase):
|
29
29
|
equipment_id: int = Field(..., alias="EquipmentId")
|
30
30
|
equipment_name: str = Field(..., alias="EquipmentName")
|
31
31
|
years: list[Year] = Field(..., alias="Years")
|
32
32
|
logo_url: str = Field(..., alias="LogoUrl")
|
33
33
|
|
34
34
|
|
35
|
-
class ChallengeTrackerContent(
|
35
|
+
class ChallengeTrackerContent(OtfItemBase):
|
36
36
|
programs: list[Program] = Field(..., alias="Programs")
|
37
37
|
challenges: list[Challenge] = Field(..., alias="Challenges")
|
38
38
|
benchmarks: list[Benchmark] = Field(..., alias="Benchmarks")
|
@@ -3,10 +3,10 @@ from typing import Any
|
|
3
3
|
|
4
4
|
from pydantic import Field
|
5
5
|
|
6
|
-
from otf_api.models.base import
|
6
|
+
from otf_api.models.base import OtfItemBase
|
7
7
|
|
8
8
|
|
9
|
-
class MetricEntry(
|
9
|
+
class MetricEntry(OtfItemBase):
|
10
10
|
title: str = Field(..., alias="Title")
|
11
11
|
equipment_id: int = Field(..., alias="EquipmentId")
|
12
12
|
entry_type: str = Field(..., alias="EntryType")
|
@@ -15,7 +15,7 @@ class MetricEntry(OtfBaseModel):
|
|
15
15
|
max_value: str = Field(..., alias="MaxValue")
|
16
16
|
|
17
17
|
|
18
|
-
class BenchmarkHistory(
|
18
|
+
class BenchmarkHistory(OtfItemBase):
|
19
19
|
studio_name: str = Field(..., alias="StudioName")
|
20
20
|
equipment_id: int = Field(..., alias="EquipmentId")
|
21
21
|
result: float | str = Field(..., alias="Result")
|
@@ -36,7 +36,7 @@ class BenchmarkHistory(OtfBaseModel):
|
|
36
36
|
) # not sure what this will be, never seen it before
|
37
37
|
|
38
38
|
|
39
|
-
class ChallengeHistory(
|
39
|
+
class ChallengeHistory(OtfItemBase):
|
40
40
|
challenge_objective: str = Field(..., alias="ChallengeObjective")
|
41
41
|
challenge_id: int = Field(..., alias="ChallengeId")
|
42
42
|
studio_id: int = Field(..., alias="StudioId")
|
@@ -48,7 +48,7 @@ class ChallengeHistory(OtfBaseModel):
|
|
48
48
|
benchmark_histories: list[BenchmarkHistory] = Field(..., alias="BenchmarkHistories")
|
49
49
|
|
50
50
|
|
51
|
-
class ChallengeTrackerDetail(
|
51
|
+
class ChallengeTrackerDetail(OtfItemBase):
|
52
52
|
challenge_category_id: int = Field(..., alias="ChallengeCategoryId")
|
53
53
|
challenge_sub_category_id: None = Field(..., alias="ChallengeSubCategoryId")
|
54
54
|
equipment_id: int = Field(..., alias="EquipmentId")
|
@@ -64,5 +64,5 @@ class ChallengeTrackerDetail(OtfBaseModel):
|
|
64
64
|
challenge_histories: list[ChallengeHistory] = Field(..., alias="ChallengeHistories")
|
65
65
|
|
66
66
|
|
67
|
-
class ChallengeTrackerDetailList(
|
67
|
+
class ChallengeTrackerDetailList(OtfItemBase):
|
68
68
|
details: list[ChallengeTrackerDetail]
|