22
33import logging
44from collections import abc
5+ from pathlib import Path
56from threading import Lock
67from typing import Any
78from typing import List
1314import httpx
1415from httpx ._types import PrimitiveData
1516
17+ import kleinkram .errors
18+ from kleinkram ._version import __version__
19+ from kleinkram .config import CONFIG_PATH
1620from kleinkram .config import Config
1721from kleinkram .config import Credentials
1822from kleinkram .config import get_config
2630COOKIE_REFRESH_TOKEN = "refreshtoken"
2731COOKIE_API_KEY = "clikey"
2832
33+ CLI_VERSION_HEADER = "Kleinkram-Client-Version"
34+
2935
3036Data = Union [PrimitiveData , Any ]
3137NestedData = Mapping [str , Data ]
@@ -65,10 +71,12 @@ class AuthenticatedClient(httpx.Client):
6571 _config : Config
6672 _config_lock : Lock
6773
68- def __init__ (self , * args : Any , ** kwargs : Any ) -> None :
74+ def __init__ (
75+ self , config_path : Path = CONFIG_PATH , * args : Any , ** kwargs : Any
76+ ) -> None :
6977 super ().__init__ (* args , ** kwargs )
7078
71- self ._config = get_config ()
79+ self ._config = get_config (path = config_path )
7280 self ._config_lock = Lock ()
7381
7482 if self ._config .credentials is None :
@@ -95,9 +103,7 @@ def _refresh_token(self) -> None:
95103 self .cookies .set (COOKIE_REFRESH_TOKEN , refresh_token )
96104
97105 logger .info ("refreshing token..." )
98- response = self .post (
99- "/auth/refresh-token" ,
100- )
106+ response = self .post ("/auth/refresh-token" )
101107 response .raise_for_status ()
102108 new_access_token = response .cookies [COOKIE_AUTH_TOKEN ]
103109 creds = Credentials (auth_token = new_access_token , refresh_token = refresh_token )
@@ -110,6 +116,22 @@ def _refresh_token(self) -> None:
110116
111117 self .cookies .set (COOKIE_AUTH_TOKEN , new_access_token )
112118
119+ def _send_request_with_kleinkram_headers (
120+ self , * args : Any , ** kwargs : Any
121+ ) -> httpx .Response :
122+ # add the cli version to the headers
123+ headers = kwargs .get ("headers" ) or {}
124+ headers .setdefault (CLI_VERSION_HEADER , __version__ )
125+ kwargs ["headers" ] = headers
126+
127+ # send the request
128+ response = super ().request (* args , ** kwargs )
129+
130+ # check version compatibility
131+ if response .status_code == 426 :
132+ raise kleinkram .errors .UpdateCLIVersion
133+ return response
134+
113135 def request (
114136 self ,
115137 method : str ,
@@ -128,7 +150,7 @@ def request(
128150 logger .info (f"requesting { method } { full_url } " )
129151
130152 httpx_params = _convert_query_params_to_httpx_format (params or {})
131- response = super (). request (
153+ response = self . _send_request_with_kleinkram_headers (
132154 method , full_url , params = httpx_params , * args , ** kwargs
133155 )
134156
@@ -148,10 +170,10 @@ def request(
148170 raise NotAuthenticated
149171
150172 logger .info (f"retrying request { method } { full_url } " )
151- resp = super (). request (
173+ response = self . _send_request_with_kleinkram_headers (
152174 method , full_url , params = httpx_params , * args , ** kwargs
153175 )
154- logger .info (f"got response { resp } " )
155- return resp
176+ logger .info (f"got response { response } " )
177+ return response
156178 else :
157179 return response
0 commit comments