Skip to content

Commit 05c8219

Browse files
authored
Merge pull request #96 from NodeJSmith/feature/add_state_dunder_methods
Feature/add state dunder methods to allow pickling
2 parents 7150220 + 5fd9a0c commit 05c8219

File tree

11 files changed

+818
-822
lines changed

11 files changed

+818
-822
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.13.3"
2+
current_version = "0.14.0"
33

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

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,4 @@ cython_debug/
167167
model_generator.py
168168
scratch*.py
169169
docs/reference/
170+
.vscode

pyproject.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "otf-api"
3-
version = "0.13.3"
3+
version = "0.14.0"
44
description = "Python OrangeTheory Fitness API Client"
55
authors = [{ name = "Jessica Smith", email = "[email protected]" }]
66
requires-python = ">=3.11"
@@ -39,7 +39,6 @@ Documentation = "https://otf-api.readthedocs.io/en/stable/"
3939
dev = [
4040
"build==1.2.1",
4141
"bump-my-version>=0.23.0,<0.24",
42-
"mypy==1.10.0",
4342
"mypy-boto3-cognito-identity>=1.38.0",
4443
"mypy-boto3-cognito-idp>=1.35.93,<2",
4544
"pre-commit==3.7.1",
@@ -51,7 +50,7 @@ dev = [
5150
docs = [
5251
"autodoc-pydantic>=2.2.0",
5352
"furo>=2024.8.6",
54-
"sphinx==8.3.0",
53+
"sphinx>=8.3.0",
5554
"sphinx-autobuild==2024.10.3",
5655
"sphinx-autodoc-typehints==3.2.0",
5756
"sphinx-autodoc2==0.5.0",
@@ -72,5 +71,5 @@ default-groups = ["dev"]
7271
pythonpath = ["src"]
7372

7473
[build-system]
75-
requires = ["setuptools >= 61.0"]
74+
requires = ["setuptools >= 80.0"]
7675
build-backend = "setuptools.build_meta"

source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
project = "OrangeTheory API"
1515
copyright = "2025, Jessica Smith"
1616
author = "Jessica Smith"
17-
release = "0.13.3"
17+
release = "0.14.0"
1818

1919
# -- General configuration ---------------------------------------------------
2020
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

src/otf_api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def _setup_logging() -> None:
3636

3737
_setup_logging()
3838

39-
__version__ = "0.13.3"
39+
__version__ = "0.14.0"
4040

4141

4242
__all__ = ["Otf", "OtfUser", "models"]

src/otf_api/api/client.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ def __init__(self, user: OtfUser | None = None):
4949
)
5050
atexit.register(self.session.close)
5151

52+
def __getstate__(self):
53+
"""Get the state of the OtfClient instance for serialization."""
54+
state = self.__dict__.copy()
55+
# Remove circular references
56+
state.pop("session", None)
57+
return state
58+
59+
def __setstate__(self, state): # noqa
60+
"""Set the state of the OtfClient instance from serialized data."""
61+
self.__dict__.update(state)
62+
self.session = httpx.Client(
63+
headers=HEADERS, auth=self.user.httpx_auth, timeout=httpx.Timeout(20.0, connect=60.0)
64+
)
65+
atexit.register(self.session.close)
66+
5267
def _build_request(
5368
self,
5469
method: str,

src/otf_api/api/members/member_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def __init__(self, client: OtfClient):
1414
self.client = client
1515
self.member_uuid = client.member_uuid
1616

17-
@CACHE.memoize(expire=600, tag="member_detail", ignore=(0,))
17+
@CACHE.memoize(expire=600, tag="member_detail")
1818
def get_member_detail(self) -> dict:
1919
"""Retrieve raw member details."""
2020
return self.client.default_request(

src/otf_api/api/studios/studio_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def __init__(self, client: OtfClient):
1515
self.client = client
1616
self.member_uuid = client.member_uuid
1717

18-
@CACHE.memoize(expire=600, tag="studio_detail", ignore=(0,))
18+
@CACHE.memoize(expire=600, tag="studio_detail")
1919
def get_studio_detail(self, studio_uuid: str) -> dict:
2020
"""Retrieve raw studio details."""
2121
return self.client.default_request("GET", f"/mobile/v1/studios/{studio_uuid}")["data"]

src/otf_api/api/workouts/workout_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def get_performance_summaries(self, limit: int | None = None) -> dict:
4343
params = {"limit": limit} if limit else {}
4444
return self.performance_summary_request("GET", "/v1/performance-summaries", params=params)
4545

46-
@CACHE.memoize(expire=600, tag="performance_summary", ignore=(0,))
46+
@CACHE.memoize(expire=600, tag="performance_summary")
4747
def get_performance_summary(self, performance_summary_id: str) -> dict:
4848
"""Retrieve raw performance summary data."""
4949
return self.performance_summary_request("GET", f"/v1/performance-summaries/{performance_summary_id}")
@@ -54,7 +54,7 @@ def get_hr_history_raw(self) -> dict:
5454
"history"
5555
]
5656

57-
@CACHE.memoize(expire=600, tag="telemetry", ignore=(0,))
57+
@CACHE.memoize(expire=600, tag="telemetry")
5858
def get_telemetry(self, performance_summary_id: str, max_data_points: int = 150) -> dict:
5959
"""Retrieve raw telemetry data."""
6060
return self.telemetry_request(

src/otf_api/auth/auth.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,20 @@ def _set_tokens(self, tokens: "InitiateAuthResponseTypeDef") -> None:
340340
self.device_group_key = device_metadata.get("DeviceGroupKey", self.device_group_key)
341341
CACHE.write_device_data_to_cache(self.device_metadata)
342342

343+
def __getstate__(self):
344+
"""Get the state of the object for pickling."""
345+
state = self.__dict__.copy()
346+
del state["idp_client"]
347+
del state["id_client"]
348+
return state
349+
350+
def __setstate__(self, state): # noqa
351+
"""Set the state of the object from a pickled state."""
352+
self.__dict__.update(state)
353+
self.idp_client = Session().client("cognito-idp", config=BOTO_CONFIG, region_name=REGION) # type: ignore
354+
355+
self.id_client = Session().client("cognito-identity", config=BOTO_CONFIG, region_name=REGION) # type: ignore
356+
343357

344358
class HttpxCognitoAuth(httpx.Auth):
345359
http_header: str = "Authorization"

0 commit comments

Comments
 (0)