lsrestclient 3.4.0__py3-none-any.whl → 3.4.1__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.
lsrestclient/__init__.py CHANGED
@@ -1,3 +1,5 @@
1
- from .exceptions import *
2
- from .response import *
3
1
  from .client import *
2
+ from .exceptions.ConnectionError import *
3
+ from .exceptions.DownStreamError import *
4
+ from .exceptions.raise_errors import *
5
+ from .response import *
lsrestclient/auth.py CHANGED
@@ -1,7 +1,7 @@
1
- from lsrestclient import LsRestClient, DownStreamError
1
+ from lsrestclient import DownStreamError, LsRestClient
2
2
 
3
3
 
4
- def auth_am_login(**kwargs) -> str:
4
+ def auth_am_login(**kwargs: object) -> str:
5
5
  am = LsRestClient.from_env("AM_API_URL", "am", True)
6
6
  r = am.post("/auth/login", body=kwargs)
7
7
  if r.status_code == 200:
lsrestclient/client.py CHANGED
@@ -1,22 +1,20 @@
1
1
  import os
2
+ import re
2
3
  from enum import Enum
3
- from typing import Optional, Dict, Any
4
+ from typing import Any, ClassVar, Dict, Optional
4
5
  from unittest.mock import MagicMock
5
6
 
6
7
  import lsjsonclasses
7
8
  import requests
8
9
  import requests_cache
9
10
  from requests import Response, Session
10
-
11
- import re
12
-
13
11
  from requests_cache import CachedSession, SQLiteCache
14
12
 
15
- from lsrestclient import (
13
+ import lsrestclient.exceptions.ConnectionError
14
+ from lsrestclient.contexts.bearer_token import bearer_token_context
15
+ from lsrestclient.response import (
16
16
  LsRestClientResponse,
17
- exceptions,
18
17
  )
19
- from lsrestclient.contexts.bearer_token import bearer_token_context
20
18
  from lsrestclient.settings import LsRestClientSettings
21
19
 
22
20
  find_parameters_regex = re.compile("{(.*?)}")
@@ -28,7 +26,7 @@ class LsRestClientBackendEnum(str, Enum):
28
26
 
29
27
 
30
28
  class LsRestClient(object):
31
- _clients = {}
29
+ _clients: ClassVar[dict[str, "LsRestClient"]] = {}
32
30
 
33
31
  @classmethod
34
32
  def from_env(
@@ -36,10 +34,10 @@ class LsRestClient(object):
36
34
  env_name: str,
37
35
  name: Optional[str] = None,
38
36
  required: bool = True,
39
- ):
37
+ ) -> "LsRestClient":
40
38
  """
41
39
  Create an instance of the LsRestClient class using environment variables.
42
- It gets globally saved under the given name, so that it can be reused.
40
+ It gets globally saved under the given name so that it can be reused.
43
41
 
44
42
  :param env_name: The name of the environment variable that holds the base URL.
45
43
  :param name: An optional name for the client instance.
@@ -53,7 +51,7 @@ class LsRestClient(object):
53
51
  return cls(base_url=base_url, name=name)
54
52
 
55
53
  @classmethod
56
- def client(cls, name: str):
54
+ def client(cls, name: str) -> "LsRestClient":
57
55
  """
58
56
  Retrieves the LsRestClient instance with the specified name.
59
57
  If a client with the given name does not exist, an exception is raised.
@@ -66,14 +64,14 @@ class LsRestClient(object):
66
64
  except KeyError:
67
65
  raise Exception(f"LsRestClient with name '{name}' not initialized.")
68
66
 
69
- def __repr__(self):
67
+ def __repr__(self) -> str:
70
68
  return f"<LsRestClient name:'{self.name}' base_url:'{self.base_url}'>"
71
69
 
72
70
  def __init__(
73
71
  self,
74
- base_url: str = None,
72
+ base_url: str | None = None,
75
73
  name: str = "default",
76
- headers: dict = None,
74
+ headers: dict | None = None,
77
75
  ignore_bearer_context: bool = False,
78
76
  cache: bool = False,
79
77
  cache_backend: LsRestClientBackendEnum = LsRestClientBackendEnum.sqlite,
@@ -111,7 +109,11 @@ class LsRestClient(object):
111
109
  self.base_headers = {"content-type": "application/json"}
112
110
 
113
111
  with bearer_token_context() as bearer_token:
114
- bearer_headers = {"Authorization": f"Bearer {bearer_token}"} if bearer_token is not None else {}
112
+ bearer_headers = (
113
+ {"Authorization": f"Bearer {bearer_token}"}
114
+ if bearer_token is not None
115
+ else {}
116
+ )
115
117
  self.base_headers.update(bearer_headers)
116
118
  if headers is not None:
117
119
  self.base_headers.update(headers)
@@ -120,7 +122,7 @@ class LsRestClient(object):
120
122
  super().__init__()
121
123
  self._clients[name] = self
122
124
 
123
- def clear_cache(self):
125
+ def clear_cache(self) -> None:
124
126
  if not isinstance(self._session, CachedSession):
125
127
  raise Exception("Cache not enabled.")
126
128
  self._session.cache.clear()
@@ -136,7 +138,7 @@ class LsRestClient(object):
136
138
  def mock_name(client_name: str, method: str, url: str) -> str:
137
139
  return f"{client_name}_{method.upper()}_{url}"
138
140
 
139
- def url_parse_params(self, url: str, params: Optional[dict] = None):
141
+ def url_parse_params(self, url: str, params: Optional[dict] = None) -> str:
140
142
  if params is None:
141
143
  params = {}
142
144
 
@@ -164,7 +166,9 @@ class LsRestClient(object):
164
166
 
165
167
  return f"{self.base_url}{url}"
166
168
 
167
- def caller(self, method: str, url: str, *args, **kwargs) -> LsRestClientResponse:
169
+ def caller(
170
+ self, method: str, url: str, *args: Any, **kwargs: Any
171
+ ) -> LsRestClientResponse:
168
172
  # check mocks
169
173
  mock = self._mocks.get(self.mock_name(self.name, method, url), None)
170
174
  func = mock if mock is not None else self.request
@@ -174,16 +178,17 @@ class LsRestClient(object):
174
178
  # but only just before calling func, because of mock path
175
179
  url = self.url_parse_params(url, kwargs.get("params", {}))
176
180
 
181
+ # noinspection PyTypeChecker
177
182
  return func(method, url, *args, **kwargs)
178
183
 
179
184
  def request(
180
185
  self,
181
186
  method: str,
182
187
  url: str,
183
- *args,
188
+ *args: list,
184
189
  params: Optional[Dict[str, Any]] = None,
185
190
  body: Optional[Dict[str, Any]] = None,
186
- **kwargs,
191
+ **kwargs: dict,
187
192
  ) -> LsRestClientResponse: # pragma: no cover
188
193
  """
189
194
  :param method: The HTTP method to be used for the request.
@@ -244,10 +249,10 @@ class LsRestClient(object):
244
249
  self,
245
250
  method: str,
246
251
  url: str,
247
- *args,
252
+ *args: list,
248
253
  params: Optional[Dict[str, Any]] = None,
249
- **kwargs,
250
- ):
254
+ **kwargs: dict,
255
+ ) -> LsRestClientResponse:
251
256
  full_url = self.full_url(url, params)
252
257
 
253
258
  try:
@@ -270,9 +275,9 @@ class LsRestClient(object):
270
275
  return response
271
276
 
272
277
  except requests.ConnectionError:
273
- raise exceptions.ConnectionError(url=full_url)
278
+ raise lsrestclient.exceptions.ConnectionError.ConnectionError(url=full_url)
274
279
 
275
- def get(self, *args, **kwargs) -> LsRestClientResponse:
280
+ def get(self, *args: Any, **kwargs: Any) -> LsRestClientResponse:
276
281
  """
277
282
  Send a GET request to the specified URL.
278
283
 
@@ -283,7 +288,7 @@ class LsRestClient(object):
283
288
 
284
289
  return self.caller("GET", *args, **kwargs)
285
290
 
286
- def post(self, *args, **kwargs) -> LsRestClientResponse:
291
+ def post(self, *args: Any, **kwargs: Any) -> LsRestClientResponse:
287
292
  """
288
293
  This method is used to send a POST request using the LSRestClient class.
289
294
 
@@ -293,7 +298,7 @@ class LsRestClient(object):
293
298
  """
294
299
  return self.caller("POST", *args, **kwargs)
295
300
 
296
- def put(self, *args, **kwargs) -> LsRestClientResponse:
301
+ def put(self, *args: Any, **kwargs: Any) -> LsRestClientResponse:
297
302
  """
298
303
  This method is used to send a PUT request using the LSRestClient class.
299
304
 
@@ -303,7 +308,7 @@ class LsRestClient(object):
303
308
  """
304
309
  return self.caller("PUT", *args, **kwargs)
305
310
 
306
- def patch(self, *args, **kwargs) -> LsRestClientResponse:
311
+ def patch(self, *args: Any, **kwargs: Any) -> LsRestClientResponse:
307
312
  """
308
313
  Send a PATCH request to the specified URL with the provided arguments.
309
314
 
@@ -313,7 +318,7 @@ class LsRestClient(object):
313
318
  """
314
319
  return self.caller("PATCH", *args, **kwargs)
315
320
 
316
- def delete(self, *args, **kwargs) -> LsRestClientResponse:
321
+ def delete(self, *args: Any, **kwargs: Any) -> LsRestClientResponse:
317
322
  """
318
323
  Deletes a resource using the DELETE method.
319
324
 
@@ -323,7 +328,7 @@ class LsRestClient(object):
323
328
  """
324
329
  return self.caller("DELETE", *args, **kwargs)
325
330
 
326
- def options(self, *args, **kwargs) -> LsRestClientResponse:
331
+ def options(self, *args: Any, **kwargs: Any) -> LsRestClientResponse:
327
332
  """
328
333
  Send an OPTIONS request using the LsRestClient.
329
334
 
@@ -347,16 +352,16 @@ class LsRestClient(object):
347
352
  """
348
353
  return self.request("HEAD", *args, **kwargs)
349
354
 
350
- def mock(self, mock_name: str, mock: MagicMock):
355
+ def mock(self, mock_name: str, mock: MagicMock) -> None:
351
356
  self._mocks[mock_name] = mock
352
357
 
353
- def unmock(self, mock_name: str):
358
+ def unmock(self, mock_name: str) -> None:
354
359
  if mock_name in self._mocks:
355
360
  del self._mocks[mock_name]
356
361
 
357
362
 
358
363
  class LsRestClientTestClient(LsRestClient):
359
- def __init__(self, test_client: Any, name: str = "test-client") -> None:
364
+ def __init__(self, test_client: Any, name: str = "test-client") -> None: # noqa: ANN401
360
365
  super().__init__(base_url=None, name=name)
361
366
  self.test_client = test_client
362
367
 
@@ -364,9 +369,13 @@ class LsRestClientTestClient(LsRestClient):
364
369
  self,
365
370
  method: str,
366
371
  url: str,
367
- *args,
372
+ *args: Any,
368
373
  params: Optional[Dict[str, Any]] = None,
369
- **kwargs,
370
- ):
374
+ **kwargs: Any,
375
+ ) -> LsRestClientResponse:
371
376
  r = self.test_client.request(method, url, *args, params=params, **kwargs)
372
- return LsRestClientResponse(status_code=r.status_code, content=r.content.decode("utf8"), headers=r.headers)
377
+ return LsRestClientResponse(
378
+ status_code=r.status_code,
379
+ content=r.content.decode("utf8"),
380
+ headers=r.headers,
381
+ )
@@ -1,12 +1,14 @@
1
1
  import contextlib
2
2
  import contextvars
3
- from typing import Optional
3
+ from typing import Any, Generator, Optional
4
4
 
5
- bearer_token_value: contextvars.ContextVar[Optional[str]] = contextvars.ContextVar("bearer_token_value", default=None)
5
+ bearer_token_value: contextvars.ContextVar[Optional[str]] = contextvars.ContextVar(
6
+ "bearer_token_value", default=None
7
+ )
6
8
 
7
9
 
8
10
  @contextlib.contextmanager
9
- def bearer_token_provider(bearer_token: str):
11
+ def bearer_token_provider(bearer_token: str) -> Generator[None, Any, None]:
10
12
  """
11
13
  :param bearer_token: The bearer token to set.
12
14
  :return: A context manager that sets the bearer token and resets it when the context is exited.
@@ -17,7 +19,7 @@ def bearer_token_provider(bearer_token: str):
17
19
 
18
20
 
19
21
  @contextlib.contextmanager
20
- def bearer_token_context():
22
+ def bearer_token_context() -> Generator[str | None, Any, None]:
21
23
  """
22
24
  Context manager for handling bearer token.
23
25
 
@@ -0,0 +1,22 @@
1
+ from typing import Optional
2
+
3
+
4
+ class ConnectionError(Exception):
5
+ """Exception class for connection errors.
6
+
7
+ Args:
8
+ url (Optional[str]): The URL that the connection could not be established to.
9
+
10
+ Attributes:
11
+ url (Optional[str]): The URL that the connection could not be established to.
12
+
13
+ Raises:
14
+ ConnectionError: If a connection could not be established to the given URL.
15
+
16
+ """
17
+
18
+ url: str
19
+
20
+ def __init__(self, url: Optional[str] = None) -> None:
21
+ self.url = url
22
+ super().__init__(f"Connection could not be established to '{url}'")
@@ -0,0 +1,12 @@
1
+ class DownStreamError(Exception):
2
+ status_code: int
3
+ url: str
4
+ content: str
5
+
6
+ def __init__(self, url: str, status_code: int, content: str) -> None:
7
+ self.url = url
8
+ self.status_code = status_code
9
+ self.content = content
10
+ super().__init__(
11
+ f"Downstream error calling {self.url}. {self.status_code} {self.content}"
12
+ )
File without changes
@@ -0,0 +1,44 @@
1
+ import contextlib
2
+ import logging
3
+ from typing import List, Optional, Type
4
+
5
+ import pydash
6
+ from webexception.webexception import WebException
7
+
8
+ from lsrestclient.response import LsRestClientResponse
9
+
10
+ log = logging.getLogger(__name__)
11
+
12
+
13
+ @contextlib.contextmanager
14
+ def raise_errors( # noqa: ANN201
15
+ r: LsRestClientResponse, exceptions: Optional[List[Type[Exception]]] = None
16
+ ):
17
+ if exceptions is None:
18
+ exceptions_by_class = {}
19
+ else:
20
+ exceptions_by_class = {e.__name__: e for e in exceptions}
21
+
22
+ if r.status_code < 399:
23
+ yield r
24
+ else:
25
+ try:
26
+ json = r.json()
27
+ except Exception:
28
+ log.error(r.content)
29
+ raise WebException(status_code=r.status_code, detail=r.content)
30
+
31
+ detail = pydash.get(json, "detail", json)
32
+ error_class = pydash.get(detail, "error_class", None)
33
+ if error_class is not None:
34
+ payload = pydash.get(detail, "error_payload", {})
35
+ else:
36
+ error_class = pydash.get(detail, "ERROR_CLASS", None)
37
+ payload = {}
38
+
39
+ if error_class in exceptions_by_class:
40
+ # noinspection PyArgumentList
41
+ e = exceptions_by_class[error_class](**payload)
42
+ raise e
43
+ # backend errors
44
+ raise WebException(status_code=r.status_code, detail=detail)
lsrestclient/fixtures.py CHANGED
@@ -1,10 +1,12 @@
1
- from lsrestclient.mock import lsrestclient_mock_context
1
+ from typing import Any, Generator
2
+
3
+ from lsrestclient.mock import LsRestClientMocker, lsrestclient_mock_context
2
4
 
3
5
  try:
4
6
  import pytest
5
7
 
6
8
  @pytest.fixture
7
- def lsrestclient_mocker():
9
+ def lsrestclient_mocker() -> Generator[LsRestClientMocker, Any, None]:
8
10
  with lsrestclient_mock_context() as mocker:
9
11
  yield mocker
10
12
 
lsrestclient/lsfastapi.py CHANGED
@@ -1,7 +1,8 @@
1
+ import logging
1
2
  from abc import ABC, abstractmethod
3
+ from typing import Any
2
4
 
3
- from lsrestclient import LsRestClient
4
- import logging
5
+ from lsrestclient import LsRestClient, LsRestClientResponse
5
6
 
6
7
  log = logging.getLogger(__name__)
7
8
 
@@ -10,7 +11,7 @@ class LsFastApiClientBase(ABC):
10
11
  _client = None
11
12
  client_name = None
12
13
 
13
- def __init__(self):
14
+ def __init__(self) -> None:
14
15
  pass
15
16
 
16
17
  @classmethod
@@ -18,23 +19,25 @@ class LsFastApiClientBase(ABC):
18
19
  # noinspection PyBroadException
19
20
  try:
20
21
  cls._client = LsRestClient.client(cls.client_name)
21
- except Exception as e: # pragma: no cover
22
+ except Exception: # pragma: no cover
22
23
  # noinspection PyArgumentList
23
24
  cls._client = cls.register()
24
25
  return cls._client
25
26
 
26
27
  @classmethod
27
- def register(cls, base_url: str = None, **kwargs) -> LsRestClient:
28
+ def register(cls, base_url: str | None = None, **kwargs: Any) -> LsRestClient:
28
29
  # noinspection PyArgumentList
29
30
  log.debug(f"Registering {cls.client_name} API client at {base_url}")
30
- cls._client = LsRestClient(name=cls.client_name, base_url=base_url or cls.base_url(), **kwargs)
31
+ cls._client = LsRestClient(
32
+ name=cls.client_name, base_url=base_url or cls.base_url(), **kwargs
33
+ )
31
34
  return cls._client
32
35
 
33
36
  @classmethod
34
- def health(cls):
37
+ def health(cls) -> LsRestClientResponse:
35
38
  return cls.client().get("/healthz")
36
39
 
37
40
  @classmethod
38
41
  @abstractmethod
39
- def base_url(cls):
42
+ def base_url(cls) -> str:
40
43
  raise NotImplementedError
lsrestclient/mock.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import dataclasses
2
2
  from contextlib import contextmanager
3
- from typing import Union
3
+ from typing import Any, Generator, Union
4
4
  from unittest.mock import MagicMock
5
5
 
6
6
  from lsrestclient import LsRestClient
@@ -14,26 +14,35 @@ class LsRestClientMockModel:
14
14
 
15
15
 
16
16
  class LsRestClientMocker(object):
17
- def __init__(self):
17
+ def __init__(self) -> None:
18
18
  super().__init__()
19
19
  self.mocks = {}
20
20
 
21
- def mock(self, client: Union[LsRestClient, str], method: str, url: str, *args, **kwargs):
21
+ def mock(
22
+ self,
23
+ client: Union[LsRestClient, str],
24
+ method: str,
25
+ url: str,
26
+ *args: Any,
27
+ **kwargs: Any,
28
+ ) -> MagicMock:
22
29
  if isinstance(client, str):
23
30
  client = LsRestClient.client(client)
24
31
 
25
32
  mock_name = LsRestClient.mock_name(client.name, method, url)
26
33
  mock = MagicMock(*args, **kwargs)
27
34
  client.mock(mock_name, mock)
28
- self.mocks[mock_name] = LsRestClientMockModel(client=client, mock_name=mock_name, mock=mock)
35
+ self.mocks[mock_name] = LsRestClientMockModel(
36
+ client=client, mock_name=mock_name, mock=mock
37
+ )
29
38
  return mock
30
39
 
31
- def unmock_all(self):
40
+ def unmock_all(self) -> None:
32
41
  for mock_name, mock_model in self.mocks.items():
33
42
  mock_model.client.unmock(mock_name)
34
43
  self.mocks = {}
35
44
 
36
- def unmock(self, client: LsRestClient, method: str, url: str):
45
+ def unmock(self, client: LsRestClient, method: str, url: str) -> None:
37
46
  mock_name = LsRestClient.mock_name(client.name, method, url)
38
47
  mock_model = self.mocks[mock_name]
39
48
  mock_model.client.unmock(mock_name)
@@ -41,7 +50,7 @@ class LsRestClientMocker(object):
41
50
 
42
51
 
43
52
  @contextmanager
44
- def lsrestclient_mock_context():
53
+ def lsrestclient_mock_context() -> Generator[LsRestClientMocker, Any, None]:
45
54
  mocker = LsRestClientMocker()
46
55
  yield mocker
47
56
  mocker.unmock_all()
lsrestclient/response.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import datetime
2
2
  from dataclasses import dataclass
3
- from typing import Optional
3
+ from typing import Any, Optional
4
4
 
5
5
  import lsjsonclasses
6
6
  import pydash
@@ -26,13 +26,13 @@ class LsRestClientResponse:
26
26
 
27
27
  _json: Optional[dict] = None
28
28
 
29
- def json(self):
29
+ def json(self) -> dict[str, Any]:
30
30
  if self._json is None and self.content != "":
31
31
  self._json = lsjsonclasses.LSoftJSONDecoder.loads(self.content)
32
32
  return self._json
33
33
 
34
34
  @classmethod
35
- def from_requests_response(cls, response: Response):
35
+ def from_requests_response(cls, response: Response) -> "LsRestClientResponse":
36
36
  """
37
37
  Create an instance of LsRestClientResponse from a requests Response object.
38
38
 
@@ -50,7 +50,9 @@ class LsRestClientResponse:
50
50
  else:
51
51
  content = response.content.decode("utf8" if encoding is None else encoding)
52
52
 
53
- ret = cls(status_code=response.status_code, content=content, headers=response.headers)
53
+ ret = cls(
54
+ status_code=response.status_code, content=content, headers=response.headers
55
+ )
54
56
  if isinstance(response, CachedResponse):
55
57
  ret.created_at = response.created_at
56
58
  ret.expires = response.expires
@@ -60,7 +62,12 @@ class LsRestClientResponse:
60
62
  return ret
61
63
 
62
64
  @classmethod
63
- def from_dict(cls, status_code: int = 200, data: dict = None, headers: CaseInsensitiveDict = None):
65
+ def from_dict(
66
+ cls,
67
+ status_code: int = 200,
68
+ data: dict | None = None,
69
+ headers: CaseInsensitiveDict = None,
70
+ ) -> "LsRestClientResponse":
64
71
  """
65
72
  Converts a dictionary into an instance of the LsRestClientResponse class.
66
73
 
@@ -1,21 +1,19 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: lsrestclient
3
- Version: 3.4.0
3
+ Version: 3.4.1
4
4
  Summary: REST Api Client
5
- Author: mba
6
- Author-email: bartel@electronic-shop.lu
7
- Requires-Python: >=3.12,<4.0
8
- Classifier: Programming Language :: Python :: 3
5
+ Author-email: mba <bartel@electronic-shop.lu>
6
+ Requires-Python: >=3.13
7
+ Requires-Dist: lsjsonclasses<3.0.0,>=2.0.1
8
+ Requires-Dist: pydantic-settings<3.0.0,>=2.10.1
9
+ Requires-Dist: pydantic<3.0.0,>=2.11.7
10
+ Requires-Dist: pydash>4.0.0
11
+ Requires-Dist: redis<7.0.0,>=6.4.0
12
+ Requires-Dist: requests-cache<2.0.0,>=1.2.1
13
+ Requires-Dist: requests<3.0.0,>=2.31.0
14
+ Requires-Dist: webexception<2.0.0,>=1.0.5
9
15
  Provides-Extra: redis
10
- Requires-Dist: fastapi-lsoft (>=1.2.0,<2.0.0)
11
- Requires-Dist: lsjsonclasses (>=2.0.1,<3.0.0)
12
- Requires-Dist: pydantic (>=2.11.7,<3.0.0)
13
- Requires-Dist: pydantic-settings (>=2.10.1,<3.0.0)
14
- Requires-Dist: pydash (>4.0.0)
15
- Requires-Dist: redis (>=6.4.0,<7.0.0) ; extra == "redis"
16
- Requires-Dist: requests (>=2.31.0,<3.0.0)
17
- Requires-Dist: requests-cache (>=1.2.1,<2.0.0)
18
- Requires-Dist: webexception (>=1.0.5,<2.0.0)
16
+ Requires-Dist: redis; extra == 'redis'
19
17
  Description-Content-Type: text/markdown
20
18
 
21
19
  # lsrestclient
@@ -110,4 +108,3 @@ For open source projects, say how it is licensed.
110
108
 
111
109
  ## Project status
112
110
  If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
113
-
@@ -0,0 +1,18 @@
1
+ lsrestclient/__init__.py,sha256=J09z2822ZVQWCfJw9Dz3DrpJY9kvMfZThHIVhEPvovU,169
2
+ lsrestclient/auth.py,sha256=E87G8PXi5mnj_fY5NuILRvQdV_zLVTyBw0ZjpmZDWrI,475
3
+ lsrestclient/client.py,sha256=tng4clgRM9uPpvNZVHfOUpq7Bb6jcPyRsRMDEzs0iik,14353
4
+ lsrestclient/fixtures.py,sha256=huiw8-mnemFHeQGypK9n-OWqutAWZI7sBWWtwQqbYLs,338
5
+ lsrestclient/lsfastapi.py,sha256=7Bnrt8pbojJ7FbBbpHTgf56xdywgfbkYcOU6WkBjGU0,1197
6
+ lsrestclient/mock.py,sha256=ebyI5bD7n0Txzi6FkS7gaAVUPcXHRcy9kDNkivHY0zQ,1560
7
+ lsrestclient/response.py,sha256=qAbCMHi-XX19S7Rc71rl4b31CUqFbK5UpQqiUh8M3M4,2847
8
+ lsrestclient/settings.py,sha256=qRhQYFCOA8sKhejrd7r47Q4Vo6mQjLbXko7jv3_889A,350
9
+ lsrestclient/contexts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ lsrestclient/contexts/bearer_token.py,sha256=hmYmr5hmeliBTrP2n9AmKf1E4Vk61lcSyDrvNTkF6HE,841
11
+ lsrestclient/exceptions/ConnectionError.py,sha256=W0Ys80aElrDAbv-xf4wiMlU-4iJaji5I63V92HUEJnk,601
12
+ lsrestclient/exceptions/DownStreamError.py,sha256=AvxQ8uu9XodRf5njnies9MHFVpzpCdJmNOEe8Z95WVk,375
13
+ lsrestclient/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ lsrestclient/exceptions/raise_errors.py,sha256=LPemwueHxOQwf3WDaM0apI5aRADxNuPxSxAztC8pblc,1323
15
+ lsrestclient-3.4.1.dist-info/METADATA,sha256=zIDRJw9VEcEjeRAYzALXCJWkzCOaCZ53kc1iVi7ZMcg,6752
16
+ lsrestclient-3.4.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
+ lsrestclient-3.4.1.dist-info/entry_points.txt,sha256=6lmLua-CwRxXMA6iG5veLwIFbtUBhhypD5RI_2lv5Ms,48
18
+ lsrestclient-3.4.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.5.2
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [pytest11]
2
+ lsrestclient = lsrestclient.fixtures
@@ -1,73 +0,0 @@
1
- import contextlib
2
- import logging
3
- from typing import Optional, List, Type
4
-
5
- import pydash
6
- from webexception.webexception import WebException
7
-
8
- log = logging.getLogger(__name__)
9
-
10
-
11
- # noinspection PyShadowingBuiltins
12
- class ConnectionError(Exception):
13
- """Exception class for connection errors.
14
-
15
- Args:
16
- url (Optional[str]): The URL that the connection could not be established to.
17
-
18
- Attributes:
19
- url (Optional[str]): The URL that the connection could not be established to.
20
-
21
- Raises:
22
- ConnectionError: If a connection could not be established to the given URL.
23
-
24
- """
25
-
26
- url: str
27
-
28
- def __init__(self, url: Optional[str] = None) -> None:
29
- self.url = url
30
- super().__init__(f"Connection could not be established to '{url}'")
31
-
32
-
33
- class DownStreamError(Exception):
34
- status_code: int
35
- url: str
36
- content: str
37
-
38
- def __init__(self, url: str, status_code: int, content: str) -> None:
39
- self.url = url
40
- self.status_code = status_code
41
- self.content = content
42
- super().__init__(f"Downstream error calling {self.url}. {self.status_code} {self.content}")
43
-
44
-
45
- @contextlib.contextmanager
46
- def raise_errors(r, exceptions: Optional[List[Type[Exception]]] = None):
47
- if exceptions is None:
48
- exceptions_by_class = {}
49
- else:
50
- exceptions_by_class = {e.__name__: e for e in exceptions}
51
-
52
- if r.status_code < 399:
53
- yield r
54
- else:
55
- try:
56
- json = r.json()
57
- except Exception as e:
58
- log.error(r.content)
59
- raise WebException(status_code=r.status_code, detail=r.content)
60
-
61
- detail = pydash.get(json, "detail", json)
62
- error_class = pydash.get(detail, "error_class", None)
63
- if error_class is not None:
64
- payload = pydash.get(detail, "error_payload", {})
65
- else:
66
- error_class = pydash.get(detail, "ERROR_CLASS", None)
67
- payload = {}
68
-
69
- if error_class in exceptions_by_class:
70
- e = exceptions_by_class[error_class](**payload)
71
- raise e
72
- # backend errors
73
- raise WebException(status_code=r.status_code, detail=detail)
@@ -1,15 +0,0 @@
1
- lsrestclient/__init__.py,sha256=lI62SHmG0m-iukB5UEwdN5dO4cKnDasOt-TmR1rgaWI,72
2
- lsrestclient/auth.py,sha256=IC6niEht-xB_wC7da0HIeM05Ha785qhls-Q39P6dMHQ,467
3
- lsrestclient/client.py,sha256=oBrzclu96e9hAMXLcJBAOfKb0qsy55TVvOZ6S48XTas,13822
4
- lsrestclient/contexts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- lsrestclient/contexts/bearer_token.py,sha256=GZZOzAI2Ng_9DvFCbhv1Wwb8wJ1AYCca3fQeNtt2NaU,753
6
- lsrestclient/exceptions.py,sha256=exJd1BfygNkkAqekmWepVXvXlMiOInVzPRnq7TmPURs,2149
7
- lsrestclient/fixtures.py,sha256=dFkAYQXL6xqTOwRofb03Nsu_cIjq1sG10Rh8dxWfz9s,239
8
- lsrestclient/lsfastapi.py,sha256=Hn-PgV8RKifa0BbNZzbuK-FCVbJpFmUIpItxZbivd0A,1084
9
- lsrestclient/mock.py,sha256=Ya12F0t5sXHTSt-X4jDDj5ILJx6y6QaBAMXutQMsIRI,1376
10
- lsrestclient/response.py,sha256=4DYeN9e7phcrbm0QwwQS7uBI-sTDq7bKkP28BRWCzqA,2704
11
- lsrestclient/settings.py,sha256=qRhQYFCOA8sKhejrd7r47Q4Vo6mQjLbXko7jv3_889A,350
12
- lsrestclient-3.4.0.dist-info/METADATA,sha256=g4m0vVv1vbO0oSFjmXQwr4yWGyX-Ghb7oj8gdxMdoU8,6862
13
- lsrestclient-3.4.0.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
14
- lsrestclient-3.4.0.dist-info/entry_points.txt,sha256=7lN1XN3lq5Jv5PlpOdIlFrLlFlwzE5MaEWSgMhKASOM,47
15
- lsrestclient-3.4.0.dist-info/RECORD,,
@@ -1,3 +0,0 @@
1
- [pytest11]
2
- lsrestclient=lsrestclient.fixtures
3
-