otf-api 0.8.2__py3-none-any.whl → 0.9.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 +7 -4
- otf_api/api.py +699 -480
- otf_api/auth/__init__.py +4 -0
- otf_api/auth/auth.py +234 -0
- otf_api/auth/user.py +66 -0
- otf_api/auth/utils.py +129 -0
- otf_api/exceptions.py +38 -5
- otf_api/filters.py +97 -0
- otf_api/logging.py +19 -0
- otf_api/models/__init__.py +27 -38
- otf_api/models/body_composition_list.py +47 -50
- otf_api/models/bookings.py +63 -87
- otf_api/models/challenge_tracker_content.py +42 -21
- otf_api/models/challenge_tracker_detail.py +68 -48
- otf_api/models/classes.py +53 -62
- otf_api/models/enums.py +108 -30
- otf_api/models/lifetime_stats.py +59 -45
- otf_api/models/member_detail.py +95 -115
- otf_api/models/member_membership.py +18 -17
- otf_api/models/member_purchases.py +21 -127
- otf_api/models/mixins.py +37 -33
- otf_api/models/notifications.py +17 -0
- otf_api/models/out_of_studio_workout_history.py +22 -31
- otf_api/models/performance_summary_detail.py +47 -42
- otf_api/models/performance_summary_list.py +19 -37
- otf_api/models/studio_detail.py +51 -98
- otf_api/models/studio_services.py +27 -48
- otf_api/models/telemetry.py +14 -5
- otf_api/utils.py +134 -0
- {otf_api-0.8.2.dist-info → otf_api-0.9.1.dist-info}/METADATA +21 -10
- otf_api-0.9.1.dist-info/RECORD +35 -0
- {otf_api-0.8.2.dist-info → otf_api-0.9.1.dist-info}/WHEEL +1 -1
- otf_api/auth.py +0 -316
- otf_api/models/book_class.py +0 -89
- otf_api/models/cancel_booking.py +0 -49
- otf_api/models/favorite_studios.py +0 -106
- otf_api/models/latest_agreement.py +0 -21
- otf_api/models/telemetry_hr_history.py +0 -34
- otf_api/models/telemetry_max_hr.py +0 -13
- otf_api/models/total_classes.py +0 -8
- otf_api-0.8.2.dist-info/AUTHORS.md +0 -9
- otf_api-0.8.2.dist-info/RECORD +0 -36
- {otf_api-0.8.2.dist-info → otf_api-0.9.1.dist-info}/LICENSE +0 -0
otf_api/models/member_detail.py
CHANGED
@@ -1,135 +1,115 @@
|
|
1
1
|
from datetime import date, datetime
|
2
|
-
from typing import Any
|
3
2
|
|
4
3
|
from pydantic import Field, field_validator
|
5
4
|
|
6
5
|
from otf_api.models.base import OtfItemBase
|
6
|
+
from otf_api.models.mixins import AddressMixin
|
7
|
+
from otf_api.models.studio_detail import StudioDetail
|
7
8
|
|
8
9
|
|
9
|
-
class Address(
|
10
|
-
member_address_uuid: str | None = Field(None, alias="memberAddressUUId")
|
11
|
-
type: str
|
12
|
-
address1: str
|
13
|
-
address2: str | None = None
|
14
|
-
suburb: str | None = None
|
15
|
-
territory: str
|
16
|
-
postal_code: str = Field(..., alias="postalCode")
|
17
|
-
country: str
|
18
|
-
|
19
|
-
|
20
|
-
class MemberCreditCard(OtfItemBase):
|
21
|
-
name_on_card: str = Field(..., alias="nameOnCard")
|
22
|
-
cc_type: str = Field(..., alias="ccType")
|
23
|
-
cc_last4: str = Field(..., alias="ccLast4")
|
24
|
-
|
25
|
-
|
26
|
-
class PhysicalCountryDetails(OtfItemBase):
|
27
|
-
country_code: str = Field(..., alias="countryCode")
|
28
|
-
description: str
|
29
|
-
|
30
|
-
|
31
|
-
class StudioLocation(OtfItemBase):
|
32
|
-
physical_country_id: int = Field(..., alias="physicalCountryId")
|
33
|
-
physical_country_details: PhysicalCountryDetails = Field(..., alias="physicalCountryDetails")
|
34
|
-
|
35
|
-
|
36
|
-
class StudioPartner(OtfItemBase):
|
37
|
-
studio_acs_id: str = Field(..., alias="studioAcsId")
|
38
|
-
|
39
|
-
|
40
|
-
class HomeStudio(OtfItemBase):
|
41
|
-
studio_id: int = Field(..., alias="studioId")
|
42
|
-
studio_uuid: str = Field(..., alias="studioUUId")
|
43
|
-
studio_name: str = Field(..., alias="studioName")
|
44
|
-
studio_number: str = Field(..., alias="studioNumber")
|
45
|
-
mbo_studio_id: int = Field(..., alias="mboStudioId")
|
46
|
-
time_zone: str = Field(..., alias="timeZone")
|
47
|
-
is_integrated: bool = Field(..., alias="isIntegrated")
|
48
|
-
studio_status: str = Field(..., alias="studioStatus")
|
49
|
-
studio_location: StudioLocation = Field(..., alias="studioLocation")
|
50
|
-
studio_partner: StudioPartner = Field(..., alias="studioPartner")
|
10
|
+
class Address(AddressMixin):
|
11
|
+
member_address_uuid: str | None = Field(None, alias="memberAddressUUId", exclude=True, repr=False)
|
12
|
+
type: str | None = None
|
51
13
|
|
52
14
|
|
53
15
|
class MemberProfile(OtfItemBase):
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
automated_hr: int = Field(..., alias="automatedHr")
|
60
|
-
member_optin_flow_type_id: int = Field(..., alias="memberOptinFlowTypeId")
|
16
|
+
unit_of_measure: str | None = Field(None, alias="unitOfMeasure")
|
17
|
+
max_hr_type: str | None = Field(None, alias="maxHrType")
|
18
|
+
manual_max_hr: int | None = Field(None, alias="manualMaxHr")
|
19
|
+
formula_max_hr: int | None = Field(None, alias="formulaMaxHr")
|
20
|
+
automated_hr: int | None = Field(None, alias="automatedHr")
|
61
21
|
|
22
|
+
member_profile_uuid: str | None = Field(None, alias="memberProfileUUId", exclude=True, repr=False)
|
23
|
+
member_optin_flow_type_id: int | None = Field(None, alias="memberOptinFlowTypeId", exclude=True, repr=False)
|
62
24
|
|
63
|
-
class MemberClassSummary(OtfItemBase):
|
64
|
-
total_classes_booked: int = Field(..., alias="totalClassesBooked")
|
65
|
-
total_classes_attended: int = Field(..., alias="totalClassesAttended")
|
66
|
-
total_intro: int = Field(..., alias="totalIntro")
|
67
|
-
total_ot_live_classes_booked: int = Field(..., alias="totalOTLiveClassesBooked")
|
68
|
-
total_ot_live_classes_attended: int = Field(..., alias="totalOTLiveClassesAttended")
|
69
|
-
total_classes_used_hrm: int = Field(..., alias="totalClassesUsedHRM")
|
70
|
-
total_studios_visited: int = Field(..., alias="totalStudiosVisited")
|
71
|
-
first_visit_date: datetime = Field(..., alias="firstVisitDate")
|
72
|
-
last_class_visited_date: datetime = Field(..., alias="lastClassVisitedDate")
|
73
|
-
last_class_booked_date: datetime = Field(..., alias="lastClassBookedDate")
|
74
|
-
last_class_studio_visited: int = Field(..., alias="lastClassStudioVisited")
|
75
25
|
|
26
|
+
class MemberClassSummary(OtfItemBase):
|
27
|
+
total_classes_booked: int | None = Field(None, alias="totalClassesBooked")
|
28
|
+
total_classes_attended: int | None = Field(None, alias="totalClassesAttended")
|
29
|
+
total_intro_classes: int | None = Field(None, alias="totalIntro")
|
30
|
+
total_ot_live_classes_booked: int | None = Field(None, alias="totalOTLiveClassesBooked")
|
31
|
+
total_ot_live_classes_attended: int | None = Field(None, alias="totalOTLiveClassesAttended")
|
32
|
+
total_classes_used_hrm: int | None = Field(None, alias="totalClassesUsedHRM")
|
33
|
+
total_studios_visited: int | None = Field(None, alias="totalStudiosVisited")
|
34
|
+
first_visit_date: date | None = Field(None, alias="firstVisitDate")
|
35
|
+
last_class_visited_date: date | None = Field(None, alias="lastClassVisitedDate")
|
36
|
+
last_class_booked_date: date | None = Field(None, alias="lastClassBookedDate")
|
76
37
|
|
77
|
-
|
78
|
-
member_referrer_uuid: str = Field(..., alias="memberReferrerUUId")
|
38
|
+
last_class_studio_visited: int | None = Field(None, alias="lastClassStudioVisited", exclude=True, repr=False)
|
79
39
|
|
80
40
|
|
81
41
|
class MemberDetail(OtfItemBase):
|
82
|
-
member_id: int = Field(..., alias="memberId")
|
83
42
|
member_uuid: str = Field(..., alias="memberUUId")
|
84
|
-
cognito_id: str = Field(
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
43
|
+
cognito_id: str = Field(
|
44
|
+
...,
|
45
|
+
alias="cognitoId",
|
46
|
+
exclude=True,
|
47
|
+
repr=False,
|
48
|
+
description="Cognito user ID, not necessary for end users. Also on OtfUser object.",
|
49
|
+
)
|
50
|
+
|
51
|
+
home_studio: StudioDetail
|
52
|
+
profile: MemberProfile = Field(..., alias="memberProfile")
|
53
|
+
class_summary: MemberClassSummary | None = Field(None, alias="memberClassSummary")
|
54
|
+
addresses: list[Address] | None = Field(default_factory=list)
|
55
|
+
|
56
|
+
studio_display_name: str | None = Field(
|
57
|
+
None, alias="userName", description="The value that is displayed on tread/rower tablets and OTBeat screens"
|
58
|
+
)
|
59
|
+
first_name: str | None = Field(None, alias="firstName")
|
60
|
+
last_name: str | None = Field(None, alias="lastName")
|
61
|
+
email: str | None = Field(None, alias="email")
|
62
|
+
phone_number: str | None = Field(None, alias="phoneNumber")
|
63
|
+
birth_day: date | None = Field(None, alias="birthDay")
|
64
|
+
gender: str | None = Field(None, alias="gender")
|
65
|
+
locale: str | None = Field(None, alias="locale")
|
66
|
+
weight: int | None = Field(None, alias="weight")
|
67
|
+
weight_units: str | None = Field(None, alias="weightMeasure")
|
68
|
+
height: int | None = Field(None, alias="height")
|
69
|
+
height_units: str | None = Field(None, alias="heightMeasure")
|
70
|
+
|
71
|
+
# unused fields - leaving these in for now in case someone finds a purpose for them
|
72
|
+
# but they will potentially (likely?) be removed in the future
|
73
|
+
|
74
|
+
# mbo fields
|
75
|
+
mbo_id: str | None = Field(None, alias="mboId", exclude=True, repr=False, description="MindBody attr")
|
76
|
+
mbo_status: str | None = Field(None, alias="mboStatus", exclude=True, repr=False, description="MindBody attr")
|
77
|
+
mbo_studio_id: int | None = Field(None, alias="mboStudioId", exclude=True, repr=False, description="MindBody attr")
|
78
|
+
mbo_unique_id: int | None = Field(None, alias="mboUniqueId", exclude=True, repr=False, description="MindBody attr")
|
79
|
+
|
80
|
+
# ids
|
81
|
+
created_by: str | None = Field(None, alias="createdBy", exclude=True, repr=False)
|
82
|
+
home_studio_id: int | None = Field(
|
83
|
+
None, alias="homeStudioId", exclude=True, repr=False, description="Not used by API"
|
84
|
+
)
|
85
|
+
member_id: int | None = Field(None, alias="memberId", exclude=True, repr=False, description="Not used by API")
|
86
|
+
otf_acs_id: str | None = Field(None, alias="otfAcsId", exclude=True, repr=False)
|
87
|
+
updated_by: str | None = Field(None, alias="updatedBy", exclude=True, repr=False)
|
88
|
+
|
89
|
+
# unused address/member detail fields
|
90
|
+
created_date: datetime | None = Field(None, alias="createdDate", exclude=True, repr=False)
|
91
|
+
updated_date: datetime | None = Field(None, alias="updatedDate", exclude=True, repr=False)
|
92
|
+
|
93
|
+
address_line1: str | None = Field(None, alias="addressLine1", exclude=True, repr=False)
|
94
|
+
address_line2: str | None = Field(None, alias="addressLine2", exclude=True, repr=False)
|
95
|
+
alternate_emails: None = Field(None, alias="alternateEmails", exclude=True, repr=False)
|
96
|
+
cc_last4: str | None = Field(None, alias="ccLast4", exclude=True, repr=False)
|
97
|
+
cc_type: str | None = Field(None, alias="ccType", exclude=True, repr=False)
|
98
|
+
city: str | None = Field(None, exclude=True, repr=False)
|
99
|
+
home_phone: str | None = Field(None, alias="homePhone", exclude=True, repr=False)
|
100
|
+
intro_neccessary: bool | None = Field(None, alias="introNeccessary", exclude=True, repr=False)
|
101
|
+
is_deleted: bool | None = Field(None, alias="isDeleted", exclude=True, repr=False)
|
102
|
+
is_member_verified: bool | None = Field(None, alias="isMemberVerified", exclude=True, repr=False)
|
103
|
+
lead_prospect: bool | None = Field(None, alias="leadProspect", exclude=True, repr=False)
|
104
|
+
max_hr: int | None = Field(
|
105
|
+
None, alias="maxHr", exclude=True, repr=False, description="Also found in member_profile"
|
106
|
+
)
|
107
|
+
online_signup: None = Field(None, alias="onlineSignup", exclude=True, repr=False)
|
108
|
+
phone_type: None = Field(None, alias="phoneType", exclude=True, repr=False)
|
109
|
+
postal_code: str | None = Field(None, alias="postalCode", exclude=True, repr=False)
|
110
|
+
state: str | None = Field(None, exclude=True, repr=False)
|
111
|
+
work_phone: str | None = Field(None, alias="workPhone", exclude=True, repr=False)
|
112
|
+
year_imported: int | None = Field(None, alias="yearImported", exclude=True, repr=False)
|
133
113
|
|
134
114
|
@field_validator("birth_day")
|
135
115
|
@classmethod
|
@@ -137,5 +117,5 @@ class MemberDetail(OtfItemBase):
|
|
137
117
|
if value is None:
|
138
118
|
return value
|
139
119
|
if not isinstance(value, date):
|
140
|
-
return datetime.strptime(value, "%Y-%m-%d").date()
|
120
|
+
return datetime.strptime(value, "%Y-%m-%d").date()
|
141
121
|
return value
|
@@ -6,20 +6,21 @@ from otf_api.models.base import OtfItemBase
|
|
6
6
|
|
7
7
|
|
8
8
|
class MemberMembership(OtfItemBase):
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
9
|
+
payment_date: datetime | None = Field(None, alias="paymentDate")
|
10
|
+
active_date: datetime | None = Field(None, alias="activeDate")
|
11
|
+
expiration_date: datetime | None = Field(None, alias="expirationDate")
|
12
|
+
current: bool | None = None
|
13
|
+
count: int | None = None
|
14
|
+
remaining: int | None = None
|
15
|
+
name: str | None = None
|
16
|
+
updated_date: datetime | None = Field(None, alias="updatedDate")
|
17
|
+
created_date: datetime | None = Field(None, alias="createdDate")
|
18
|
+
is_deleted: bool | None = Field(None, alias="isDeleted")
|
19
|
+
|
20
|
+
member_membership_id: int | None = Field(None, alias="memberMembershipId", exclude=True, repr=False)
|
21
|
+
member_membership_uuid: str | None = Field(None, alias="memberMembershipUUId", exclude=True, repr=False)
|
22
|
+
membership_id: int | None = Field(None, alias="membershipId", exclude=True, repr=False)
|
23
|
+
member_id: int | None = Field(None, alias="memberId", exclude=True, repr=False)
|
24
|
+
mbo_description_id: str | None = Field(None, alias="mboDescriptionId", exclude=True, repr=False)
|
25
|
+
created_by: str | None = Field(None, alias="createdBy", exclude=True, repr=False)
|
26
|
+
updated_by: str | None = Field(None, alias="updatedBy", exclude=True, repr=False)
|
@@ -3,133 +3,27 @@ from datetime import datetime
|
|
3
3
|
from pydantic import Field
|
4
4
|
|
5
5
|
from otf_api.models.base import OtfItemBase
|
6
|
-
|
7
|
-
|
8
|
-
class Location(OtfItemBase):
|
9
|
-
phone: str
|
10
|
-
latitude: str
|
11
|
-
longitude: str
|
12
|
-
address1: str
|
13
|
-
address2: str | None = None
|
14
|
-
city: str
|
15
|
-
state: str
|
16
|
-
postal_code: str = Field(..., alias="postalCode")
|
17
|
-
|
18
|
-
|
19
|
-
class Currency(OtfItemBase):
|
20
|
-
currency_alphabetic_code: str = Field(..., alias="currencyAlphabeticCode")
|
21
|
-
|
22
|
-
|
23
|
-
class DefaultCurrency(OtfItemBase):
|
24
|
-
currency_id: int = Field(..., alias="currencyId")
|
25
|
-
currency: Currency
|
26
|
-
|
27
|
-
|
28
|
-
class Country(OtfItemBase):
|
29
|
-
country_id: int = Field(..., alias="countryId")
|
30
|
-
country_code: str = Field(..., alias="countryCode")
|
31
|
-
description: str
|
32
|
-
country_currency_code: str = Field(..., alias="countryCurrencyCode")
|
33
|
-
default_currency: DefaultCurrency = Field(..., alias="defaultCurrency")
|
34
|
-
|
35
|
-
|
36
|
-
class StudioLocation(OtfItemBase):
|
37
|
-
studio_location_id: int = Field(..., alias="studioLocationId")
|
38
|
-
bill_to_address: str = Field(..., alias="billToAddress")
|
39
|
-
bill_to_address2: str = Field(..., alias="billToAddress2")
|
40
|
-
bill_to_city: str = Field(..., alias="billToCity")
|
41
|
-
bill_to_state: str = Field(..., alias="billToState")
|
42
|
-
bill_to_postal_code: str = Field(..., alias="billToPostalCode")
|
43
|
-
bill_to_region: str = Field(..., alias="billToRegion")
|
44
|
-
bill_to_country_id: int = Field(..., alias="billToCountryId")
|
45
|
-
bill_to_country: str = Field(..., alias="billToCountry")
|
46
|
-
ship_to_address: str = Field(..., alias="shipToAddress")
|
47
|
-
ship_to_address2: str | None = Field(None, alias="shipToAddress2")
|
48
|
-
ship_to_city: str = Field(..., alias="shipToCity")
|
49
|
-
ship_to_state: str = Field(..., alias="shipToState")
|
50
|
-
ship_to_postal_code: str = Field(..., alias="shipToPostalCode")
|
51
|
-
ship_to_region: str = Field(..., alias="shipToRegion")
|
52
|
-
ship_to_country_id: int = Field(..., alias="shipToCountryId")
|
53
|
-
ship_to_country: str = Field(..., alias="shipToCountry")
|
54
|
-
physical_address: str = Field(..., alias="physicalAddress")
|
55
|
-
physical_address2: str | None = Field(None, alias="physicalAddress2")
|
56
|
-
physical_city: str = Field(..., alias="physicalCity")
|
57
|
-
physical_state: str = Field(..., alias="physicalState")
|
58
|
-
physical_postal_code: str = Field(..., alias="physicalPostalCode")
|
59
|
-
physical_region: str = Field(..., alias="physicalRegion")
|
60
|
-
physical_country_id: int = Field(..., alias="physicalCountryId")
|
61
|
-
physical_country: str = Field(..., alias="physicalCountry")
|
62
|
-
phone_number: str = Field(..., alias="phoneNumber")
|
63
|
-
latitude: str
|
64
|
-
longitude: str
|
65
|
-
country: Country
|
66
|
-
|
67
|
-
|
68
|
-
class Studio(OtfItemBase):
|
69
|
-
studio_id: int = Field(..., alias="studioId")
|
70
|
-
studio_uuid: str = Field(..., alias="studioUUId")
|
71
|
-
mbo_studio_id: int = Field(..., alias="mboStudioId")
|
72
|
-
studio_name: str = Field(..., alias="studioName")
|
73
|
-
area_id: int = Field(..., alias="areaId")
|
74
|
-
market_id: int = Field(..., alias="marketId")
|
75
|
-
state_id: int = Field(..., alias="stateId")
|
76
|
-
studio_physical_location_id: int = Field(..., alias="studioPhysicalLocationId")
|
77
|
-
studio_number: str = Field(..., alias="studioNumber")
|
78
|
-
description: str
|
79
|
-
studio_version: str = Field(..., alias="studioVersion")
|
80
|
-
studio_token: str = Field(..., alias="studioToken")
|
81
|
-
studio_status: str = Field(..., alias="studioStatus")
|
82
|
-
open_date: datetime = Field(..., alias="openDate")
|
83
|
-
studio_type_id: int = Field(..., alias="studioTypeId")
|
84
|
-
pos_type_id: int = Field(..., alias="posTypeId")
|
85
|
-
tax_inclusive_pricing: bool = Field(..., alias="taxInclusivePricing")
|
86
|
-
tax_rate: str = Field(..., alias="taxRate")
|
87
|
-
logo_url: str = Field(..., alias="logoUrl")
|
88
|
-
page_color1: str = Field(..., alias="pageColor1")
|
89
|
-
page_color2: str = Field(..., alias="pageColor2")
|
90
|
-
page_color3: str = Field(..., alias="pageColor3")
|
91
|
-
page_color4: str = Field(..., alias="pageColor4")
|
92
|
-
accepts_visa_master_card: bool = Field(..., alias="acceptsVisaMasterCard")
|
93
|
-
accepts_american_express: bool = Field(..., alias="acceptsAmericanExpress")
|
94
|
-
accepts_discover: bool = Field(..., alias="acceptsDiscover")
|
95
|
-
accepts_ach: bool = Field(..., alias="acceptsACH")
|
96
|
-
sms_package_enabled: bool = Field(..., alias="smsPackageEnabled")
|
97
|
-
allows_dashboard_access: bool = Field(..., alias="allowsDashboardAccess")
|
98
|
-
pricing_level: str = Field(..., alias="pricingLevel")
|
99
|
-
contact_email: str = Field(..., alias="contactEmail")
|
100
|
-
royalty_rate: str = Field(..., alias="royaltyRate")
|
101
|
-
commission_percent: str = Field(..., alias="commissionPercent")
|
102
|
-
marketing_fund_rate: str = Field(..., alias="marketingFundRate")
|
103
|
-
time_zone: str = Field(..., alias="timeZone")
|
104
|
-
environment: str
|
105
|
-
allows_cr_waitlist: bool = Field(..., alias="allowsCRWaitlist")
|
106
|
-
cr_waitlist_flag_last_updated: datetime = Field(..., alias="crWaitlistFlagLastUpdated")
|
107
|
-
is_integrated: bool = Field(..., alias="isIntegrated")
|
108
|
-
locations: list[Location]
|
109
|
-
studio_location: StudioLocation = Field(..., alias="studioLocation")
|
6
|
+
from otf_api.models.studio_detail import StudioDetail
|
110
7
|
|
111
8
|
|
112
9
|
class MemberPurchase(OtfItemBase):
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
class MemberPurchaseList(OtfItemBase):
|
135
|
-
data: list[MemberPurchase]
|
10
|
+
purchase_uuid: str = Field(..., alias="memberPurchaseUUId")
|
11
|
+
name: str | None = None
|
12
|
+
price: str | None = None
|
13
|
+
purchase_date_time: datetime | None = Field(None, alias="memberPurchaseDateTime")
|
14
|
+
purchase_type: str | None = Field(None, alias="memberPurchaseType")
|
15
|
+
status: str | None = None
|
16
|
+
quantity: int | None = None
|
17
|
+
studio: StudioDetail = Field(..., exclude=True, repr=False)
|
18
|
+
|
19
|
+
member_fee_id: int | None = Field(None, alias="memberFeeId", exclude=True, repr=False)
|
20
|
+
member_id: int | None = Field(..., alias="memberId", exclude=True, repr=False)
|
21
|
+
member_membership_id: int | None = Field(None, alias="memberMembershipId", exclude=True, repr=False)
|
22
|
+
member_purchase_id: int | None = Field(..., alias="memberPurchaseId", exclude=True, repr=False)
|
23
|
+
member_service_id: int | None = Field(None, alias="memberServiceId", exclude=True, repr=False)
|
24
|
+
pos_contract_id: int | None = Field(None, alias="posContractId", exclude=True, repr=False)
|
25
|
+
pos_description_id: int | None = Field(None, alias="posDescriptionId", exclude=True, repr=False)
|
26
|
+
pos_pmt_ref_no: int | None = Field(None, alias="posPmtRefNo", exclude=True, repr=False)
|
27
|
+
pos_product_id: int | None = Field(..., alias="posProductId", exclude=True, repr=False)
|
28
|
+
pos_sale_id: int | None = Field(..., alias="posSaleId", exclude=True, repr=False)
|
29
|
+
studio_id: int | None = Field(..., alias="studioId", exclude=True, repr=False)
|
otf_api/models/mixins.py
CHANGED
@@ -1,44 +1,48 @@
|
|
1
|
-
from
|
1
|
+
from pydantic import AliasChoices, Field, field_validator, model_validator
|
2
2
|
|
3
|
-
from
|
3
|
+
from otf_api.models.base import OtfItemBase
|
4
4
|
|
5
|
-
from otf_api.models.enums import ClassType
|
6
5
|
|
6
|
+
class PhoneLongitudeLatitudeMixin(OtfItemBase):
|
7
|
+
phone_number: str | None = Field(None, alias=AliasChoices("phone", "phoneNumber"))
|
8
|
+
latitude: float | None = Field(None, alias=AliasChoices("latitude"))
|
9
|
+
longitude: float | None = Field(None, alias=AliasChoices("longitude"))
|
7
10
|
|
8
|
-
class OtfClassTimeMixin:
|
9
|
-
starts_at_local: datetime
|
10
|
-
ends_at_local: datetime
|
11
|
-
name: str
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
class AddressMixin(OtfItemBase):
|
13
|
+
address_line1: str | None = Field(None, alias=AliasChoices("line1", "address1", "address", "physicalAddress"))
|
14
|
+
address_line2: str | None = Field(None, alias=AliasChoices("line2", "address2", "physicalAddress2"))
|
15
|
+
city: str | None = Field(None, alias=AliasChoices("city", "physicalCity", "suburb"))
|
16
|
+
postal_code: str | None = Field(None, alias=AliasChoices("postal_code", "postalCode", "physicalPostalCode"))
|
17
|
+
state: str | None = Field(None, alias=AliasChoices("state", "physicalState", "territory"))
|
18
|
+
country: str | None = Field(None, alias=AliasChoices("country", "physicalCountry"))
|
19
|
+
region: str | None = Field(None, exclude=True, repr=False, alias=AliasChoices("physicalRegion", "region"))
|
20
|
+
country_id: int | None = Field(None, exclude=True, repr=False, alias=AliasChoices("physicalCountryId", "countryId"))
|
16
21
|
|
17
|
-
@
|
18
|
-
|
19
|
-
|
22
|
+
@model_validator(mode="before")
|
23
|
+
@classmethod
|
24
|
+
def check_country(cls, values):
|
25
|
+
if set(values.keys()) == set(
|
26
|
+
["phone", "latitude", "longitude", "address1", "address2", "city", "state", "postalCode"]
|
27
|
+
):
|
28
|
+
values = {k: v for k, v in values.items() if v and str(v) != "0.00000000"}
|
20
29
|
|
21
|
-
|
22
|
-
|
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:]
|
30
|
+
if "country" in values and isinstance(values["country"], dict):
|
31
|
+
values["country_currency"] = values.pop("country")
|
27
32
|
|
28
|
-
|
33
|
+
if "physicalCountry" in values and isinstance(values["physicalCountry"], dict):
|
34
|
+
values["country_currency"] = values.pop("physicalCountry")
|
29
35
|
|
30
|
-
|
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
|
36
|
+
return values
|
37
37
|
|
38
|
-
@
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
@field_validator("address_line1", "address_line2", "city", "postal_code", "state", "country")
|
39
|
+
@classmethod
|
40
|
+
def clean_strings(cls, value: str | None, **_kwargs) -> str | None:
|
41
|
+
if value is None:
|
42
|
+
return value
|
43
|
+
value = value.strip()
|
43
44
|
|
44
|
-
|
45
|
+
if not value:
|
46
|
+
return None
|
47
|
+
|
48
|
+
return value
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from pydantic import Field
|
2
|
+
|
3
|
+
from otf_api.models.base import OtfItemBase
|
4
|
+
|
5
|
+
|
6
|
+
class SmsNotificationSettings(OtfItemBase):
|
7
|
+
is_promotional_sms_opt_in: bool | None = Field(None, alias="isPromotionalSmsOptIn")
|
8
|
+
is_transactional_sms_opt_in: bool | None = Field(None, alias="isTransactionalSmsOptIn")
|
9
|
+
is_promotional_phone_opt_in: bool | None = Field(None, alias="isPromotionalPhoneOptIn")
|
10
|
+
is_transactional_phone_opt_in: bool | None = Field(None, alias="isTransactionalPhoneOptIn")
|
11
|
+
|
12
|
+
|
13
|
+
class EmailNotificationSettings(OtfItemBase):
|
14
|
+
is_system_email_opt_in: bool | None = Field(None, alias="isSystemEmailOptIn")
|
15
|
+
is_promotional_email_opt_in: bool | None = Field(None, alias="isPromotionalEmailOptIn")
|
16
|
+
is_transactional_email_opt_in: bool | None = Field(None, alias="isTransactionalEmailOptIn")
|
17
|
+
email: str | None = None
|
@@ -1,41 +1,32 @@
|
|
1
1
|
from datetime import datetime
|
2
2
|
|
3
|
-
from pydantic import Field
|
3
|
+
from pydantic import AliasPath, Field
|
4
4
|
|
5
5
|
from otf_api.models.base import OtfItemBase
|
6
6
|
|
7
7
|
|
8
|
-
class WorkoutType(OtfItemBase):
|
9
|
-
id: int
|
10
|
-
display_name: str = Field(..., alias="displayName")
|
11
|
-
icon: str
|
12
|
-
|
13
|
-
|
14
8
|
class OutOfStudioWorkoutHistory(OtfItemBase):
|
15
|
-
workout_date: datetime = Field(..., alias="workoutDate")
|
16
|
-
start_time: datetime = Field(..., alias="startTime")
|
17
|
-
end_time: datetime = Field(..., alias="endTime")
|
18
|
-
duration_unit: str = Field(..., alias="durationUnit")
|
19
|
-
duration: float
|
20
|
-
total_calories: int = Field(..., alias="totalCalories")
|
21
|
-
hr_percent_max: int = Field(..., alias="hrPercentMax")
|
22
|
-
distance_unit: str = Field(..., alias="distanceUnit")
|
23
|
-
total_distance: float = Field(..., alias="totalDistance")
|
24
|
-
splat_points: int = Field(..., alias="splatPoints")
|
25
|
-
target_heart_rate: int = Field(..., alias="targetHeartRate")
|
26
|
-
red_zone_seconds: int = Field(..., alias="redZoneSeconds")
|
27
|
-
orange_zone_seconds: int = Field(..., alias="orangeZoneSeconds")
|
28
|
-
green_zone_seconds: int = Field(..., alias="greenZoneSeconds")
|
29
|
-
blue_zone_seconds: int = Field(..., alias="blueZoneSeconds")
|
30
|
-
grey_zone_seconds: int = Field(..., alias="greyZoneSeconds")
|
31
|
-
total_steps: int = Field(..., alias="totalSteps")
|
32
|
-
has_detailed_data: bool = Field(..., alias="hasDetailedData")
|
33
|
-
workout_type: WorkoutType = Field(..., alias="workoutType")
|
34
9
|
member_uuid: str = Field(..., alias="memberUUId")
|
35
10
|
workout_uuid: str = Field(..., alias="workoutUUId")
|
36
|
-
avg_heartrate: int = Field(..., alias="avgHeartrate")
|
37
|
-
max_heartrate: int = Field(..., alias="maxHeartrate")
|
38
|
-
|
39
11
|
|
40
|
-
|
41
|
-
|
12
|
+
workout_date: datetime | None = Field(None, alias="workoutDate")
|
13
|
+
start_time: datetime | None = Field(None, alias="startTime")
|
14
|
+
end_time: datetime | None = Field(None, alias="endTime")
|
15
|
+
duration: float | None = None
|
16
|
+
duration_unit: str | None = Field(None, alias="durationUnit")
|
17
|
+
total_calories: int | None = Field(None, alias="totalCalories")
|
18
|
+
hr_percent_max: int | None = Field(None, alias="hrPercentMax")
|
19
|
+
distance_unit: str | None = Field(None, alias="distanceUnit")
|
20
|
+
total_distance: float | None = Field(None, alias="totalDistance")
|
21
|
+
splat_points: int | None = Field(None, alias="splatPoints")
|
22
|
+
target_heart_rate: int | None = Field(None, alias="targetHeartRate")
|
23
|
+
total_steps: int | None = Field(None, alias="totalSteps")
|
24
|
+
has_detailed_data: bool | None = Field(None, alias="hasDetailedData")
|
25
|
+
avg_heartrate: int | None = Field(None, alias="avgHeartrate")
|
26
|
+
max_heartrate: int | None = Field(None, alias="maxHeartrate")
|
27
|
+
workout_type: str | None = Field(None, alias=AliasPath("workoutType", "displayName"))
|
28
|
+
red_zone_seconds: int | None = Field(None, alias="redZoneSeconds")
|
29
|
+
orange_zone_seconds: int | None = Field(None, alias="orangeZoneSeconds")
|
30
|
+
green_zone_seconds: int | None = Field(None, alias="greenZoneSeconds")
|
31
|
+
blue_zone_seconds: int | None = Field(None, alias="blueZoneSeconds")
|
32
|
+
grey_zone_seconds: int | None = Field(None, alias="greyZoneSeconds")
|