otf-api 0.6.4__py3-none-any.whl → 0.7.1__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 +1 -9
- otf_api/api.py +76 -111
- otf_api/auth.py +11 -10
- otf_api/exceptions.py +18 -0
- otf_api/models/__init__.py +25 -32
- otf_api/models/base.py +1 -16
- otf_api/models/{responses/body_composition_list.py → body_composition_list.py} +3 -14
- otf_api/models/book_class.py +89 -0
- otf_api/models/bookings.py +119 -0
- otf_api/models/cancel_booking.py +49 -0
- otf_api/models/{responses/challenge_tracker_detail.py → challenge_tracker_detail.py} +12 -13
- otf_api/models/classes.py +80 -0
- otf_api/models/enums.py +87 -0
- otf_api/models/{responses/favorite_studios.py → favorite_studios.py} +17 -19
- otf_api/models/{responses/lifetime_stats.py → lifetime_stats.py} +0 -18
- otf_api/models/{responses/member_detail.py → member_detail.py} +16 -19
- otf_api/models/{responses/member_purchases.py → member_purchases.py} +10 -10
- otf_api/models/mixins.py +44 -0
- otf_api/models/{responses/out_of_studio_workout_history.py → out_of_studio_workout_history.py} +3 -3
- otf_api/models/{responses/performance_summary_list.py → performance_summary_list.py} +2 -5
- otf_api/models/studio_detail.py +109 -0
- otf_api/models/{responses/studio_services.py → studio_services.py} +2 -2
- otf_api/models/{responses/telemetry.py → telemetry.py} +1 -1
- {otf_api-0.6.4.dist-info → otf_api-0.7.1.dist-info}/METADATA +3 -3
- otf_api-0.7.1.dist-info/RECORD +36 -0
- otf_api/models/responses/__init__.py +0 -57
- otf_api/models/responses/book_class.py +0 -407
- otf_api/models/responses/bookings.py +0 -160
- otf_api/models/responses/cancel_booking.py +0 -95
- otf_api/models/responses/classes.py +0 -148
- otf_api/models/responses/enums.py +0 -23
- otf_api/models/responses/studio_detail.py +0 -113
- otf_api-0.6.4.dist-info/RECORD +0 -35
- /otf_api/models/{responses/challenge_tracker_content.py → challenge_tracker_content.py} +0 -0
- /otf_api/models/{responses/latest_agreement.py → latest_agreement.py} +0 -0
- /otf_api/models/{responses/member_membership.py → member_membership.py} +0 -0
- /otf_api/models/{responses/performance_summary_detail.py → performance_summary_detail.py} +0 -0
- /otf_api/models/{responses/telemetry_hr_history.py → telemetry_hr_history.py} +0 -0
- /otf_api/models/{responses/telemetry_max_hr.py → telemetry_max_hr.py} +0 -0
- /otf_api/models/{responses/total_classes.py → total_classes.py} +0 -0
- {otf_api-0.6.4.dist-info → otf_api-0.7.1.dist-info}/AUTHORS.md +0 -0
- {otf_api-0.6.4.dist-info → otf_api-0.7.1.dist-info}/LICENSE +0 -0
- {otf_api-0.6.4.dist-info → otf_api-0.7.1.dist-info}/WHEEL +0 -0
@@ -1,148 +0,0 @@
|
|
1
|
-
from datetime import datetime
|
2
|
-
from enum import Enum
|
3
|
-
from typing import ClassVar
|
4
|
-
|
5
|
-
from humanize import precisedelta
|
6
|
-
from pydantic import Field
|
7
|
-
|
8
|
-
from otf_api.models.base import OtfItemBase, OtfListBase
|
9
|
-
|
10
|
-
|
11
|
-
class DoW(str, Enum):
|
12
|
-
monday = "monday"
|
13
|
-
tuesday = "tuesday"
|
14
|
-
wednesday = "wednesday"
|
15
|
-
thursday = "thursday"
|
16
|
-
friday = "friday"
|
17
|
-
saturday = "saturday"
|
18
|
-
sunday = "sunday"
|
19
|
-
|
20
|
-
@classmethod
|
21
|
-
def get_case_insensitive(cls, value: str) -> "DoW":
|
22
|
-
lcase_to_actual = {item.value.lower(): item for item in cls}
|
23
|
-
return lcase_to_actual[value.lower()]
|
24
|
-
|
25
|
-
|
26
|
-
class ClassType(str, Enum):
|
27
|
-
ORANGE_60_MIN_2G = "Orange 60 Min 2G"
|
28
|
-
TREAD_50 = "Tread 50"
|
29
|
-
STRENGTH_50 = "Strength 50"
|
30
|
-
ORANGE_3G = "Orange 3G"
|
31
|
-
ORANGE_60_TORNADO = "Orange 60 - Tornado"
|
32
|
-
ORANGE_TORNADO = "Orange Tornado"
|
33
|
-
ORANGE_90_MIN_3G = "Orange 90 Min 3G"
|
34
|
-
VIP_CLASS = "VIP Class"
|
35
|
-
OTHER = "Other"
|
36
|
-
|
37
|
-
@classmethod
|
38
|
-
def get_case_insensitive(cls, value: str) -> str:
|
39
|
-
lcase_to_actual = {item.value.lower(): item.value for item in cls}
|
40
|
-
return lcase_to_actual[value.lower()]
|
41
|
-
|
42
|
-
|
43
|
-
class Address(OtfItemBase):
|
44
|
-
line1: str
|
45
|
-
city: str
|
46
|
-
state: str
|
47
|
-
country: str
|
48
|
-
postal_code: str
|
49
|
-
|
50
|
-
|
51
|
-
class Studio(OtfItemBase):
|
52
|
-
id: str
|
53
|
-
name: str
|
54
|
-
mbo_studio_id: str
|
55
|
-
time_zone: str
|
56
|
-
currency_code: str
|
57
|
-
address: Address
|
58
|
-
phone_number: str
|
59
|
-
latitude: float
|
60
|
-
longitude: float
|
61
|
-
|
62
|
-
|
63
|
-
class Coach(OtfItemBase):
|
64
|
-
mbo_staff_id: str
|
65
|
-
first_name: str
|
66
|
-
image_url: str | None = None
|
67
|
-
|
68
|
-
|
69
|
-
class OtfClassTimeMixin:
|
70
|
-
starts_at_local: datetime
|
71
|
-
ends_at_local: datetime
|
72
|
-
name: str
|
73
|
-
|
74
|
-
@property
|
75
|
-
def day_of_week(self) -> str:
|
76
|
-
return self.starts_at_local.strftime("%A")
|
77
|
-
|
78
|
-
@property
|
79
|
-
def date(self) -> str:
|
80
|
-
return self.starts_at_local.strftime("%Y-%m-%d")
|
81
|
-
|
82
|
-
@property
|
83
|
-
def time(self) -> str:
|
84
|
-
"""Returns time in 12 hour clock format, with no leading 0"""
|
85
|
-
val = self.starts_at_local.strftime("%I:%M %p")
|
86
|
-
if val[0] == "0":
|
87
|
-
val = " " + val[1:]
|
88
|
-
|
89
|
-
return val
|
90
|
-
|
91
|
-
@property
|
92
|
-
def duration(self) -> str:
|
93
|
-
duration = self.ends_at_local - self.starts_at_local
|
94
|
-
human_val: str = precisedelta(duration, minimum_unit="minutes")
|
95
|
-
if human_val == "1 hour and 30 minutes":
|
96
|
-
return "90 minutes"
|
97
|
-
return human_val
|
98
|
-
|
99
|
-
@property
|
100
|
-
def class_type(self) -> ClassType:
|
101
|
-
for class_type in ClassType:
|
102
|
-
if class_type.value in self.name:
|
103
|
-
return class_type
|
104
|
-
|
105
|
-
return ClassType.OTHER
|
106
|
-
|
107
|
-
|
108
|
-
class OtfClass(OtfItemBase, OtfClassTimeMixin):
|
109
|
-
id: str
|
110
|
-
ot_class_uuid: str = Field(
|
111
|
-
alias="ot_base_class_uuid",
|
112
|
-
description="The OTF class UUID, this is what shows in a booking response and how you can book a class.",
|
113
|
-
)
|
114
|
-
starts_at: datetime
|
115
|
-
starts_at_local: datetime
|
116
|
-
ends_at: datetime
|
117
|
-
ends_at_local: datetime
|
118
|
-
name: str
|
119
|
-
type: str
|
120
|
-
studio: Studio
|
121
|
-
coach: Coach
|
122
|
-
max_capacity: int
|
123
|
-
booking_capacity: int
|
124
|
-
waitlist_size: int
|
125
|
-
full: bool
|
126
|
-
waitlist_available: bool
|
127
|
-
canceled: bool
|
128
|
-
mbo_class_id: str
|
129
|
-
mbo_class_schedule_id: str
|
130
|
-
mbo_class_description_id: str
|
131
|
-
created_at: datetime
|
132
|
-
updated_at: datetime
|
133
|
-
is_home_studio: bool | None = Field(None, description="Custom helper field to determine if at home studio")
|
134
|
-
is_booked: bool | None = Field(None, description="Custom helper field to determine if class is already booked")
|
135
|
-
|
136
|
-
@property
|
137
|
-
def has_availability(self) -> bool:
|
138
|
-
return not self.full
|
139
|
-
|
140
|
-
@property
|
141
|
-
def day_of_week_enum(self) -> DoW:
|
142
|
-
dow = self.starts_at_local.strftime("%A")
|
143
|
-
return DoW.get_case_insensitive(dow)
|
144
|
-
|
145
|
-
|
146
|
-
class OtfClassList(OtfListBase):
|
147
|
-
collection_field: ClassVar[str] = "classes"
|
148
|
-
classes: list[OtfClass]
|
@@ -1,23 +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
|
@@ -1,113 +0,0 @@
|
|
1
|
-
from datetime import datetime
|
2
|
-
from typing import ClassVar
|
3
|
-
|
4
|
-
from pydantic import Field
|
5
|
-
|
6
|
-
from otf_api.models.base import OtfItemBase, OtfListBase
|
7
|
-
|
8
|
-
|
9
|
-
class Country(OtfItemBase):
|
10
|
-
country_id: int = Field(..., alias="countryId")
|
11
|
-
country_currency_code: str = Field(..., alias="countryCurrencyCode")
|
12
|
-
country_currency_name: str = Field(..., alias="countryCurrencyName")
|
13
|
-
currency_alphabetic_code: str = Field(..., alias="currencyAlphabeticCode")
|
14
|
-
|
15
|
-
|
16
|
-
class StudioLocation(OtfItemBase):
|
17
|
-
physical_address: str = Field(..., alias="physicalAddress")
|
18
|
-
physical_address2: str | None = Field(..., alias="physicalAddress2")
|
19
|
-
physical_city: str = Field(..., alias="physicalCity")
|
20
|
-
physical_state: str = Field(..., alias="physicalState")
|
21
|
-
physical_postal_code: str = Field(..., alias="physicalPostalCode")
|
22
|
-
physical_region: str = Field(..., alias="physicalRegion")
|
23
|
-
physical_country: str = Field(..., alias="physicalCountry")
|
24
|
-
country: Country
|
25
|
-
phone_number: str = Field(..., alias="phoneNumber")
|
26
|
-
latitude: float
|
27
|
-
longitude: float
|
28
|
-
|
29
|
-
|
30
|
-
class Language(OtfItemBase):
|
31
|
-
language_id: None = Field(..., alias="languageId")
|
32
|
-
language_code: None = Field(..., alias="languageCode")
|
33
|
-
language_name: None = Field(..., alias="languageName")
|
34
|
-
|
35
|
-
|
36
|
-
class StudioLocationLocalized(OtfItemBase):
|
37
|
-
language: Language
|
38
|
-
studio_name: str | None = Field(..., alias="studioName")
|
39
|
-
studio_address: str | None = Field(..., alias="studioAddress")
|
40
|
-
|
41
|
-
|
42
|
-
class StudioProfiles(OtfItemBase):
|
43
|
-
is_web: bool = Field(..., alias="isWeb")
|
44
|
-
intro_capacity: int = Field(..., alias="introCapacity")
|
45
|
-
is_crm: bool | None = Field(..., alias="isCrm")
|
46
|
-
|
47
|
-
|
48
|
-
class SocialMediaLink(OtfItemBase):
|
49
|
-
id: str
|
50
|
-
language_id: str = Field(..., alias="languageId")
|
51
|
-
name: str
|
52
|
-
value: str
|
53
|
-
|
54
|
-
|
55
|
-
class StudioDetail(OtfItemBase):
|
56
|
-
studio_id: int = Field(..., alias="studioId")
|
57
|
-
studio_uuid: str = Field(..., alias="studioUUId")
|
58
|
-
mbo_studio_id: int | None = Field(..., alias="mboStudioId")
|
59
|
-
studio_number: str = Field(..., alias="studioNumber")
|
60
|
-
studio_name: str = Field(..., alias="studioName")
|
61
|
-
studio_physical_location_id: int = Field(..., alias="studioPhysicalLocationId")
|
62
|
-
time_zone: str | None = Field(..., alias="timeZone")
|
63
|
-
contact_email: str | None = Field(..., alias="contactEmail")
|
64
|
-
studio_token: str = Field(..., alias="studioToken")
|
65
|
-
environment: str
|
66
|
-
pricing_level: str | None = Field(..., alias="pricingLevel")
|
67
|
-
tax_rate: str | None = Field(..., alias="taxRate")
|
68
|
-
accepts_visa_master_card: bool = Field(..., alias="acceptsVisaMasterCard")
|
69
|
-
accepts_american_express: bool = Field(..., alias="acceptsAmericanExpress")
|
70
|
-
accepts_discover: bool = Field(..., alias="acceptsDiscover")
|
71
|
-
accepts_ach: bool = Field(..., alias="acceptsAch")
|
72
|
-
is_integrated: bool = Field(..., alias="isIntegrated")
|
73
|
-
description: str | None = None
|
74
|
-
studio_version: str | None = Field(..., alias="studioVersion")
|
75
|
-
studio_status: str = Field(..., alias="studioStatus")
|
76
|
-
open_date: datetime | None = Field(..., alias="openDate")
|
77
|
-
re_open_date: datetime | None = Field(..., alias="reOpenDate")
|
78
|
-
studio_type_id: int | None = Field(..., alias="studioTypeId")
|
79
|
-
pos_type_id: int | None = Field(..., alias="posTypeId")
|
80
|
-
market_id: int | None = Field(..., alias="marketId")
|
81
|
-
area_id: int | None = Field(..., alias="areaId")
|
82
|
-
state_id: int | None = Field(..., alias="stateId")
|
83
|
-
logo_url: str | None = Field(..., alias="logoUrl")
|
84
|
-
page_color1: str | None = Field(..., alias="pageColor1")
|
85
|
-
page_color2: str | None = Field(..., alias="pageColor2")
|
86
|
-
page_color3: str | None = Field(..., alias="pageColor3")
|
87
|
-
page_color4: str | None = Field(..., alias="pageColor4")
|
88
|
-
sms_package_enabled: bool | None = Field(..., alias="smsPackageEnabled")
|
89
|
-
allows_dashboard_access: bool | None = Field(..., alias="allowsDashboardAccess")
|
90
|
-
allows_cr_waitlist: bool = Field(..., alias="allowsCrWaitlist")
|
91
|
-
cr_waitlist_flag_last_updated: datetime | None = Field(..., alias="crWaitlistFlagLastUpdated")
|
92
|
-
royalty_rate: int | None = Field(..., alias="royaltyRate")
|
93
|
-
marketing_fund_rate: int | None = Field(..., alias="marketingFundRate")
|
94
|
-
commission_percent: int | None = Field(..., alias="commissionPercent")
|
95
|
-
is_mobile: bool | None = Field(..., alias="isMobile")
|
96
|
-
is_otbeat: bool | None = Field(..., alias="isOtbeat")
|
97
|
-
distance: float | None = None
|
98
|
-
studio_location: StudioLocation = Field(..., alias="studioLocation")
|
99
|
-
studio_location_localized: StudioLocationLocalized = Field(..., alias="studioLocationLocalized")
|
100
|
-
studio_profiles: StudioProfiles = Field(..., alias="studioProfiles")
|
101
|
-
social_media_links: list[SocialMediaLink] = Field(..., alias="socialMediaLinks")
|
102
|
-
|
103
|
-
|
104
|
-
class Pagination(OtfItemBase):
|
105
|
-
page_index: int = Field(..., alias="pageIndex")
|
106
|
-
page_size: int = Field(..., alias="pageSize")
|
107
|
-
total_count: int = Field(..., alias="totalCount")
|
108
|
-
total_pages: int = Field(..., alias="totalPages")
|
109
|
-
|
110
|
-
|
111
|
-
class StudioDetailList(OtfListBase):
|
112
|
-
collection_field: ClassVar[str] = "studios"
|
113
|
-
studios: list[StudioDetail]
|
otf_api-0.6.4.dist-info/RECORD
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
otf_api/__init__.py,sha256=9dl1vObg-jQX4JSv6kUWZnAklknfJet8UkivLcaxQ_0,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=bSElQBSVfwOV4KyFfa134WyCIqPctCXiDVjQkAgOfnc,1378
|
5
|
-
otf_api/models/base.py,sha256=gsMf3XGKqc68CRC-Mp3ARdnXKCpbWWGttZ8pfUwuEu0,664
|
6
|
-
otf_api/models/responses/__init__.py,sha256=cbTfcMieu6Hc91NC2x7fLTacS5dAVuLZUJYKA99fhW4,1901
|
7
|
-
otf_api/models/responses/body_composition_list.py,sha256=N1amk4sWzgiBFmnCUUlMGSwOh_XGucqW_8MvE0XsRKY,12271
|
8
|
-
otf_api/models/responses/book_class.py,sha256=2GLmGXkryUdRUCFNpuSxMAtKcZc9823LLqGcDsQdcK0,15605
|
9
|
-
otf_api/models/responses/bookings.py,sha256=0bKxwNCWt23sXB_PIANdyuperMmZJu1_UdBaUJb8xMI,6295
|
10
|
-
otf_api/models/responses/cancel_booking.py,sha256=O23utnhBs7oxmAgmbq7rD8EC2lvJjibg8Of4bGwAGvE,3922
|
11
|
-
otf_api/models/responses/challenge_tracker_content.py,sha256=KKpSWyyg3viN0vf1Sg2zTMlMZExLe3I6wowmUPWvRCA,1423
|
12
|
-
otf_api/models/responses/challenge_tracker_detail.py,sha256=82LZ0E7YsUXDYRbaXvMAaSjbYEo_Ys4cRGAXcgMTjbA,3143
|
13
|
-
otf_api/models/responses/classes.py,sha256=czg6BFNNt0_f-NaEPXS45qmRqVFmwK-laTyONu2jb7Q,3820
|
14
|
-
otf_api/models/responses/enums.py,sha256=qPhRrU-W7SF3W9aKPpq8al1rIlG_KXuvbJNTy7jPnDk,381
|
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=STVJagQdmEl2frY7lAsTdSFjoL_7HdAOSG2mbqtUYvM,6073
|
19
|
-
otf_api/models/responses/member_membership.py,sha256=_z301T9DrdQW9vIgnx_LeZmkRhvMVhkxrn_v6DDfCUk,995
|
20
|
-
otf_api/models/responses/member_purchases.py,sha256=Gr0xAhrgNDXd5lGd2j7kwNm2_p1o3IGQDJS5LfVyebw,6116
|
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=wZudL8uORrm4SRlPyRgwOrLLBEArQE3HuF9L3BKF6MY,5108
|
25
|
-
otf_api/models/responses/studio_services.py,sha256=cnnSljjOLauWAdvbf3ujKfXkrCvBsQGCXoBTARhmIqQ,1849
|
26
|
-
otf_api/models/responses/telemetry.py,sha256=OtM3vI_KWYdWKpqMdMsav26sVVquflYl5KDHiNTWPus,2026
|
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.4.dist-info/AUTHORS.md,sha256=FcNWMxpe8KDuTq4Qau0SUXsabQwGs9TGnMp1WkXRnj8,123
|
32
|
-
otf_api-0.6.4.dist-info/LICENSE,sha256=UaPT9ynYigC3nX8n22_rC37n-qmTRKLFaHrtUwF9ktE,1071
|
33
|
-
otf_api-0.6.4.dist-info/METADATA,sha256=wwGIgTWoSZMygc-xuKWNrbDDG3ra-mai3tJ2myI7BNc,1989
|
34
|
-
otf_api-0.6.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
35
|
-
otf_api-0.6.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|