kleinkram 0.38.1.dev20241120100707__py3-none-any.whl → 0.38.1.dev20241125112529__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.

Potentially problematic release.


This version of kleinkram might be problematic. Click here for more details.

kleinkram/api/client.py CHANGED
@@ -1,13 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
+ from threading import Lock
4
5
  from typing import Any
5
6
 
6
7
  import httpx
7
8
  from kleinkram.auth import Config
8
9
  from kleinkram.config import Credentials
9
- from kleinkram.errors import LOGIN_MESSAGE
10
- from kleinkram.errors import NotAuthenticatedException
10
+ from kleinkram.errors import NotAuthenticated
11
11
 
12
12
  logger = logging.getLogger(__name__)
13
13
 
@@ -21,31 +21,35 @@ class NotLoggedInException(Exception): ...
21
21
 
22
22
 
23
23
  class AuthenticatedClient(httpx.Client):
24
+ _config: Config
25
+ _config_lock: Lock
26
+
24
27
  def __init__(self, *args: Any, **kwargs: Any) -> None:
25
28
  super().__init__(*args, **kwargs)
26
- self.config = Config()
27
29
 
28
- if self.config.has_cli_key:
29
- assert self.config.cli_key, "unreachable"
30
+ self._config = Config()
31
+ self._config_lock = Lock()
32
+
33
+ if self._config.has_cli_key:
34
+ assert self._config.cli_key, "unreachable"
30
35
  logger.info("using cli key...")
31
- self.cookies.set(COOKIE_CLI_KEY, self.config.cli_key)
36
+ self.cookies.set(COOKIE_CLI_KEY, self._config.cli_key)
32
37
 
33
- elif self.config.has_refresh_token:
38
+ elif self._config.has_refresh_token:
34
39
  logger.info("using refresh token...")
35
- assert self.config.auth_token is not None, "unreachable"
36
- self.cookies.set(COOKIE_AUTH_TOKEN, self.config.auth_token)
40
+ assert self._config.auth_token is not None, "unreachable"
41
+ self.cookies.set(COOKIE_AUTH_TOKEN, self._config.auth_token)
37
42
  else:
38
43
  logger.info("not authenticated...")
39
- raise NotAuthenticatedException(self.config.endpoint)
44
+ raise NotAuthenticated
40
45
 
41
46
  def _refresh_token(self) -> None:
42
- if self.config.has_cli_key:
43
- raise RuntimeError
44
-
45
- refresh_token = self.config.refresh_token
46
- if not refresh_token:
47
- raise RuntimeError
47
+ if self._config.has_cli_key:
48
+ raise RuntimeError("cannot refresh token when using cli key auth")
48
49
 
50
+ refresh_token = self._config.refresh_token
51
+ if refresh_token is None:
52
+ raise RuntimeError("no refresh token found")
49
53
  self.cookies.set(COOKIE_REFRESH_TOKEN, refresh_token)
50
54
 
51
55
  logger.info("refreshing token...")
@@ -53,30 +57,35 @@ class AuthenticatedClient(httpx.Client):
53
57
  "/auth/refresh-token",
54
58
  )
55
59
  response.raise_for_status()
56
-
57
60
  new_access_token = response.cookies[COOKIE_AUTH_TOKEN]
58
61
  creds = Credentials(auth_token=new_access_token, refresh_token=refresh_token)
59
62
 
60
63
  logger.info("saving new tokens...")
61
- self.config.save_credentials(creds)
64
+
65
+ with self._config_lock:
66
+ self._config.save_credentials(creds)
67
+
62
68
  self.cookies.set(COOKIE_AUTH_TOKEN, new_access_token)
63
69
 
64
70
  def request(
65
71
  self, method: str, url: str | httpx.URL, *args: Any, **kwargs: Any
66
72
  ) -> httpx.Response:
67
73
  if isinstance(url, httpx.URL):
68
- raise ValueError("url must be a slug")
74
+ raise NotImplementedError(f"`httpx.URL` is not supported {url!r}")
75
+ if not url.startswith("/"):
76
+ url = f"/{url}"
69
77
 
70
78
  # try to do a request
71
- full_url = f"{self.config.endpoint}{url}"
79
+ full_url = f"{self._config.endpoint}{url}"
72
80
  logger.info(f"requesting {method} {full_url}")
73
81
  response = super().request(method, full_url, *args, **kwargs)
82
+
74
83
  logger.info(f"got response {response}")
75
84
 
76
85
  # if the requesting a refresh token fails, we are not logged in
77
86
  if (url == "/auth/refresh-token") and response.status_code == 401:
78
87
  logger.info("got 401, not logged in...")
79
- raise NotLoggedInException(LOGIN_MESSAGE)
88
+ raise NotAuthenticated
80
89
 
81
90
  # otherwise we try to refresh the token
82
91
  if response.status_code == 401:
@@ -84,12 +93,11 @@ class AuthenticatedClient(httpx.Client):
84
93
  try:
85
94
  self._refresh_token()
86
95
  except Exception:
87
- raise NotLoggedInException(LOGIN_MESSAGE)
96
+ raise NotAuthenticated
88
97
 
89
98
  logger.info(f"retrying request {method} {full_url}")
90
99
  resp = super().request(method, full_url, *args, **kwargs)
91
100
  logger.info(f"got response {resp}")
92
101
  return resp
93
-
94
102
  else:
95
103
  return response