otf-api 0.2.1__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. otf_api/__init__.py +12 -67
  2. otf_api/api.py +794 -36
  3. otf_api/cli/__init__.py +4 -0
  4. otf_api/cli/_utilities.py +60 -0
  5. otf_api/cli/app.py +177 -0
  6. otf_api/cli/bookings.py +231 -0
  7. otf_api/cli/prompts.py +162 -0
  8. otf_api/models/__init__.py +4 -8
  9. otf_api/models/auth.py +18 -12
  10. otf_api/models/base.py +205 -2
  11. otf_api/models/responses/__init__.py +6 -14
  12. otf_api/models/responses/body_composition_list.py +304 -0
  13. otf_api/models/responses/book_class.py +405 -0
  14. otf_api/models/responses/bookings.py +211 -37
  15. otf_api/models/responses/cancel_booking.py +93 -0
  16. otf_api/models/responses/challenge_tracker_content.py +6 -6
  17. otf_api/models/responses/challenge_tracker_detail.py +6 -6
  18. otf_api/models/responses/classes.py +205 -7
  19. otf_api/models/responses/enums.py +0 -35
  20. otf_api/models/responses/favorite_studios.py +5 -5
  21. otf_api/models/responses/latest_agreement.py +2 -2
  22. otf_api/models/responses/lifetime_stats.py +92 -0
  23. otf_api/models/responses/member_detail.py +17 -12
  24. otf_api/models/responses/member_membership.py +2 -2
  25. otf_api/models/responses/member_purchases.py +9 -9
  26. otf_api/models/responses/out_of_studio_workout_history.py +4 -4
  27. otf_api/models/responses/performance_summary_detail.py +1 -1
  28. otf_api/models/responses/performance_summary_list.py +13 -13
  29. otf_api/models/responses/studio_detail.py +10 -10
  30. otf_api/models/responses/studio_services.py +8 -8
  31. otf_api/models/responses/telemetry.py +6 -6
  32. otf_api/models/responses/telemetry_hr_history.py +6 -6
  33. otf_api/models/responses/telemetry_max_hr.py +3 -3
  34. otf_api/models/responses/total_classes.py +2 -2
  35. otf_api/models/responses/workouts.py +4 -4
  36. otf_api-0.3.0.dist-info/METADATA +55 -0
  37. otf_api-0.3.0.dist-info/RECORD +42 -0
  38. otf_api-0.3.0.dist-info/entry_points.txt +3 -0
  39. otf_api/__version__.py +0 -1
  40. otf_api/classes_api.py +0 -44
  41. otf_api/member_api.py +0 -380
  42. otf_api/performance_api.py +0 -54
  43. otf_api/studios_api.py +0 -96
  44. otf_api/telemetry_api.py +0 -95
  45. otf_api-0.2.1.dist-info/METADATA +0 -284
  46. otf_api-0.2.1.dist-info/RECORD +0 -38
  47. {otf_api-0.2.1.dist-info → otf_api-0.3.0.dist-info}/AUTHORS.md +0 -0
  48. {otf_api-0.2.1.dist-info → otf_api-0.3.0.dist-info}/LICENSE +0 -0
  49. {otf_api-0.2.1.dist-info → otf_api-0.3.0.dist-info}/WHEEL +0 -0
@@ -1,284 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: otf-api
3
- Version: 0.2.1
4
- Summary: Python OrangeTheory Fitness API Client
5
- License: MIT
6
- Author: Jessica Smith
7
- Author-email: j.smith.git1@gmail.com
8
- Requires-Python: >=3.10,<4.0
9
- Classifier: Development Status :: 4 - Beta
10
- Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.10
15
- Classifier: Programming Language :: Python :: 3.11
16
- Classifier: Programming Language :: Python :: 3.12
17
- Classifier: Topic :: Internet :: WWW/HTTP
18
- Classifier: Topic :: Software Development :: Libraries
19
- Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
20
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
- Requires-Dist: aiohttp (==3.9.5)
22
- Requires-Dist: loguru (==0.7.2)
23
- Requires-Dist: pycognito (==2024.5.1)
24
- Requires-Dist: pydantic (==2.7.3)
25
- Project-URL: Documentation, https://otf-api.readthedocs.io/en/latest/
26
- Description-Content-Type: text/markdown
27
-
28
- Simple API client for interacting with the OrangeTheory Fitness APIs.
29
-
30
-
31
- This library allows access to the OrangeTheory API to retrieve workouts and performance data, class schedules, studio information, and bookings. It is a work in progress, currently only allowing access to GET calls, but my goal is to expand it to include POST, PUT, and DELETE calls as well.
32
-
33
- ## Installation
34
- ```bash
35
- pip install otf-api
36
- ```
37
-
38
- ## Overview
39
-
40
- To use the API, you need to create an instance of the `Api` class, providing your email address and password. This will authenticate you with the API and allow you to make requests. When the `Api` object is created it automatically grabs your member details and home studio, to simplify the process of making requests.
41
-
42
- The `Api` object has multiple api objects as attributes, which you can use to make requests to the API. The available api objects are:
43
-
44
- - `classes_api`
45
- - `members_api`
46
- - `performance_api`
47
- - `studios_api`
48
- - `telemetry_api`
49
-
50
-
51
- ## Example Usage
52
-
53
- Note: see more examples in the `examples` directory and in the [usage docs](https://otf-api.readthedocs.io/en/latest/usage/).
54
-
55
- ```python
56
- import asyncio
57
- import json
58
- import os
59
-
60
- from otf_api import Api
61
-
62
- USERNAME = os.getenv("OTF_EMAIL")
63
- PASSWORD = os.getenv("OTF_PASSWORD")
64
-
65
-
66
- async def main():
67
- otf = await Api.create(USERNAME, PASSWORD)
68
-
69
- # performance summaries are historical records of your performance in workouts
70
- # `get_performance_summaries` takes a limit (default of 30) and returns a list of summaries
71
- data_list = await otf.performance_api.get_performance_summaries()
72
- print(json.dumps(data_list.summaries[0].model_dump(), indent=4, default=str))
73
- """
74
- {
75
- "performance_summary_id": "29dd97f4-3418-4247-b35c-37eabc5e17f3",
76
- "details": {
77
- "calories_burned": 506,
78
- "splat_points": 18,
79
- "step_count": 0,
80
- "active_time_seconds": 3413,
81
- "zone_time_minutes": {
82
- "gray": 2,
83
- "blue": 13,
84
- "green": 24,
85
- "orange": 16,
86
- "red": 2
87
- }
88
- },
89
- "ratable": true,
90
- "class_": {
91
- "ot_base_class_uuid": "b6549fc2-a479-4b03-9303-e0e45dbcd8c9",
92
- "starts_at_local": "2024-06-11T09:45:00",
93
- "name": "Orange 60 Min 2G",
94
- "coach": ...,
95
- "studio": ...,
96
- },
97
- "ratings": null
98
- }
99
- """
100
-
101
- # you can get detailed information about a specific performance summary by calling `get_performance_summary`
102
- # which takes a performance_summary_id as an argument
103
- data = await otf.performance_api.get_performance_summary(data_list.summaries[0].performance_summary_id)
104
- print(json.dumps(data.model_dump(), indent=4, default=str))
105
-
106
- """
107
- {
108
- "id": "29dd97f4-3418-4247-b35c-37eabc5e17f3",
109
- "details": {
110
- "calories_burned": 506,
111
- "splat_points": 18,
112
- "step_count": 3314,
113
- "active_time_seconds": 0,
114
- "zone_time_minutes": {
115
- "gray": 2,
116
- "blue": 13,
117
- "green": 24,
118
- "orange": 16,
119
- "red": 2
120
- },
121
- "heart_rate": {
122
- "max_hr": 0,
123
- "peak_hr": 180,
124
- "peak_hr_percent": 94,
125
- "avg_hr": 149,
126
- "avg_hr_percent": 78
127
- },
128
- "equipment_data": {
129
- "treadmill": {
130
- "avg_pace": {
131
- "display_value": "15:23",
132
- "display_unit": "min/mile",
133
- "metric_value": "923"
134
- },
135
- "avg_speed": {
136
- "display_value": 3.9,
137
- "display_unit": "mph",
138
- "metric_value": 3.9
139
- },
140
- "max_pace": ...,
141
- "max_speed": ...,
142
- "moving_time": ...,
143
- "total_distance": ...,
144
- "avg_incline": ...,
145
- "elevation_gained": ...,
146
- "max_incline": ...
147
- },
148
- "rower": ...
149
- }
150
- },
151
- "ratable": false,
152
- "class_": {
153
- "starts_at_local": "2024-06-11T09:45:00",
154
- "name": "Orange 60 Min 2G"
155
- }
156
- }
157
- """
158
-
159
- # workouts is a similar endpoint but returns more data - this is what OTLive uses to display workout history
160
- # this endpoint takes no arguments and returns all workouts back to, as far as we can tell, around 2019
161
- workouts = await otf.member_api.get_workouts()
162
- print(json.dumps(workouts.workouts[0].model_dump(), indent=4, default=str))
163
- """
164
- {
165
- "studio_number": "8292",
166
- "studio_name": "AnyTown OH - East",
167
- "class_type": "Orange 60 Min 2G",
168
- "active_time": 3413,
169
- "coach": "Coach",
170
- "member_uuid": "b4df31a6-fa54-4a7f-85eb-1f5b613c6414",
171
- "class_date": "2024-06-11 09:45:00+00:00",
172
- "total_calories": 506,
173
- "avg_hr": 149,
174
- "max_hr": 180,
175
- "avg_percent_hr": 78,
176
- "max_percent_hr": 94,
177
- "total_splat_points": 18,
178
- "red_zone_time_second": 137,
179
- "orange_zone_time_second": 979,
180
- "green_zone_time_second": 1415,
181
- "blue_zone_time_second": 769,
182
- "black_zone_time_second": 113,
183
- "step_count": 3314,
184
- "class_history_uuid": "c71658c3-46e7-410b-8ffa-9a8ffd3828fa",
185
- "class_id": "30299",
186
- "date_created": "2024-06-11 10:43:00+00:00",
187
- "date_updated": "2024-06-11 10:43:00+00:00",
188
- "is_intro": false,
189
- "is_leader": false,
190
- "member_email": null,
191
- "member_name": "Member Name",
192
- "member_performance_id": "0cbc39d3-bb9b-4021-8006-8eb23c272f0d",
193
- "minute_by_minute_hr": [
194
- 108,
195
- 147,
196
- 149,
197
- ...
198
- ],
199
- "source": "OTbeat Live",
200
- "studio_account_uuid": "studio-number-0325",
201
- "version": "1",
202
- "workout_type": {
203
- "id": 101,
204
- "display_name": "Studio Workout",
205
- "icon": ""
206
- }
207
- }
208
- """
209
-
210
- # telemetry is a detailed record of a specific workout - minute by minute, or more granular if desired
211
- # this endpoint takes a class_history_uuid, as well as a number of max data points - if you do not pass
212
- # this value it will attempt to return enough data points for 30 second intervals
213
- telemetry = await otf.telemetry_api.get_telemetry(workouts.workouts[0].class_history_uuid)
214
- print(json.dumps(telemetry.model_dump(), indent=4, default=str))
215
-
216
- """
217
- {
218
- "member_uuid": "fa323d40-bfae-4e72-872c-e11188d182a7",
219
- "class_history_uuid": "5945a723-930b-449a-bd8f-8267a4ff392f",
220
- "class_start_time": "2024-06-11 14:46:07+00:00",
221
- "max_hr": 191,
222
- "zones": {
223
- "gray": {
224
- "start_bpm": 96,
225
- "end_bpm": 116
226
- },
227
- "blue": {
228
- "start_bpm": 117,
229
- "end_bpm": 135
230
- },
231
- "green": {
232
- "start_bpm": 136,
233
- "end_bpm": 159
234
- },
235
- "orange": {
236
- "start_bpm": 160,
237
- "end_bpm": 175
238
- },
239
- "red": {
240
- "start_bpm": 176,
241
- "end_bpm": 191
242
- }
243
- },
244
- "window_size": 30,
245
- "telemetry": [
246
- {
247
- "relative_timestamp": 0,
248
- "hr": 105,
249
- "agg_splats": 0,
250
- "agg_calories": 2,
251
- "timestamp": "2024-06-11 14:46:07+00:00",
252
- "tread_data": {
253
- "tread_speed": 1.34,
254
- "tread_incline": 1.0,
255
- "agg_tread_distance": 9
256
- }
257
- },
258
- {
259
- "relative_timestamp": 30,
260
- "hr": 132,
261
- "agg_splats": 0,
262
- "agg_calories": 4,
263
- "timestamp": "2024-06-11 14:46:37+00:00",
264
- "tread_data": {
265
- "tread_speed": 2.46,
266
- "tread_incline": 1.0,
267
- "agg_tread_distance": 62
268
- }
269
- },
270
- ...
271
- ]
272
- }
273
- """
274
-
275
-
276
- if __name__ == "__main__":
277
- asyncio.run(main())
278
-
279
- ```
280
-
281
-
282
- Disclaimer:
283
- This project is in no way affiliated with OrangeTheory Fitness.
284
-
@@ -1,38 +0,0 @@
1
- otf_api/__init__.py,sha256=FkZ1Yc26-CSBaRr1aPCOxjAg-QGkDzMalj-7tBHi7MA,1580
2
- otf_api/__version__.py,sha256=HfjVOrpTnmZ-xVFCYSVmX50EXaBQeJteUHG-PD6iQs8,22
3
- otf_api/api.py,sha256=Ua8rTeJUdX-gP_TJJteWB7axTef-9LSEDvy8Pahg6C0,5023
4
- otf_api/classes_api.py,sha256=KaKYM32rUa9Ofd6AV4hNF7YF3EWuQa1S40bWhYg06PQ,1594
5
- otf_api/member_api.py,sha256=UamXcW0w-gbmVOWfJLQoNJYermwNAX_aL8AIZvwAAa8,15146
6
- otf_api/models/__init__.py,sha256=ELtDtUqZLChDO5QyGguiYGd1l5cGsJr4qeayGTu2Uv0,1391
7
- otf_api/models/auth.py,sha256=Zfxf5K0G81o3d6exDuP8W0C033VCrls2fUPwE-GIm5w,3982
8
- otf_api/models/base.py,sha256=VVL3FKOBVRz3SMfxyhMaWgNSkjmccmIEr9DH0wL8GgY,203
9
- otf_api/models/responses/__init__.py,sha256=zP84-upo2FV5Prl0ckl_6Jg9BkTvGJ9T7fGYk9rFHwQ,1834
10
- otf_api/models/responses/bookings.py,sha256=cmhtxCyF4KXdRB6hiIcqFVtnjPSZyONmiZTjao0aw-8,4919
11
- otf_api/models/responses/challenge_tracker_content.py,sha256=g3GyWzDvis_SuUQ9HDEY8ffVeSzhqPuvkiX2CUHHyRs,1429
12
- otf_api/models/responses/challenge_tracker_detail.py,sha256=Ob2ZXFANmqZEp7McTOXk2q_-NWkzGj5nbc59hRLRZj0,3054
13
- otf_api/models/responses/classes.py,sha256=CwLKmjiFY3xgEe5sBIUMrUuJ_XN68Nqg46vjWBQXiXo,1073
14
- otf_api/models/responses/enums.py,sha256=ySlRn-eVtm3GjT8TsFFAIKDqs2NjGmz-M63-QGRQIWM,2182
15
- otf_api/models/responses/favorite_studios.py,sha256=jeOep69_pnwpk6lLBumYfFExv0ViM2HjXRLvTsm0psc,4987
16
- otf_api/models/responses/latest_agreement.py,sha256=upSTIfKpgas-foPBwn9Pds1mjxxvYvZC2LbSl5VSKWs,776
17
- otf_api/models/responses/member_detail.py,sha256=f31c4m4ids2-vl_G57gqRsDeSeWrDV3Hph5NwBTzT0o,5917
18
- otf_api/models/responses/member_membership.py,sha256=_yOpMTceuD-533Nnv7dC8NQI3rf3HI1zO8lvvlazu08,997
19
- otf_api/models/responses/member_purchases.py,sha256=48ng_rRPCmYWXNVirT792zqNxxywngKAlIG65sr8gys,6094
20
- otf_api/models/responses/out_of_studio_workout_history.py,sha256=9e10JUXx1yJyrQ-LldDVAJWXqQu6lfGGKc5IN3MEgkc,1713
21
- otf_api/models/responses/performance_summary_detail.py,sha256=s4k-684QNVFngA8uh7wnuoc4nHryt6K-WZ5rQCTo40s,1582
22
- otf_api/models/responses/performance_summary_list.py,sha256=1F02o_L7wwRzzz6Nti6jJPfzjJV4XDj26xteWlBJRAE,1245
23
- otf_api/models/responses/studio_detail.py,sha256=LU-mJq0TpxtzyRDYCRVLCoD0mEjT_EhIAGtC6zmHuvw,5017
24
- otf_api/models/responses/studio_services.py,sha256=fHfsBMByW77-uE4t0q4C7M7DJ8Km4sb3pkjiq2GnYig,1844
25
- otf_api/models/responses/telemetry.py,sha256=owLbL-_4SwzxOYgQruS1NfJm1zp3UqgvsvgaO723v7U,1669
26
- otf_api/models/responses/telemetry_hr_history.py,sha256=WcxNUMzLsw7Cg6AFTFLWp0Keqwi5zqz4ubM0x3Tm_18,769
27
- otf_api/models/responses/telemetry_max_hr.py,sha256=CBpbaHKZ2pmBADT1egsiPILUGgPfQXPIivKzTJz6QB4,269
28
- otf_api/models/responses/total_classes.py,sha256=7WP3jB4z-4ZwIAShJg2CTBL-zlZqwb-lVptc_Ybsw3A,290
29
- otf_api/models/responses/workouts.py,sha256=vI7aOHbXnOUxWquA0nc_P5wcvFkxc0k11RaoXHcsGng,3181
30
- otf_api/performance_api.py,sha256=vQpziBdMkN4MsdF6--uqr9fjbf-tQIezNvXtBv-CeWU,2019
31
- otf_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- otf_api/studios_api.py,sha256=7h6ZMJS9bWCVdpnSlVY4neLYiIagVKPzZSrxi1fB8-U,3568
33
- otf_api/telemetry_api.py,sha256=LvtBlbXZfxUNhX_dcvCt01DgLJ7DZrUcsWF0VvcT0AE,3715
34
- otf_api-0.2.1.dist-info/AUTHORS.md,sha256=FcNWMxpe8KDuTq4Qau0SUXsabQwGs9TGnMp1WkXRnj8,123
35
- otf_api-0.2.1.dist-info/LICENSE,sha256=UaPT9ynYigC3nX8n22_rC37n-qmTRKLFaHrtUwF9ktE,1071
36
- otf_api-0.2.1.dist-info/METADATA,sha256=ati9UFv1gy2c_TzCFtw7uE9LWjagN-FWSNny1JeTqVE,9532
37
- otf_api-0.2.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
38
- otf_api-0.2.1.dist-info/RECORD,,