sumo-wrapper-python 1.0.26__tar.gz → 1.0.28__tar.gz

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 sumo-wrapper-python might be problematic. Click here for more details.

Files changed (46) hide show
  1. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/PKG-INFO +3 -2
  2. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/_auth_provider.py +17 -4
  3. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/_logging.py +3 -3
  4. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/_retry_strategy.py +2 -2
  5. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/_version.py +2 -2
  6. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/sumo_client.py +34 -24
  7. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo_wrapper_python.egg-info/PKG-INFO +3 -2
  8. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/.github/workflows/build_docs.yaml +0 -0
  9. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/.github/workflows/linting.yml +0 -0
  10. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/.github/workflows/publish_release.yml +0 -0
  11. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/.github/workflows/pytest.yml +0 -0
  12. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/.gitignore +0 -0
  13. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/.pre-commit-config.yaml +0 -0
  14. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/.readthedocs.yaml +0 -0
  15. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/CONTRIBUTING.md +0 -0
  16. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/LICENSE +0 -0
  17. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/README.md +0 -0
  18. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/SECURITY.md +0 -0
  19. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/Makefile +0 -0
  20. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/_static/equinor-logo.png +0 -0
  21. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/_static/equinor-logo2.jpg +0 -0
  22. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/_static/equinor_logo.jpg +0 -0
  23. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/_static/equinor_logo_only.jpg +0 -0
  24. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/_templates/layout.html +0 -0
  25. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/api.rst +0 -0
  26. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/conf.py +0 -0
  27. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/index.rst +0 -0
  28. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/make.bat +0 -0
  29. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/docs/sumo-wrapper-python.rst +0 -0
  30. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/pyproject.toml +0 -0
  31. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/setup.cfg +0 -0
  32. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/__init__.py +0 -0
  33. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/__init__.py +0 -0
  34. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/_blob_client.py +0 -0
  35. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/_decorators.py +0 -0
  36. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/config.py +0 -0
  37. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo/wrapper/login.py +0 -0
  38. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo_wrapper_python.egg-info/SOURCES.txt +0 -0
  39. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo_wrapper_python.egg-info/dependency_links.txt +0 -0
  40. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo_wrapper_python.egg-info/entry_points.txt +0 -0
  41. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo_wrapper_python.egg-info/requires.txt +0 -0
  42. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/src/sumo_wrapper_python.egg-info/top_level.txt +0 -0
  43. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/tests/conftest.py +0 -0
  44. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/tests/test_sumo_thin_client.py +0 -0
  45. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/tests/testdata/case.yml +0 -0
  46. {sumo_wrapper_python-1.0.26 → sumo_wrapper_python-1.0.28}/tests/testdata/surface.yml +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: sumo-wrapper-python
3
- Version: 1.0.26
3
+ Version: 1.0.28
4
4
  Summary: Python wrapper for the Sumo API
5
5
  Author: Equinor
6
6
  License: Apache License
@@ -229,6 +229,7 @@ Requires-Dist: sphinxcontrib-apidoc; extra == "docs"
229
229
  Provides-Extra: dev
230
230
  Requires-Dist: ruff; extra == "dev"
231
231
  Requires-Dist: pre-commit; extra == "dev"
232
+ Dynamic: license-file
232
233
 
233
234
  # sumo-wrapper-python
234
235
 
@@ -7,6 +7,7 @@ import sys
7
7
  import time
8
8
  from datetime import datetime, timedelta, timezone
9
9
  from pathlib import Path
10
+ from typing import Dict
10
11
  from urllib.parse import parse_qs
11
12
 
12
13
  import jwt
@@ -76,10 +77,10 @@ class AuthProvider:
76
77
  # ELSE
77
78
  return result["access_token"]
78
79
 
79
- def get_authorization(self):
80
+ def get_authorization(self) -> Dict:
80
81
  token = self.get_token()
81
82
  if token is None:
82
- return ""
83
+ return {}
83
84
 
84
85
  return {"Authorization": "Bearer " + token}
85
86
 
@@ -101,6 +102,13 @@ class AuthProvider:
101
102
  pass
102
103
 
103
104
 
105
+ class AuthProviderNone(AuthProvider):
106
+ def get_token(self):
107
+ raise Exception("No valid authorization provider found.")
108
+
109
+ pass
110
+
111
+
104
112
  class AuthProviderSilent(AuthProvider):
105
113
  def __init__(self, client_id, authority, resource_id):
106
114
  super().__init__(resource_id)
@@ -423,7 +431,7 @@ def get_auth_provider(
423
431
  refresh_token=None,
424
432
  devicecode=False,
425
433
  case_uuid=None,
426
- ):
434
+ ) -> AuthProvider:
427
435
  if refresh_token:
428
436
  return AuthProviderRefreshToken(
429
437
  refresh_token, client_id, authority, resource_id
@@ -435,6 +443,9 @@ def get_auth_provider(
435
443
  if os.path.exists(get_token_path(resource_id, ".sharedkey", case_uuid)):
436
444
  return AuthProviderSumoToken(resource_id, case_uuid)
437
445
  # ELSE
446
+ if os.path.exists(get_token_path(resource_id, ".sharedkey")):
447
+ return AuthProviderSumoToken(resource_id)
448
+ # ELSE
438
449
  if os.path.exists(get_token_path(resource_id, ".token")):
439
450
  auth_silent = AuthProviderSilent(client_id, authority, resource_id)
440
451
  token = auth_silent.get_token()
@@ -472,6 +483,8 @@ def get_auth_provider(
472
483
  ]
473
484
  ):
474
485
  return AuthProviderManaged(resource_id)
486
+ # ELSE
487
+ return AuthProviderNone(resource_id)
475
488
 
476
489
 
477
490
  def cleanup_shared_keys():
@@ -481,7 +494,7 @@ def cleanup_shared_keys():
481
494
  for f in os.listdir(tokendir):
482
495
  ff = os.path.join(tokendir, f)
483
496
  if os.path.isfile(ff):
484
- (name, ext) = os.path.splitext(ff)
497
+ (_, ext) = os.path.splitext(ff)
485
498
  if ext.lower() == ".sharedkey":
486
499
  try:
487
500
  with open(ff, "r") as file:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from datetime import datetime
2
+ from datetime import datetime, timezone
3
3
 
4
4
 
5
5
  class LogHandlerSumo(logging.Handler):
@@ -11,8 +11,8 @@ class LogHandlerSumo(logging.Handler):
11
11
  def emit(self, record):
12
12
  try:
13
13
  dt = (
14
- datetime.now(datetime.timezone.utc)
15
- .replace(microsecond=0)
14
+ datetime.now(timezone.utc)
15
+ .replace(microsecond=0, tzinfo=None)
16
16
  .isoformat()
17
17
  + "Z"
18
18
  )
@@ -44,7 +44,7 @@ class RetryStrategy:
44
44
  self._exp_base = exp_base
45
45
  return
46
46
 
47
- def make_retryer(self):
47
+ def make_retryer(self) -> tn.Retrying:
48
48
  return tn.Retrying(
49
49
  stop=tn.stop_after_attempt(self._stop_after),
50
50
  retry=(
@@ -63,7 +63,7 @@ class RetryStrategy:
63
63
  before_sleep=_log_retry_info,
64
64
  )
65
65
 
66
- def make_retryer_async(self):
66
+ def make_retryer_async(self) -> tn.AsyncRetrying:
67
67
  return tn.AsyncRetrying(
68
68
  stop=tn.stop_after_attempt(self._stop_after),
69
69
  retry=(
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '1.0.26'
21
- __version_tuple__ = version_tuple = (1, 0, 26)
20
+ __version__ = version = '1.0.28'
21
+ __version_tuple__ = version_tuple = (1, 0, 28)
@@ -3,6 +3,7 @@ import contextlib
3
3
  import logging
4
4
  import re
5
5
  import time
6
+ from typing import Dict, Optional, Tuple
6
7
 
7
8
  import httpx
8
9
  import jwt
@@ -25,11 +26,14 @@ DEFAULT_TIMEOUT = httpx.Timeout(30.0)
25
26
  class SumoClient:
26
27
  """Authenticate and perform requests to the Sumo API."""
27
28
 
29
+ _client: httpx.Client
30
+ _async_client: httpx.AsyncClient
31
+
28
32
  def __init__(
29
33
  self,
30
34
  env: str,
31
- token: str = None,
32
- interactive: bool = False,
35
+ token: Optional[str] = None,
36
+ interactive: bool = True,
33
37
  devicecode: bool = False,
34
38
  verbosity: str = "CRITICAL",
35
39
  retry_strategy=RetryStrategy(),
@@ -119,26 +123,23 @@ class SumoClient:
119
123
  def __enter__(self):
120
124
  return self
121
125
 
122
- def __exit__(self, exc_type, exc_value, traceback):
126
+ def __exit__(self, *_):
123
127
  if not self._borrowed_client:
124
128
  self._client.close()
125
- self._client = None
126
129
  return False
127
130
 
128
131
  async def __aenter__(self):
129
132
  return self
130
133
 
131
- async def __aexit__(self, exc_type, exc_value, traceback):
134
+ async def __aexit__(self, *_):
132
135
  if not self._borrowed_async_client:
133
136
  await self._async_client.aclose()
134
- self._async_client = None
135
137
  return False
136
138
 
137
139
  def __del__(self):
138
140
  if self._client is not None and not self._borrowed_client:
139
141
  self._client.close()
140
142
  pass
141
- self._client = None
142
143
  if self._async_client is not None and not self._borrowed_async_client:
143
144
 
144
145
  async def closeit(client):
@@ -151,7 +152,6 @@ class SumoClient:
151
152
  except RuntimeError:
152
153
  pass
153
154
  pass
154
- self._async_client = None
155
155
 
156
156
  def authenticate(self):
157
157
  if self.auth is None:
@@ -186,7 +186,7 @@ class SumoClient:
186
186
  )
187
187
 
188
188
  @raise_for_status
189
- def get(self, path: str, params: dict = None) -> dict:
189
+ def get(self, path: str, params: Optional[Dict] = None) -> httpx.Response:
190
190
  """Performs a GET-request to the Sumo API.
191
191
 
192
192
  Args:
@@ -247,9 +247,9 @@ class SumoClient:
247
247
  def post(
248
248
  self,
249
249
  path: str,
250
- blob: bytes = None,
251
- json: dict = None,
252
- params: dict = None,
250
+ blob: Optional[bytes] = None,
251
+ json: Optional[dict] = None,
252
+ params: Optional[dict] = None,
253
253
  ) -> httpx.Response:
254
254
  """Performs a POST-request to the Sumo API.
255
255
 
@@ -320,7 +320,10 @@ class SumoClient:
320
320
 
321
321
  @raise_for_status
322
322
  def put(
323
- self, path: str, blob: bytes = None, json: dict = None
323
+ self,
324
+ path: str,
325
+ blob: Optional[bytes] = None,
326
+ json: Optional[dict] = None,
324
327
  ) -> httpx.Response:
325
328
  """Performs a PUT-request to the Sumo API.
326
329
 
@@ -365,7 +368,9 @@ class SumoClient:
365
368
  return retryer(_put)
366
369
 
367
370
  @raise_for_status
368
- def delete(self, path: str, params: dict = None) -> dict:
371
+ def delete(
372
+ self, path: str, params: Optional[dict] = None
373
+ ) -> httpx.Response:
369
374
  """Performs a DELETE-request to the Sumo API.
370
375
 
371
376
  Args:
@@ -402,12 +407,12 @@ class SumoClient:
402
407
 
403
408
  return retryer(_delete)
404
409
 
405
- def _get_retry_details(self, response_in):
410
+ def _get_retry_details(self, response_in) -> Tuple[str, int]:
406
411
  assert response_in.status_code == 202, (
407
412
  "Incorrect status code; expcted 202"
408
413
  )
409
414
  headers = response_in.headers
410
- location = headers.get("location")
415
+ location: str = headers.get("location")
411
416
  assert location is not None, "Missing header: Location"
412
417
  assert location.startswith(self.base_url)
413
418
  retry_after = headers.get("retry-after")
@@ -440,7 +445,6 @@ class SumoClient:
440
445
  )
441
446
  location, retry_after = self._get_retry_details(response)
442
447
  pass
443
- return None # should never get here.
444
448
 
445
449
  def getLogger(self, name):
446
450
  """Gets a logger object that sends log objects into the message_log
@@ -495,7 +499,9 @@ class SumoClient:
495
499
  return self
496
500
 
497
501
  @raise_for_status_async
498
- async def get_async(self, path: str, params: dict = None):
502
+ async def get_async(
503
+ self, path: str, params: Optional[dict] = None
504
+ ) -> httpx.Response:
499
505
  """Performs an async GET-request to the Sumo API.
500
506
 
501
507
  Args:
@@ -556,9 +562,9 @@ class SumoClient:
556
562
  async def post_async(
557
563
  self,
558
564
  path: str,
559
- blob: bytes = None,
560
- json: dict = None,
561
- params: dict = None,
565
+ blob: Optional[bytes] = None,
566
+ json: Optional[dict] = None,
567
+ params: Optional[dict] = None,
562
568
  ) -> httpx.Response:
563
569
  """Performs an async POST-request to the Sumo API.
564
570
 
@@ -630,7 +636,10 @@ class SumoClient:
630
636
 
631
637
  @raise_for_status_async
632
638
  async def put_async(
633
- self, path: str, blob: bytes = None, json: dict = None
639
+ self,
640
+ path: str,
641
+ blob: Optional[bytes] = None,
642
+ json: Optional[dict] = None,
634
643
  ) -> httpx.Response:
635
644
  """Performs an async PUT-request to the Sumo API.
636
645
 
@@ -675,7 +684,9 @@ class SumoClient:
675
684
  return await retryer(_put)
676
685
 
677
686
  @raise_for_status_async
678
- async def delete_async(self, path: str, params: dict = None) -> dict:
687
+ async def delete_async(
688
+ self, path: str, params: Optional[dict] = None
689
+ ) -> httpx.Response:
679
690
  """Performs an async DELETE-request to the Sumo API.
680
691
 
681
692
  Args:
@@ -736,4 +747,3 @@ class SumoClient:
736
747
  )
737
748
  location, retry_after = self._get_retry_details(response)
738
749
  pass
739
- return None # should never get here.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: sumo-wrapper-python
3
- Version: 1.0.26
3
+ Version: 1.0.28
4
4
  Summary: Python wrapper for the Sumo API
5
5
  Author: Equinor
6
6
  License: Apache License
@@ -229,6 +229,7 @@ Requires-Dist: sphinxcontrib-apidoc; extra == "docs"
229
229
  Provides-Extra: dev
230
230
  Requires-Dist: ruff; extra == "dev"
231
231
  Requires-Dist: pre-commit; extra == "dev"
232
+ Dynamic: license-file
232
233
 
233
234
  # sumo-wrapper-python
234
235