Skip to content

Commit 446013f

Browse files
authored
Merge branch 'main' into feat/attempt-other-auth-flow-if-sharedkey-is-invalid
2 parents 345a1e9 + 8c4d4a4 commit 446013f

3 files changed

Lines changed: 48 additions & 75 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
__pycache__/
22
*.py[cod]
33
.DS_Store
4+
.idea*
45
*~
56
_venv
67
venv

src/sumo/wrapper/config.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/sumo/wrapper/sumo_client.py

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import asyncio
22
import contextlib
33
import logging
4+
import os
45
import re
56
import time
67
from typing import Dict, Optional, Tuple
@@ -16,12 +17,15 @@
1617
)
1718
from ._logging import LogHandlerSumo
1819
from ._retry_strategy import RetryStrategy
19-
from .config import APP_REGISTRATION, AUTHORITY_HOST_URI, TENANT_ID
2020

2121
logger = logging.getLogger("sumo.wrapper")
2222

2323
DEFAULT_TIMEOUT = httpx.Timeout(30.0)
2424

25+
WELL_KNOWN = os.environ.get(
26+
"SUMOCONNECTIONINFO", "https://api.sumo.equinor.com/well-known"
27+
)
28+
2529

2630
class SumoClient:
2731
"""Authenticate and perform requests to the Sumo API."""
@@ -31,7 +35,7 @@ class SumoClient:
3135

3236
def __init__(
3337
self,
34-
env: str,
38+
env: str = "prod",
3539
token: Optional[str] = None,
3640
interactive: bool = True,
3741
devicecode: bool = False,
@@ -41,22 +45,46 @@ def __init__(
4145
case_uuid=None,
4246
http_client=None,
4347
async_http_client=None,
48+
client_id: Optional[str] = None,
4449
):
4550
"""Initialize a new Sumo object
4651
4752
Args:
48-
env: Sumo environment
49-
token: Access token or refresh token.
50-
interactive: Enable interactive authentication (in browser).
51-
If not enabled, code grant flow will be used.
52-
verbosity: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
53+
env (str): Sumo environment. Defaults to "prod".
54+
token (Optional[str]): Access token or refresh token. Defaults to None.
55+
interactive (bool): Enable interactive authentication (in browser).
56+
If not enabled, code grant flow will be used. Defaults to True.
57+
devicecode (bool): Enable device code flow. Defaults to False.
58+
verbosity (str): Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL).
59+
Defaults to "CRITICAL".
60+
retry_strategy (RetryStrategy): Retry strategy for HTTP requests.
61+
Defaults to RetryStrategy().
62+
timeout (int): Timeout for HTTP requests. Defaults to DEFAULT_TIMEOUT.
63+
case_uuid (Optional[str]): Case UUID for authentication. Defaults to None.
64+
http_client (Optional[httpx.Client]): HTTP client for synchronous requests.
65+
Defaults to None.
66+
async_http_client (Optional[httpx.AsyncClient]): HTTP client for asynchronous requests.
67+
Defaults to None.
68+
client_id (Optional[str]): Client ID for authentication. If None, will use
69+
AZURE_CLIENT_ID from environment variables or the config. Defaults to None.
5370
"""
5471

5572
logger.setLevel(verbosity)
5673

57-
if env not in APP_REGISTRATION:
74+
well_known = httpx.get(WELL_KNOWN).json()
75+
if env not in well_known["envs"]:
5876
raise ValueError(f"Invalid environment: {env}")
5977

78+
tenant_id = well_known["tenant_id"]
79+
authority_host = well_known["authority"]
80+
config = well_known["envs"][env]
81+
resource_id = config["resource_id"]
82+
base_url = config["base_url"]
83+
self.client_id = (
84+
client_id
85+
or os.environ.get("AZURE_CLIENT_ID")
86+
or config["client_id"]
87+
)
6088
self.env = env
6189
self._verbosity = verbosity
6290

@@ -100,49 +128,19 @@ def __init__(
100128
pass
101129
pass
102130

103-
if env == "prod":
104-
self.base_url = "https://api.sumo.equinor.com/api/v1"
105-
elif env == "localhost":
106-
self.base_url = "http://localhost:8084/api/v1"
107-
else:
108-
self.base_url = (
109-
f"https://main-sumo-core-{env}.c3.radix.equinor.com/api/v1"
110-
)
111131
cleanup_shared_keys()
132+
self.auth = get_auth_provider(
133+
client_id=self.client_id,
134+
authority=f"{authority_host}{tenant_id}",
135+
resource_id=resource_id,
136+
interactive=interactive,
137+
refresh_token=refresh_token,
138+
access_token=access_token,
139+
devicecode=devicecode,
140+
case_uuid=case_uuid,
141+
)
112142

113-
def _get_auth_provider():
114-
return get_auth_provider(
115-
client_id=APP_REGISTRATION[env]["CLIENT_ID"],
116-
authority=f"{AUTHORITY_HOST_URI}/{TENANT_ID}",
117-
resource_id=APP_REGISTRATION[env]["RESOURCE_ID"],
118-
interactive=interactive,
119-
refresh_token=refresh_token,
120-
access_token=access_token,
121-
devicecode=devicecode,
122-
case_uuid=case_uuid,
123-
)
124-
125-
def _try_setup_auth_provider():
126-
self.auth = _get_auth_provider()
127-
response = httpx.get(
128-
url=self.base_url + "/userpermissions",
129-
headers=self.auth.get_authorization(),
130-
)
131-
if response.is_success:
132-
return True, False
133-
134-
elif response.status_code == 401:
135-
return False, self.auth.delete_token()
136-
137-
else:
138-
raise httpx.HTTPStatusError
139-
140-
ok, retry = _try_setup_auth_provider()
141-
if retry:
142-
ok, retry = _try_setup_auth_provider()
143-
if retry:
144-
ok, retry = _try_setup_auth_provider()
145-
143+
self.base_url = base_url
146144
return
147145

148146
def __enter__(self):

0 commit comments

Comments
 (0)