Skip to content

Commit de3d551

Browse files
Move cache globals to cache.py
1 parent ed369e4 commit de3d551

File tree

2 files changed

+63
-59
lines changed

2 files changed

+63
-59
lines changed

sync/clients/cache.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import logging
22
from datetime import datetime, timedelta, timezone
3-
from typing import Optional, Tuple
3+
from typing import Optional, Tuple, Union, Callable, Type
4+
from pathlib import Path
5+
import json
6+
7+
from platformdirs import user_cache_dir
48

59
logger = logging.getLogger(__name__)
610

@@ -43,3 +47,57 @@ def _set_cached_token(self) -> None:
4347

4448
def _get_cached_token(self) -> Optional[Tuple[str, datetime]]:
4549
raise NotImplementedError
50+
51+
52+
class FileCachedToken(CachedToken):
53+
def __init__(self):
54+
self._cache_file = Path(user_cache_dir("syncsparkpy")) / "auth.json"
55+
56+
super().__init__()
57+
58+
def _get_cached_token(self) -> Optional[Tuple[str, datetime]]:
59+
# Cache is optional, we can fail to read it and not worry
60+
if self._cache_file.exists():
61+
try:
62+
cached_token = json.loads(self._cache_file.read_text())
63+
cached_access_token = cached_token["access_token"]
64+
cached_expiry = datetime.fromisoformat(cached_token["expires_at_utc"])
65+
return cached_access_token, cached_expiry
66+
except Exception as e:
67+
logger.warning(
68+
f"Failed to read cached access token @ {self._cache_file}", exc_info=e
69+
)
70+
71+
return None
72+
73+
def _set_cached_token(self) -> None:
74+
# Cache is optional, we can fail to read it and not worry
75+
try:
76+
self._cache_file.parent.mkdir(parents=True, exist_ok=True)
77+
self._cache_file.write_text(
78+
json.dumps(
79+
{
80+
"access_token": self._access_token,
81+
"expires_at_utc": self._access_token_expires_at_utc.isoformat(),
82+
}
83+
)
84+
)
85+
except Exception as e:
86+
logger.warning(
87+
f"Failed to write cached access token @ {self._cache_file}", exc_info=e
88+
)
89+
90+
91+
# Putting this here instead of config.py because circular imports and typing.
92+
ACCESS_TOKEN_CACHE_CLS_TYPE = Union[Type[CachedToken], Callable[[], CachedToken]]
93+
_access_token_cache_cls: ACCESS_TOKEN_CACHE_CLS_TYPE = FileCachedToken # Default to local file caching.
94+
95+
96+
def set_access_token_cache_cls(access_token_cache_cls: ACCESS_TOKEN_CACHE_CLS_TYPE) -> None:
97+
global _access_token_cache_cls
98+
_access_token_cache_cls = access_token_cache_cls
99+
100+
101+
def get_access_token_cache_cache() -> ACCESS_TOKEN_CACHE_CLS_TYPE:
102+
global _access_token_cache_cls
103+
return _access_token_cache_cls

sync/clients/sync.py

Lines changed: 4 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,15 @@
1-
import json
21
import logging
3-
from datetime import datetime
4-
from pathlib import Path
5-
from typing import Generator, Optional, Tuple, Type, Callable, Union
2+
from typing import Generator, Optional
63

74
import dateutil.parser
85
import httpx
9-
from platformdirs import user_cache_dir
106

117
from ..config import API_KEY, CONFIG, APIKey
128
from . import USER_AGENT, RetryableHTTPClient, encode_json
13-
from .cache import CachedToken
14-
9+
from .cache import ACCESS_TOKEN_CACHE_CLS_TYPE, FileCachedToken, get_access_token_cache_cache
1510
logger = logging.getLogger(__name__)
1611

1712

18-
class FileCachedToken(CachedToken):
19-
def __init__(self):
20-
self._cache_file = Path(user_cache_dir("syncsparkpy")) / "auth.json"
21-
22-
super().__init__()
23-
24-
def _get_cached_token(self) -> Optional[Tuple[str, datetime]]:
25-
# Cache is optional, we can fail to read it and not worry
26-
if self._cache_file.exists():
27-
try:
28-
cached_token = json.loads(self._cache_file.read_text())
29-
cached_access_token = cached_token["access_token"]
30-
cached_expiry = datetime.fromisoformat(cached_token["expires_at_utc"])
31-
return cached_access_token, cached_expiry
32-
except Exception as e:
33-
logger.warning(
34-
f"Failed to read cached access token @ {self._cache_file}", exc_info=e
35-
)
36-
37-
return None
38-
39-
def _set_cached_token(self) -> None:
40-
# Cache is optional, we can fail to read it and not worry
41-
try:
42-
self._cache_file.parent.mkdir(parents=True, exist_ok=True)
43-
self._cache_file.write_text(
44-
json.dumps(
45-
{
46-
"access_token": self._access_token,
47-
"expires_at_utc": self._access_token_expires_at_utc.isoformat(),
48-
}
49-
)
50-
)
51-
except Exception as e:
52-
logger.warning(
53-
f"Failed to write cached access token @ {self._cache_file}", exc_info=e
54-
)
55-
56-
57-
# Putting this here instead of config.py because circular imports and typing.
58-
_access_token_cache_cls = FileCachedToken # Default to local file caching.
59-
ACCESS_TOKEN_CACHE_CLS_TYPE = Union[Type[CachedToken], Callable[[], CachedToken]]
60-
61-
62-
def set_access_token_cache_cls(access_token_cache_cls: ACCESS_TOKEN_CACHE_CLS_TYPE) -> None:
63-
global _access_token_cache_cls
64-
_access_token_cache_cls = access_token_cache_cls
65-
66-
6713
class SyncAuth(httpx.Auth):
6814
requires_response_body = True
6915

@@ -395,7 +341,7 @@ def get_default_client() -> SyncClient:
395341
_sync_client = SyncClient(
396342
CONFIG.api_url,
397343
API_KEY,
398-
access_token_cache_cls=_access_token_cache_cls
344+
access_token_cache_cls=get_access_token_cache_cache()
399345
)
400346
return _sync_client
401347

@@ -409,6 +355,6 @@ def get_default_async_client() -> ASyncClient:
409355
_async_sync_client = ASyncClient(
410356
CONFIG.api_url,
411357
API_KEY,
412-
access_token_cache_cls=_access_token_cache_cls
358+
access_token_cache_cls=get_access_token_cache_cache()
413359
)
414360
return _async_sync_client

0 commit comments

Comments
 (0)