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.
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.4.dist-info → otf_api-0.7.1.dist-info}/METADATA +3 -3
  25. otf_api-0.7.1.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.4.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.4.dist-info → otf_api-0.7.1.dist-info}/AUTHORS.md +0 -0
  42. {otf_api-0.6.4.dist-info → otf_api-0.7.1.dist-info}/LICENSE +0 -0
  43. {otf_api-0.6.4.dist-info → otf_api-0.7.1.dist-info}/WHEEL +0 -0
@@ -1,9 +1,8 @@
1
1
  from datetime import datetime
2
- from typing import ClassVar
3
2
 
4
3
  from pydantic import Field
5
4
 
6
- from otf_api.models.base import OtfItemBase, OtfListBase
5
+ from otf_api.models.base import OtfItemBase
7
6
 
8
7
 
9
8
  class Location(OtfItemBase):
@@ -32,7 +31,7 @@ class StudioLocation(OtfItemBase):
32
31
  bill_to_country_id: int = Field(..., alias="billToCountryId")
33
32
  bill_to_country: str = Field(..., alias="billToCountry")
34
33
  ship_to_address: str = Field(..., alias="shipToAddress")
35
- ship_to_address2: str | None = Field(..., alias="shipToAddress2")
34
+ ship_to_address2: str | None = Field(None, alias="shipToAddress2")
36
35
  ship_to_city: str = Field(..., alias="shipToCity")
37
36
  ship_to_state: str = Field(..., alias="shipToState")
38
37
  ship_to_postal_code: str = Field(..., alias="shipToPostalCode")
@@ -40,7 +39,7 @@ class StudioLocation(OtfItemBase):
40
39
  ship_to_country_id: int = Field(..., alias="shipToCountryId")
41
40
  ship_to_country: str = Field(..., alias="shipToCountry")
42
41
  physical_address: str = Field(..., alias="physicalAddress")
43
- physical_address2: str | None = Field(..., alias="physicalAddress2")
42
+ physical_address2: str | None = Field(None, alias="physicalAddress2")
44
43
  physical_city: str = Field(..., alias="physicalCity")
45
44
  physical_state: str = Field(..., alias="physicalState")
46
45
  physical_postal_code: str = Field(..., alias="physicalPostalCode")
@@ -57,30 +56,30 @@ class FavoriteStudio(OtfItemBase):
57
56
  studio_uuid: str = Field(..., alias="studioUUId")
58
57
  mbo_studio_id: int = Field(..., alias="mboStudioId")
59
58
  studio_name: str = Field(..., alias="studioName")
60
- area_id: int | None = Field(..., alias="areaId")
61
- market_id: int | None = Field(..., alias="marketId")
62
- state_id: int | None = Field(..., alias="stateId")
59
+ area_id: int | None = Field(None, alias="areaId")
60
+ market_id: int | None = Field(None, alias="marketId")
61
+ state_id: int | None = Field(None, alias="stateId")
63
62
  studio_physical_location_id: int = Field(..., alias="studioPhysicalLocationId")
64
63
  studio_number: str = Field(..., alias="studioNumber")
65
64
  description: str | None = None
66
- studio_version: str | None = Field(..., alias="studioVersion")
65
+ studio_version: str | None = Field(None, alias="studioVersion")
67
66
  studio_token: str = Field(..., alias="studioToken")
68
67
  studio_status: str = Field(..., alias="studioStatus")
69
68
  open_date: datetime = Field(..., alias="openDate")
70
69
  studio_type_id: int = Field(..., alias="studioTypeId")
71
- pos_type_id: int | None = Field(..., alias="posTypeId")
72
- logo_url: str | None = Field(..., alias="logoUrl")
73
- page_color1: str | None = Field(..., alias="pageColor1")
74
- page_color2: str | None = Field(..., alias="pageColor2")
75
- page_color3: str | None = Field(..., alias="pageColor3")
76
- page_color4: str | None = Field(..., alias="pageColor4")
70
+ pos_type_id: int | None = Field(None, alias="posTypeId")
71
+ logo_url: str | None = Field(None, alias="logoUrl")
72
+ page_color1: str | None = Field(None, alias="pageColor1")
73
+ page_color2: str | None = Field(None, alias="pageColor2")
74
+ page_color3: str | None = Field(None, alias="pageColor3")
75
+ page_color4: str | None = Field(None, alias="pageColor4")
77
76
  accepts_visa_master_card: bool = Field(..., alias="acceptsVisaMasterCard")
78
77
  accepts_american_express: bool = Field(..., alias="acceptsAmericanExpress")
79
78
  accepts_discover: bool = Field(..., alias="acceptsDiscover")
80
79
  accepts_ach: bool = Field(..., alias="acceptsACH")
81
- sms_package_enabled: bool | None = Field(..., alias="smsPackageEnabled")
82
- allows_dashboard_access: bool | None = Field(..., alias="allowsDashboardAccess")
83
- pricing_level: str | None = Field(..., alias="pricingLevel")
80
+ sms_package_enabled: bool | None = Field(None, alias="smsPackageEnabled")
81
+ allows_dashboard_access: bool | None = Field(None, alias="allowsDashboardAccess")
82
+ pricing_level: str | None = Field(None, alias="pricingLevel")
84
83
  contact_email: str = Field(..., alias="contactEmail")
85
84
  time_zone: str = Field(..., alias="timeZone")
86
85
  environment: str
@@ -95,8 +94,7 @@ class FavoriteStudio(OtfItemBase):
95
94
  studio_location: StudioLocation = Field(..., alias="studioLocation")
96
95
 
97
96
 
98
- class FavoriteStudioList(OtfListBase):
99
- collection_field: ClassVar[str] = "studios"
97
+ class FavoriteStudioList(OtfItemBase):
100
98
  studios: list[FavoriteStudio]
101
99
 
102
100
  @property
@@ -1,26 +1,8 @@
1
- from enum import Enum
2
-
3
1
  from pydantic import Field
4
2
 
5
3
  from otf_api.models.base import OtfItemBase
6
4
 
7
5
 
8
- class StatsTime(str, Enum):
9
- LastYear = "lastYear"
10
- ThisYear = "thisYear"
11
- LastMonth = "lastMonth"
12
- ThisMonth = "thisMonth"
13
- LastWeek = "lastWeek"
14
- ThisWeek = "thisWeek"
15
- AllTime = "allTime"
16
-
17
-
18
- class StatsType(str, Enum):
19
- Home = "outStudio"
20
- Studio = "inStudio"
21
- All = "allStats"
22
-
23
-
24
6
  class OutStudioMixin(OtfItemBase):
25
7
  walking_distance: float = Field(..., alias="walkingDistance")
26
8
  running_distance: float = Field(..., alias="runningDistance")
@@ -1,7 +1,6 @@
1
1
  from datetime import date, datetime
2
- from typing import Any
3
2
 
4
- from pydantic import Field
3
+ from pydantic import Field, field_validator
5
4
 
6
5
  from otf_api.models.base import OtfItemBase
7
6
 
@@ -16,12 +15,6 @@ class Address(OtfItemBase):
16
15
  postal_code: str = Field(..., alias="postalCode")
17
16
  country: str
18
17
 
19
- def __init__(self, **data):
20
- if "memberaddressUUId" in data:
21
- data["memberAddressUUId"] = data.pop("memberaddressUUId")
22
-
23
- super().__init__(**data)
24
-
25
18
 
26
19
  class MemberCreditCard(OtfItemBase):
27
20
  name_on_card: str = Field(..., alias="nameOnCard")
@@ -93,18 +86,18 @@ class MemberDetail(OtfItemBase):
93
86
  first_name: str = Field(..., alias="firstName")
94
87
  last_name: str = Field(..., alias="lastName")
95
88
  email: str
96
- profile_picture_url: str | None = Field(..., alias="profilePictureUrl")
89
+ profile_picture_url: str | None = Field(None, alias="profilePictureUrl")
97
90
  alternate_emails: None = Field(..., alias="alternateEmails")
98
- address_line1: str | None = Field(..., alias="addressLine1")
99
- address_line2: str | None = Field(..., alias="addressLine2")
91
+ address_line1: str | None = Field(None, alias="addressLine1")
92
+ address_line2: str | None = Field(None, alias="addressLine2")
100
93
  city: str | None
101
94
  state: str | None
102
- postal_code: str | None = Field(..., alias="postalCode")
95
+ postal_code: str | None = Field(None, alias="postalCode")
103
96
  phone_number: str = Field(..., alias="phoneNumber")
104
- home_phone: str | None = Field(..., alias="homePhone")
105
- work_phone: str | None = Field(..., alias="workPhone")
97
+ home_phone: str | None = Field(None, alias="homePhone")
98
+ work_phone: str | None = Field(None, alias="workPhone")
106
99
  phone_type: None = Field(..., alias="phoneType")
107
- birth_day: date | str = Field(..., alias="birthDay")
100
+ birth_day: date = Field(..., alias="birthDay")
108
101
  cc_last4: str = Field(..., alias="ccLast4")
109
102
  cc_type: str = Field(..., alias="ccType")
110
103
  gender: str
@@ -133,7 +126,11 @@ class MemberDetail(OtfItemBase):
133
126
  otf_acs_id: str = Field(..., alias="otfAcsId")
134
127
  member_class_summary: MemberClassSummary | None = Field(None, alias="memberClassSummary")
135
128
 
136
- def __init__(self, **data: Any):
137
- super().__init__(**data)
138
- if self.birth_day and isinstance(self.birth_day, str):
139
- self.birth_day = datetime.strptime(self.birth_day, "%Y-%m-%d").date() # noqa
129
+ @field_validator("birth_day")
130
+ @classmethod
131
+ def validate_birth_day(cls, value: date | str | None, **_kwargs) -> date | None:
132
+ if value is None:
133
+ return value
134
+ if not isinstance(value, date):
135
+ return datetime.strptime(value, "%Y-%m-%d").date() # noqa
136
+ return value
@@ -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, OtfListBase
5
+ from otf_api.models.base import OtfItemBase
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: str | None = Field(..., alias="shipToAddress2")
47
+ ship_to_address2: str | None = Field(None, 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: str | None = Field(..., alias="physicalAddress2")
55
+ physical_address2: str | None = Field(None, 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")
@@ -118,18 +118,18 @@ class MemberPurchase(OtfItemBase):
118
118
  member_purchase_date_time: datetime = Field(..., alias="memberPurchaseDateTime")
119
119
  member_purchase_type: str = Field(..., alias="memberPurchaseType")
120
120
  status: str
121
- member_service_id: int | None = Field(..., alias="memberServiceId")
122
- member_membership_id: int | None = Field(..., alias="memberMembershipId")
123
- member_fee_id: int | None = Field(..., alias="memberFeeId")
124
- pos_contract_id: int | None = Field(..., alias="posContractId")
121
+ member_service_id: int | None = Field(None, alias="memberServiceId")
122
+ member_membership_id: int | None = Field(None, alias="memberMembershipId")
123
+ member_fee_id: int | None = Field(None, alias="memberFeeId")
124
+ pos_contract_id: int | None = Field(None, alias="posContractId")
125
125
  pos_product_id: int = Field(..., alias="posProductId")
126
- pos_description_id: int | None = Field(..., alias="posDescriptionId")
127
- pos_pmt_ref_no: int | None = Field(..., alias="posPmtRefNo")
126
+ pos_description_id: int | None = Field(None, alias="posDescriptionId")
127
+ pos_pmt_ref_no: int | None = Field(None, alias="posPmtRefNo")
128
128
  pos_sale_id: int = Field(..., alias="posSaleId")
129
129
  quantity: int
130
130
  member_id: int = Field(..., alias="memberId")
131
131
  studio: Studio
132
132
 
133
133
 
134
- class MemberPurchaseList(OtfListBase):
134
+ class MemberPurchaseList(OtfItemBase):
135
135
  data: list[MemberPurchase]
@@ -0,0 +1,44 @@
1
+ from datetime import datetime
2
+
3
+ from humanize import precisedelta
4
+
5
+ from otf_api.models.enums import ClassType
6
+
7
+
8
+ class OtfClassTimeMixin:
9
+ starts_at_local: datetime
10
+ ends_at_local: datetime
11
+ name: str
12
+
13
+ @property
14
+ def day_of_week(self) -> str:
15
+ return self.starts_at_local.strftime("%A")
16
+
17
+ @property
18
+ def date(self) -> str:
19
+ return self.starts_at_local.strftime("%Y-%m-%d")
20
+
21
+ @property
22
+ def time(self) -> str:
23
+ """Returns time in 12 hour clock format, with no leading 0"""
24
+ val = self.starts_at_local.strftime("%I:%M %p")
25
+ if val[0] == "0":
26
+ val = " " + val[1:]
27
+
28
+ return val
29
+
30
+ @property
31
+ def duration(self) -> str:
32
+ duration = self.ends_at_local - self.starts_at_local
33
+ human_val: str = precisedelta(duration, minimum_unit="minutes")
34
+ if human_val == "1 hour and 30 minutes":
35
+ return "90 minutes"
36
+ return human_val
37
+
38
+ @property
39
+ def class_type(self) -> ClassType:
40
+ for class_type in ClassType:
41
+ if class_type.value in self.name:
42
+ return class_type
43
+
44
+ return ClassType.OTHER
@@ -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, OtfListBase
5
+ from otf_api.models.base import OtfItemBase
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(OtfListBase):
41
- data: list[OutOfStudioWorkoutHistory]
40
+ class OutOfStudioWorkoutHistoryList(OtfItemBase):
41
+ workouts: list[OutOfStudioWorkoutHistory]
@@ -1,8 +1,6 @@
1
- from typing import ClassVar
2
-
3
1
  from pydantic import Field
4
2
 
5
- from otf_api.models.base import OtfItemBase, OtfListBase
3
+ from otf_api.models.base import OtfItemBase
6
4
 
7
5
 
8
6
  class ZoneTimeMinutes(OtfItemBase):
@@ -66,6 +64,5 @@ class PerformanceSummaryEntry(OtfItemBase):
66
64
  ratings: Ratings | None = None
67
65
 
68
66
 
69
- class PerformanceSummaryList(OtfListBase):
70
- collection_field: ClassVar[str] = "summaries"
67
+ class PerformanceSummaryList(OtfItemBase):
71
68
  summaries: list[PerformanceSummaryEntry]
@@ -0,0 +1,109 @@
1
+ from datetime import datetime
2
+
3
+ from pydantic import Field
4
+
5
+ from otf_api.models.base import OtfItemBase
6
+
7
+
8
+ class Country(OtfItemBase):
9
+ country_id: int = Field(..., alias="countryId")
10
+ country_currency_code: str | None = Field(None, alias="countryCurrencyCode")
11
+ country_currency_name: str | None = Field(None, alias="countryCurrencyName")
12
+ currency_alphabetic_code: str | None = Field(None, alias="currencyAlphabeticCode")
13
+
14
+
15
+ class StudioLocation(OtfItemBase):
16
+ physical_address: str | None = Field(None, alias="physicalAddress")
17
+ physical_address2: str | None = Field(None, alias="physicalAddress2")
18
+ physical_city: str | None = Field(None, alias="physicalCity")
19
+ physical_state: str | None = Field(None, alias="physicalState")
20
+ physical_postal_code: str | None = Field(None, alias="physicalPostalCode")
21
+ physical_region: str | None = Field(None, alias="physicalRegion", exclude=True)
22
+ physical_country: str | None = Field(None, alias="physicalCountry", exclude=True)
23
+ country: Country | None = Field(None, exclude=True)
24
+ phone_number: str | None = Field(None, alias="phoneNumber")
25
+ latitude: float | None = Field(None, exclude=True)
26
+ longitude: float | None = Field(None, exclude=True)
27
+
28
+
29
+ class Language(OtfItemBase):
30
+ language_id: None = Field(None, alias="languageId")
31
+ language_code: None = Field(None, alias="languageCode")
32
+ language_name: None = Field(None, alias="languageName")
33
+
34
+
35
+ class StudioLocationLocalized(OtfItemBase):
36
+ language: Language | None = Field(None, exclude=True)
37
+ studio_name: str | None = Field(None, alias="studioName")
38
+ studio_address: str | None = Field(None, alias="studioAddress")
39
+
40
+
41
+ class StudioProfiles(OtfItemBase):
42
+ is_web: bool | None = Field(None, alias="isWeb")
43
+ intro_capacity: int | None = Field(None, alias="introCapacity")
44
+ is_crm: bool | None = Field(None, alias="isCrm")
45
+
46
+
47
+ class SocialMediaLink(OtfItemBase):
48
+ id: str
49
+ language_id: str | None = Field(None, alias="languageId")
50
+ name: str
51
+ value: str
52
+
53
+
54
+ class StudioDetail(OtfItemBase):
55
+ studio_id: int = Field(..., alias="studioId", exclude=True)
56
+ studio_uuid: str = Field(..., alias="studioUUId")
57
+ studio_location_localized: StudioLocationLocalized | None = Field(
58
+ None, alias="studioLocationLocalized", exclude=True
59
+ )
60
+ studio_location: StudioLocation | None = Field(None, alias="studioLocation")
61
+ studio_name: str | None = Field(None, alias="studioName")
62
+ studio_number: str | None = Field(None, alias="studioNumber", exclude=True)
63
+ studio_physical_location_id: int | None = Field(None, alias="studioPhysicalLocationId", exclude=True)
64
+ studio_profiles: StudioProfiles | None = Field(None, alias="studioProfiles", exclude=True)
65
+ studio_status: str | None = Field(None, alias="studioStatus", exclude=True)
66
+ studio_token: str | None = Field(None, alias="studioToken", exclude=True)
67
+ studio_type_id: int | None = Field(None, alias="studioTypeId", exclude=True)
68
+ studio_version: str | None = Field(None, alias="studioVersion", exclude=True)
69
+ mbo_studio_id: int | None = Field(None, alias="mboStudioId", exclude=True)
70
+ accepts_ach: bool | None = Field(None, alias="acceptsAch", exclude=True)
71
+ accepts_american_express: bool | None = Field(None, alias="acceptsAmericanExpress", exclude=True)
72
+ accepts_discover: bool | None = Field(None, alias="acceptsDiscover", exclude=True)
73
+ accepts_visa_master_card: bool | None = Field(None, alias="acceptsVisaMasterCard", exclude=True)
74
+ allows_cr_waitlist: bool | None = Field(None, alias="allowsCrWaitlist", exclude=True)
75
+ allows_dashboard_access: bool | None = Field(None, alias="allowsDashboardAccess", exclude=True)
76
+ area_id: int | None = Field(None, alias="areaId", exclude=True)
77
+ commission_percent: int | None = Field(None, alias="commissionPercent", exclude=True)
78
+ contact_email: str | None = Field(None, alias="contactEmail", exclude=True)
79
+ cr_waitlist_flag_last_updated: datetime | None = Field(None, alias="crWaitlistFlagLastUpdated", exclude=True)
80
+ description: str | None = Field(None, exclude=True)
81
+ distance: float | None = Field(None, exclude=True)
82
+ environment: str | None = Field(None, exclude=True)
83
+ is_integrated: bool | None = Field(None, alias="isIntegrated", exclude=True)
84
+ is_mobile: bool | None = Field(None, alias="isMobile", exclude=True)
85
+ is_otbeat: bool | None = Field(None, alias="isOtbeat", exclude=True)
86
+ logo_url: str | None = Field(None, alias="logoUrl", exclude=True)
87
+ market_id: int | None = Field(None, alias="marketId", exclude=True)
88
+ marketing_fund_rate: int | None = Field(None, alias="marketingFundRate", exclude=True)
89
+ open_date: datetime | None = Field(None, alias="openDate", exclude=True)
90
+ pos_type_id: int | None = Field(None, alias="posTypeId", exclude=True)
91
+ pricing_level: str | None = Field(None, alias="pricingLevel", exclude=True)
92
+ re_open_date: datetime | None = Field(None, alias="reOpenDate", exclude=True)
93
+ royalty_rate: int | None = Field(None, alias="royaltyRate", exclude=True)
94
+ sms_package_enabled: bool | None = Field(None, alias="smsPackageEnabled", exclude=True)
95
+ social_media_links: list[SocialMediaLink] | None = Field(None, alias="socialMediaLinks", exclude=True)
96
+ state_id: int | None = Field(None, alias="stateId", exclude=True)
97
+ tax_rate: str | None = Field(None, alias="taxRate", exclude=True)
98
+ time_zone: str | None = Field(None, alias="timeZone", exclude=True)
99
+
100
+
101
+ class Pagination(OtfItemBase):
102
+ page_index: int | None = Field(None, alias="pageIndex")
103
+ page_size: int | None = Field(None, alias="pageSize")
104
+ total_count: int | None = Field(None, alias="totalCount")
105
+ total_pages: int | None = Field(None, alias="totalPages")
106
+
107
+
108
+ class StudioDetailList(OtfItemBase):
109
+ 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, OtfListBase
5
+ from otf_api.models.base import OtfItemBase
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(OtfListBase):
56
+ class StudioServiceList(OtfItemBase):
57
57
  data: list[StudioService]
@@ -28,7 +28,7 @@ class TreadData(OtfItemBase):
28
28
  class RowData(OtfItemBase):
29
29
  row_speed: float = Field(..., alias="rowSpeed")
30
30
  row_pps: float = Field(..., alias="rowPps")
31
- row_Spm: float = Field(..., alias="rowSpm")
31
+ row_spm: float = Field(..., alias="rowSpm")
32
32
  agg_row_distance: int = Field(..., alias="aggRowDistance")
33
33
  row_pace: int = Field(..., alias="rowPace")
34
34
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: otf-api
3
- Version: 0.6.4
3
+ Version: 0.7.1
4
4
  Summary: Python OrangeTheory Fitness API Client
5
5
  License: MIT
6
6
  Author: Jessica Smith
@@ -21,8 +21,6 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
21
  Requires-Dist: aiohttp (==3.10.*)
22
22
  Requires-Dist: humanize (>=4.9.0,<5.0.0)
23
23
  Requires-Dist: inflection (==0.5.*)
24
- Requires-Dist: loguru (==0.7.2)
25
- Requires-Dist: pendulum (>=3.0.0,<4.0.0)
26
24
  Requires-Dist: pint (==0.24.*)
27
25
  Requires-Dist: pycognito (==2024.5.1)
28
26
  Requires-Dist: pydantic (==2.7.3)
@@ -31,6 +29,8 @@ Description-Content-Type: text/markdown
31
29
 
32
30
  Simple API client for interacting with the OrangeTheory Fitness APIs.
33
31
 
32
+ Review the [documentation](https://otf-api.readthedocs.io/en/stable/).
33
+
34
34
 
35
35
  This library allows access to the OrangeTheory API to retrieve workouts and performance data, class schedules, studio information, and bookings.
36
36
 
@@ -0,0 +1,36 @@
1
+ otf_api/__init__.py,sha256=F-8LCsLePnnHuimm50SvzHn4Ezpa13NKklIrkusrM0Y,101
2
+ otf_api/api.py,sha256=J7kQUtTRq3RnurGReuS2e4oroKGtscHWgCIoHAPdaww,33939
3
+ otf_api/auth.py,sha256=HwFFDSWiUMri2guuR_e5mJktvyyIUpulXIrCSHm0Fzc,10295
4
+ otf_api/exceptions.py,sha256=Nx9k7RFEJpS_BA92T2LEyJtx9Q5wFfP-QB032p61nDc,407
5
+ otf_api/models/__init__.py,sha256=mPfArX4y-P5PD59phrPSWho4eX45rDtGWyjy6jntnzs,1965
6
+ otf_api/models/base.py,sha256=KJlIxl_sRj6f-g5vKYPw4yV6fGDk-fwZ93EO0JGPYMw,202
7
+ otf_api/models/body_composition_list.py,sha256=dOIGnHN85qFHRrZ5m3Nk-8NpGRYjPyEg5E0V-mkAtNI,11672
8
+ otf_api/models/book_class.py,sha256=x-1scD1rxhDiDe9sc_bznCFSD87SXFMkNwq3mvfIuN4,4648
9
+ otf_api/models/bookings.py,sha256=lC5xv7ENN_QZ3vHqigkVL-yixOrndJgt73JYeKbFdh4,5632
10
+ otf_api/models/cancel_booking.py,sha256=yvITOaWKi8YDmuCfcQolt2f8F4vmSXAHRZct7b7GYpA,2328
11
+ otf_api/models/challenge_tracker_content.py,sha256=KKpSWyyg3viN0vf1Sg2zTMlMZExLe3I6wowmUPWvRCA,1423
12
+ otf_api/models/challenge_tracker_detail.py,sha256=dcd_2DCFPAOwE6Vpwk_uInyFSKDjbA0hsZYicVN9YQY,3122
13
+ otf_api/models/classes.py,sha256=OrIVFwT4R5QiTA0jpx56rCVdDhg4NsfsVCrWxPPEyxs,1959
14
+ otf_api/models/enums.py,sha256=EC8Ls3QCbP1DjkNwR2JfQVhSPVeG-Z8Lfh_0bFGJfno,2127
15
+ otf_api/models/favorite_studios.py,sha256=fLrZ_sonAlQsGT6TDyH6Z9TC0nbhMEvOu33hGkE8Puk,4997
16
+ otf_api/models/latest_agreement.py,sha256=aE8hbWE4Pgguw4Itah7a1SqwOLpJ6t9oODFwLQ8Wzo0,774
17
+ otf_api/models/lifetime_stats.py,sha256=X7oeqGwvvchNRcqGogfGG4aCudaVmAnfBlP5bi89KHE,3052
18
+ otf_api/models/member_detail.py,sha256=cWaynlqpF5wwvotvfIwzJUKyTIz3ppYBMRlPNyDdoV8,5986
19
+ otf_api/models/member_membership.py,sha256=_z301T9DrdQW9vIgnx_LeZmkRhvMVhkxrn_v6DDfCUk,995
20
+ otf_api/models/member_purchases.py,sha256=9QrGqDYX8mbPdTOswIJcDWYzmHjc-qsVRyQENE_RS8U,6111
21
+ otf_api/models/mixins.py,sha256=PFhzq0zZTN0wbBqEsCUWkO89EOskTPzyoDqtuvUIjTA,1141
22
+ otf_api/models/out_of_studio_workout_history.py,sha256=q9E1LfNHd9-SQ_ZQUG46abDDoMbDPW_XDSS8DGxtDnY,1713
23
+ otf_api/models/performance_summary_detail.py,sha256=U7GbVet_klwv7Joc8DiBJw4tjb3OmjoT19KGxorrNYo,1637
24
+ otf_api/models/performance_summary_list.py,sha256=z1W1b7rOZ9HESgRL9P_krd7MSGaMASxCVr3EpYOLBvE,1262
25
+ otf_api/models/studio_detail.py,sha256=Yk_OiBbGzUmTaTSVi6PdXbbu2QfMcaNpk2QCEVS5v-k,5823
26
+ otf_api/models/studio_services.py,sha256=mFDClPtU0HCk5fb19gjGKpt2F8n8kto7sj1pE_l4RdQ,1836
27
+ otf_api/models/telemetry.py,sha256=-BeX1wDcysiwn9Vqf2nanjGoB3n6YhdAEwZY6VGW6vE,2026
28
+ otf_api/models/telemetry_hr_history.py,sha256=vDcLb4wTHVBw8O0mGblUujHfJegkflOCWW-bnTXNCI0,763
29
+ otf_api/models/telemetry_max_hr.py,sha256=xKxH0fIlOqFyZv8UW98XsxF-GMoIs9gnCTAbu88ZQtg,266
30
+ otf_api/models/total_classes.py,sha256=WrKkWbq0eK8J0RC4qhZ5kmXnv_ZTDbyzsoRm7XKGlss,288
31
+ otf_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ otf_api-0.7.1.dist-info/AUTHORS.md,sha256=FcNWMxpe8KDuTq4Qau0SUXsabQwGs9TGnMp1WkXRnj8,123
33
+ otf_api-0.7.1.dist-info/LICENSE,sha256=UaPT9ynYigC3nX8n22_rC37n-qmTRKLFaHrtUwF9ktE,1071
34
+ otf_api-0.7.1.dist-info/METADATA,sha256=X_BbDrQ066A9EnO40Y4hmfGu4yvEg-rRHR7abnyRiTU,1988
35
+ otf_api-0.7.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
+ otf_api-0.7.1.dist-info/RECORD,,
@@ -1,57 +0,0 @@
1
- from .body_composition_list import BodyCompositionList
2
- from .book_class import BookClass
3
- from .bookings import BookingList, BookingStatus
4
- from .cancel_booking import CancelBooking
5
- from .challenge_tracker_content import ChallengeTrackerContent
6
- from .challenge_tracker_detail import ChallengeTrackerDetailList
7
- from .classes import ClassType, DoW, OtfClassList
8
- from .enums import ChallengeType, EquipmentType
9
- from .favorite_studios import FavoriteStudioList
10
- from .latest_agreement import LatestAgreement
11
- from .lifetime_stats import StatsResponse, StatsTime
12
- from .member_detail import MemberDetail
13
- from .member_membership import MemberMembership
14
- from .member_purchases import MemberPurchaseList
15
- from .out_of_studio_workout_history import OutOfStudioWorkoutHistoryList
16
- from .performance_summary_detail import PerformanceSummaryDetail
17
- from .performance_summary_list import PerformanceSummaryList
18
- from .studio_detail import Pagination, StudioDetail, StudioDetailList
19
- from .studio_services import StudioServiceList
20
- from .telemetry import Telemetry
21
- from .telemetry_hr_history import TelemetryHrHistory
22
- from .telemetry_max_hr import TelemetryMaxHr
23
- from .total_classes import TotalClasses
24
-
25
- __all__ = [
26
- "BodyCompositionList",
27
- "BookClass",
28
- "BookingList",
29
- "BookingStatus",
30
- "CancelBooking",
31
- "ChallengeTrackerContent",
32
- "ChallengeTrackerDetailList",
33
- "ChallengeType",
34
- "ClassType",
35
- "DoW",
36
- "EquipmentType",
37
- "FavoriteStudioList",
38
- "LatestAgreement",
39
- "MemberDetail",
40
- "MemberMembership",
41
- "MemberPurchaseList",
42
- "OtfClassList",
43
- "OutOfStudioWorkoutHistoryList",
44
- "Pagination",
45
- "PerformanceSummaryDetail",
46
- "PerformanceSummaryList",
47
- "StatsResponse",
48
- "StatsTime",
49
- "StudioDetail",
50
- "StudioDetailList",
51
- "StudioServiceList",
52
- "StudioStatus",
53
- "Telemetry",
54
- "TelemetryHrHistory",
55
- "TelemetryMaxHr",
56
- "TotalClasses",
57
- ]