otf-api 0.6.3__py3-none-any.whl → 0.7.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.
Files changed (43) hide show
  1. otf_api/__init__.py +1 -9
  2. otf_api/api.py +76 -111
  3. otf_api/auth.py +11 -10
  4. otf_api/exceptions.py +18 -0
  5. otf_api/models/__init__.py +25 -32
  6. otf_api/models/base.py +1 -16
  7. otf_api/models/{responses/body_composition_list.py → body_composition_list.py} +3 -14
  8. otf_api/models/book_class.py +89 -0
  9. otf_api/models/bookings.py +119 -0
  10. otf_api/models/cancel_booking.py +49 -0
  11. otf_api/models/{responses/challenge_tracker_detail.py → challenge_tracker_detail.py} +12 -13
  12. otf_api/models/classes.py +80 -0
  13. otf_api/models/enums.py +87 -0
  14. otf_api/models/{responses/favorite_studios.py → favorite_studios.py} +17 -19
  15. otf_api/models/{responses/lifetime_stats.py → lifetime_stats.py} +0 -18
  16. otf_api/models/{responses/member_detail.py → member_detail.py} +16 -19
  17. otf_api/models/{responses/member_purchases.py → member_purchases.py} +10 -10
  18. otf_api/models/mixins.py +44 -0
  19. otf_api/models/{responses/out_of_studio_workout_history.py → out_of_studio_workout_history.py} +3 -3
  20. otf_api/models/{responses/performance_summary_list.py → performance_summary_list.py} +2 -5
  21. otf_api/models/studio_detail.py +109 -0
  22. otf_api/models/{responses/studio_services.py → studio_services.py} +2 -2
  23. otf_api/models/{responses/telemetry.py → telemetry.py} +1 -1
  24. {otf_api-0.6.3.dist-info → otf_api-0.7.0.dist-info}/METADATA +3 -3
  25. otf_api-0.7.0.dist-info/RECORD +36 -0
  26. otf_api/models/responses/__init__.py +0 -57
  27. otf_api/models/responses/book_class.py +0 -407
  28. otf_api/models/responses/bookings.py +0 -160
  29. otf_api/models/responses/cancel_booking.py +0 -95
  30. otf_api/models/responses/classes.py +0 -148
  31. otf_api/models/responses/enums.py +0 -23
  32. otf_api/models/responses/studio_detail.py +0 -113
  33. otf_api-0.6.3.dist-info/RECORD +0 -35
  34. /otf_api/models/{responses/challenge_tracker_content.py → challenge_tracker_content.py} +0 -0
  35. /otf_api/models/{responses/latest_agreement.py → latest_agreement.py} +0 -0
  36. /otf_api/models/{responses/member_membership.py → member_membership.py} +0 -0
  37. /otf_api/models/{responses/performance_summary_detail.py → performance_summary_detail.py} +0 -0
  38. /otf_api/models/{responses/telemetry_hr_history.py → telemetry_hr_history.py} +0 -0
  39. /otf_api/models/{responses/telemetry_max_hr.py → telemetry_max_hr.py} +0 -0
  40. /otf_api/models/{responses/total_classes.py → total_classes.py} +0 -0
  41. {otf_api-0.6.3.dist-info → otf_api-0.7.0.dist-info}/AUTHORS.md +0 -0
  42. {otf_api-0.6.3.dist-info → otf_api-0.7.0.dist-info}/LICENSE +0 -0
  43. {otf_api-0.6.3.dist-info → otf_api-0.7.0.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]
@@ -1,35 +0,0 @@
1
- otf_api/__init__.py,sha256=xlcXajeJBiY-8MCb6UtskDB9HokjGj9q1Bj2brTKYNI,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=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.3.dist-info/AUTHORS.md,sha256=FcNWMxpe8KDuTq4Qau0SUXsabQwGs9TGnMp1WkXRnj8,123
32
- otf_api-0.6.3.dist-info/LICENSE,sha256=UaPT9ynYigC3nX8n22_rC37n-qmTRKLFaHrtUwF9ktE,1071
33
- otf_api-0.6.3.dist-info/METADATA,sha256=StPDL8jXbUNc29F4-pOob_TpzCzTkPfmzjdUkSySUJM,1989
34
- otf_api-0.6.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
35
- otf_api-0.6.3.dist-info/RECORD,,