Skip to content

Commit 8235da3

Browse files
authored
Merge pull request #91 from NodeJSmith/feature/organization_and_more_best_practices
Feature/organization and more best practices
2 parents ee986d8 + 96e4dae commit 8235da3

File tree

103 files changed

+5017
-3796
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+5017
-3796
lines changed

.bumpversion.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool.bumpversion]
2-
current_version = "0.12.1"
2+
current_version = "0.13.0"
33

44
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(?:-(?P<rc_l>rc)(?P<rc>0|[1-9]\\d*))?"
55

.codespellrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[codespell]
2-
skip = ./build,./.venv/,./venv/,./.tox,.git,*.pdf,*.svg,versioneer.py,package-lock.json,_vendor,*.css,.codespellrc,poetry.lock
2+
skip = ./build,./.venv/,./venv/,./.tox,.git,*.pdf,*.svg,versioneer.py,package-lock.json,_vendor,*.css,.codespellrc,poetry.lock,uv.lock
33
ignore-words-list = OT,Checkin,Tread,AllTime,allTime,tread

.readthedocs.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ build:
1414
# See https://github.com/readthedocs/readthedocs.org/pull/11152/
1515
- PATH="/home/docs/.local/bin:$PATH" && VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH uv sync --group docs --active --link-mode=copy
1616

17-
mkdocs:
18-
configuration: mkdocs.yml
17+
sphinx:
18+
configuration: source/conf.py

cliff.toml

Lines changed: 0 additions & 83 deletions
This file was deleted.

docs/index.md

Lines changed: 0 additions & 14 deletions
This file was deleted.

docs/usage.md

Lines changed: 0 additions & 51 deletions
This file was deleted.

examples/challenge_tracker_examples.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
from otf_api import Otf
2-
from otf_api.models.enums import ChallengeCategory, EquipmentType
2+
from otf_api.models.workouts import ChallengeCategory, EquipmentType
33

44

5-
def main():
5+
def main(): # noqa: D103, ANN201
66
otf = Otf()
77

88
# You can get challenges by equipment or by challenge category
99

1010
for et in EquipmentType:
11-
benchmarks = otf.get_benchmarks_by_equipment(et)
11+
benchmarks = otf.workouts.get_benchmarks_by_equipment(et)
1212
if not benchmarks:
1313
continue
1414
print(f"Equipment: {et.name}, Challenges: {len(benchmarks):,}")
@@ -63,7 +63,7 @@ def main():
6363
"""
6464

6565
for ct in ChallengeCategory:
66-
benchmarks = otf.get_benchmarks_by_challenge_category(ct)
66+
benchmarks = otf.workouts.get_benchmarks_by_challenge_category(ct)
6767
if not benchmarks:
6868
continue
6969
print(f"Challenge Name: {ct.name}, Challenges: {len(benchmarks):,}")

examples/class_bookings_examples.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from datetime import time
22

3+
import pendulum
4+
35
from otf_api import Otf
4-
from otf_api.filters import ClassFilter, ClassType, DoW
6+
from otf_api.models.bookings import ClassFilter, ClassType, DoW
57

68

7-
def main():
9+
def main(): # noqa: D103, ANN201
810
otf = Otf()
911

1012
# you can use the ClassFilter model to setup filters to only return the classes
@@ -25,7 +27,7 @@ def main():
2527

2628
# the call to `get_classes` will return classes that match either of these filters
2729

28-
classes = otf.get_classes(filters=[cf, cf2])
30+
classes = otf.bookings.get_classes(filters=[cf, cf2])
2931
print(classes[0].model_dump_json(indent=4))
3032

3133
"""
@@ -70,7 +72,7 @@ def main():
7072
# You can also get the classes that you have booked
7173
# You can pass a start_date, end_date, status, and limit as arguments
7274

73-
bookings = otf.get_bookings()
75+
bookings = otf.bookings.get_bookings()
7476

7577
print("Latest Upcoming Class:")
7678
print(bookings[-1].model_dump_json(indent=4))
@@ -129,7 +131,7 @@ def main():
129131
# If it is a past class that you attended, it will also include workout data - it is best
130132
# to use the `get_workout_from_boooking` method to get an actual Workout object, as this
131133
# combines data from multiple endpoints to give you the same data that is shown in the app
132-
bookings_new = otf.get_bookings_new()
134+
bookings_new = otf.bookings.get_bookings_new()
133135
print("Furthest Upcoming Class (New):")
134136
print(bookings_new[0].model_dump_json(indent=4))
135137
"""
@@ -179,8 +181,9 @@ def main():
179181
"""
180182

181183
# you can get the workout data from a booking by calling `get_workout_from_booking`
184+
bookings_new = otf.bookings.get_bookings_new(pendulum.today().subtract(months=1))
182185
booking = next(x for x in bookings_new if x.workout is not None)
183-
workout = otf.get_workout_from_booking(booking)
186+
workout = otf.workouts.get_workout_from_booking(booking)
184187
print(workout.model_dump_json(indent=4, exclude_none=True))
185188
"""
186189
{

examples/studio_examples.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
from otf_api import Otf
22

33

4-
def main():
4+
def main(): # noqa: D103, ANN201
55
otf = Otf()
66

77
# if you need to figure out what studios are in an area, you can call `search_studios_by_geo`
88
# which takes latitude, longitude, distance, page_index, and page_size as arguments
99
# but you'll generally just need the first 3
1010
# same as with classes, you can leave it blank and get the studios within 50 miles of your home studio
11-
studios_by_geo = otf.search_studios_by_geo()
11+
studios_by_geo = otf.studios.search_studios_by_geo()
1212
print(studios_by_geo[0].model_dump_json(indent=4))
1313

1414
"""
@@ -36,7 +36,7 @@ def main():
3636
# if you need to get detailed information about a studio, you can call `get_studio_detail`
3737
# which takes a studio_uuid as an argument, but you can leave it blank to get details about your home studio
3838
# the return type is also StudioDetail, so the same format as the above
39-
studio_detail = otf.get_studio_detail()
39+
studio_detail = otf.studios.get_studio_detail()
4040
print(studio_detail.model_dump_json(indent=4))
4141

4242
"""
@@ -62,7 +62,7 @@ def main():
6262
"""
6363

6464
# you can get studio services, although I'm not sure if anyone would ever need this
65-
services = otf.get_studio_services(studio_detail.studio_uuid)
65+
services = otf.studios.get_studio_services(studio_detail.studio_uuid)
6666
for svc in services:
6767
print(svc.model_dump_json(indent=4))
6868

@@ -85,21 +85,21 @@ def main():
8585

8686
# you can get you favorite studios and add/remove studios from your favorites
8787
# this returns a list of StudioDetail, so the same format as the above
88-
faves = otf.get_favorite_studios()
88+
faves = otf.studios.get_favorite_studios()
8989
if faves:
9090
print(faves[0].model_dump_json(indent=4))
9191

9292
# you can add a studio to your favorites by calling `add_favorite_studio` with a studio_uuid
93-
otf.add_favorite_studio(otf.home_studio_uuid)
93+
otf.studios.add_favorite_studio(otf.home_studio_uuid)
9494

9595
# you can remove a studio from your favorites by calling `remove_favorite_studio` with a studio_uuid
96-
otf.remove_favorite_studio(otf.home_studio_uuid)
96+
otf.studios.remove_favorite_studio(otf.home_studio_uuid)
9797

9898
# if you attempt to get a studio that doesn't exist, you'll a mostly empty studio detail object
9999
# with the studio uuid set to the provided value
100100
# this allows you to avoid dealing with None values + you can still group or sort by studio_uuid
101101

102-
invalid_studio = otf.get_studio_detail("2d07e9fc-cd14-4d5b-840e-09eb2b614c6c")
102+
invalid_studio = otf.studios.get_studio_detail("2d07e9fc-cd14-4d5b-840e-09eb2b614c6c")
103103
assert invalid_studio.studio_uuid == "2d07e9fc-cd14-4d5b-840e-09eb2b614c6c"
104104
print(invalid_studio.model_dump_json(indent=4))
105105

examples/workout_examples.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
from otf_api import Otf
44
from otf_api.exceptions import AlreadyRatedError, ClassNotRatableError
5-
from otf_api.models.enums import StatsTime
5+
from otf_api.models.workouts import StatsTime
66

77

8-
def main():
8+
def main(): # noqa: D103, ANN201
99
otf = Otf()
1010

11-
resp = otf.get_member_lifetime_stats_in_studio()
11+
resp = otf.workouts.get_member_lifetime_stats_in_studio()
12+
print("Lifetime in-studio stats:")
1213
print(resp.model_dump_json(indent=4))
1314

1415
"""
@@ -29,7 +30,8 @@ def main():
2930
}
3031
"""
3132

32-
resp = otf.get_member_lifetime_stats_in_studio(StatsTime.ThisMonth)
33+
resp = otf.workouts.get_member_lifetime_stats_in_studio(StatsTime.ThisMonth)
34+
print("This month in-studio stats:")
3335
print(resp.model_dump_json(indent=4))
3436

3537
"""
@@ -53,7 +55,7 @@ def main():
5355
# you can get a list of workouts by calling `get_workouts`, which optionally takes a start and end date
5456
# the workout includes all of the details, including the performance summary, class, coach, studio, and rating data
5557
# from the new endpoint - the data matches what is shown in the OTF app after a workout
56-
data_list = otf.get_workouts()
58+
data_list = otf.workouts.get_workouts()
5759
print(data_list[0].model_dump_json(indent=4, exclude_none=True))
5860
"""
5961
{
@@ -356,7 +358,7 @@ def main():
356358
with suppress(AlreadyRatedError, ClassNotRatableError):
357359
unrated_class = next((w for w in data_list if w.ratable and not w.class_rating), None)
358360
if unrated_class:
359-
rated_workout = otf.rate_class_from_workout(unrated_class, 3, 3)
361+
rated_workout = otf.workouts.rate_class_from_workout(unrated_class, 3, 3)
360362
print(rated_workout.model_dump_json(indent=4))
361363
else:
362364
print("No unrated classes found")

0 commit comments

Comments
 (0)