From 5d23f6a1361982969d3287a857a70458a176dc6f Mon Sep 17 00:00:00 2001 From: Raymond Wiker Date: Wed, 18 Dec 2024 13:51:06 +0100 Subject: [PATCH 1/6] feat: add method to create and store a shared access key for a specific case, and extend the constructor to allow the use of this key. --- src/sumo/wrapper/_auth_provider.py | 9 +++++++++ src/sumo/wrapper/sumo_client.py | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/sumo/wrapper/_auth_provider.py b/src/sumo/wrapper/_auth_provider.py index 20fcc2c..f9b23c3 100644 --- a/src/sumo/wrapper/_auth_provider.py +++ b/src/sumo/wrapper/_auth_provider.py @@ -66,6 +66,11 @@ def get_authorization(self): return {"Authorization": "Bearer " + token} + def store_shared_access_key_for_case(self, case_uuid, token): + with open(get_token_path(self._resource_id + "+" + case_uuid, + ".sharedkey"), "w") as f: + f.write(token) + pass @@ -394,6 +399,7 @@ def get_auth_provider( access_token=None, refresh_token=None, devicecode=False, + case_uuid = None, ): if refresh_token: return AuthProviderRefreshToken( @@ -403,6 +409,9 @@ def get_auth_provider( if access_token: return AuthProviderAccessToken(access_token) # ELSE + if case_uuid is not None and os.path.exists(get_token_path(resource_id + "+" + case_uuid, ".sharedkey")): + return AuthProviderSumoToken(resource_id + "+" + case_uuid) + # ELSE if os.path.exists(get_token_path(resource_id, ".sharedkey")): return AuthProviderSumoToken(resource_id) # ELSE diff --git a/src/sumo/wrapper/sumo_client.py b/src/sumo/wrapper/sumo_client.py index 5096e1c..0b86f91 100644 --- a/src/sumo/wrapper/sumo_client.py +++ b/src/sumo/wrapper/sumo_client.py @@ -33,6 +33,7 @@ def __init__( verbosity: str = "CRITICAL", retry_strategy=RetryStrategy(), timeout=DEFAULT_TIMEOUT, + case_uuid = None, ): """Initialize a new Sumo object @@ -85,6 +86,7 @@ def __init__( refresh_token=refresh_token, access_token=access_token, devicecode=devicecode, + case_uuid = case_uuid, ) if env == "localhost": @@ -398,6 +400,22 @@ def getLogger(self, name): pass return logger + def create_shared_access_key_for_case(self, case_uuid): + """Creates and stores a shared access key that can be used to access + the case identified by *case_uuid*, in the current Sumo environment. + + This shared access key can then be used by instantiating + SumoClient with the parameter case_uuid set accordingly. + + Args: + case_uuid: the uuid for a case. + + Side effects: + Creates a new file in ~/.sumo, named {app_id}+{case_uuid} + """ + token = self.get(f"/objects('{case_uuid}')/make-shared-access-key").text + self.auth.store_shared_access_key_for_case(case_uuid, token) + @raise_for_status_async async def get_async(self, path: str, params: dict = None): """Performs an async GET-request to the Sumo API. From 34d8e36975c548e462acee0a0dcf911f1305ace0 Mon Sep 17 00:00:00 2001 From: Raymond Wiker Date: Thu, 19 Dec 2024 08:15:50 +0100 Subject: [PATCH 2/6] chore: ruff format. --- src/sumo/wrapper/_auth_provider.py | 12 ++++++++---- src/sumo/wrapper/sumo_client.py | 8 +++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/sumo/wrapper/_auth_provider.py b/src/sumo/wrapper/_auth_provider.py index f9b23c3..43d086b 100644 --- a/src/sumo/wrapper/_auth_provider.py +++ b/src/sumo/wrapper/_auth_provider.py @@ -67,8 +67,10 @@ def get_authorization(self): return {"Authorization": "Bearer " + token} def store_shared_access_key_for_case(self, case_uuid, token): - with open(get_token_path(self._resource_id + "+" + case_uuid, - ".sharedkey"), "w") as f: + with open( + get_token_path(self._resource_id + "+" + case_uuid, ".sharedkey"), + "w", + ) as f: f.write(token) pass @@ -399,7 +401,7 @@ def get_auth_provider( access_token=None, refresh_token=None, devicecode=False, - case_uuid = None, + case_uuid=None, ): if refresh_token: return AuthProviderRefreshToken( @@ -409,7 +411,9 @@ def get_auth_provider( if access_token: return AuthProviderAccessToken(access_token) # ELSE - if case_uuid is not None and os.path.exists(get_token_path(resource_id + "+" + case_uuid, ".sharedkey")): + if case_uuid is not None and os.path.exists( + get_token_path(resource_id + "+" + case_uuid, ".sharedkey") + ): return AuthProviderSumoToken(resource_id + "+" + case_uuid) # ELSE if os.path.exists(get_token_path(resource_id, ".sharedkey")): diff --git a/src/sumo/wrapper/sumo_client.py b/src/sumo/wrapper/sumo_client.py index 0b86f91..c3a94ff 100644 --- a/src/sumo/wrapper/sumo_client.py +++ b/src/sumo/wrapper/sumo_client.py @@ -33,7 +33,7 @@ def __init__( verbosity: str = "CRITICAL", retry_strategy=RetryStrategy(), timeout=DEFAULT_TIMEOUT, - case_uuid = None, + case_uuid=None, ): """Initialize a new Sumo object @@ -86,7 +86,7 @@ def __init__( refresh_token=refresh_token, access_token=access_token, devicecode=devicecode, - case_uuid = case_uuid, + case_uuid=case_uuid, ) if env == "localhost": @@ -413,7 +413,9 @@ def create_shared_access_key_for_case(self, case_uuid): Side effects: Creates a new file in ~/.sumo, named {app_id}+{case_uuid} """ - token = self.get(f"/objects('{case_uuid}')/make-shared-access-key").text + token = self.get( + f"/objects('{case_uuid}')/make-shared-access-key" + ).text self.auth.store_shared_access_key_for_case(case_uuid, token) @raise_for_status_async From c0a76d19d5d383453f37d29725c9eb61921c46fc Mon Sep 17 00:00:00 2001 From: Raymond Wiker Date: Thu, 19 Dec 2024 11:54:47 +0100 Subject: [PATCH 3/6] Capture and expose env as a property of SumoClient. --- src/sumo/wrapper/sumo_client.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sumo/wrapper/sumo_client.py b/src/sumo/wrapper/sumo_client.py index c3a94ff..b473fc9 100644 --- a/src/sumo/wrapper/sumo_client.py +++ b/src/sumo/wrapper/sumo_client.py @@ -50,6 +50,8 @@ def __init__( if env not in APP_REGISTRATION: raise ValueError(f"Invalid environment: {env}") + self.env = env + self._retry_strategy = retry_strategy self._client = httpx.Client() self._async_client = httpx.AsyncClient() From 430d5453e0cc031c32c666b4b003b5403b0264d0 Mon Sep 17 00:00:00 2001 From: Raymond Wiker Date: Thu, 19 Dec 2024 12:03:27 +0100 Subject: [PATCH 4/6] Add method for cloning a SumoClient for use with a specific case_uuid. --- src/sumo/wrapper/sumo_client.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sumo/wrapper/sumo_client.py b/src/sumo/wrapper/sumo_client.py index b473fc9..3ff70b4 100644 --- a/src/sumo/wrapper/sumo_client.py +++ b/src/sumo/wrapper/sumo_client.py @@ -51,6 +51,7 @@ def __init__( raise ValueError(f"Invalid environment: {env}") self.env = env + self._verbosity = verbosity self._retry_strategy = retry_strategy self._client = httpx.Client() @@ -420,6 +421,13 @@ def create_shared_access_key_for_case(self, case_uuid): ).text self.auth.store_shared_access_key_for_case(case_uuid, token) + def client_for_case(self, case_uuid): + """Instantiate and return new SumoClient for accessing the + case identified by "case_uuid*.""" + return SumoClient(env=self.env, verbosity=self._verbosity, + retry_strategy=self._retry_strategy, + timeout=self._timeout, case_uuid=case_uuid) + @raise_for_status_async async def get_async(self, path: str, params: dict = None): """Performs an async GET-request to the Sumo API. From 889031b49244cd9b2baf26f169c3f49807aa31ae Mon Sep 17 00:00:00 2001 From: Raymond Wiker Date: Thu, 19 Dec 2024 12:53:27 +0100 Subject: [PATCH 5/6] chore: ruff format (again). --- src/sumo/wrapper/sumo_client.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sumo/wrapper/sumo_client.py b/src/sumo/wrapper/sumo_client.py index 3ff70b4..627c6f5 100644 --- a/src/sumo/wrapper/sumo_client.py +++ b/src/sumo/wrapper/sumo_client.py @@ -424,9 +424,13 @@ def create_shared_access_key_for_case(self, case_uuid): def client_for_case(self, case_uuid): """Instantiate and return new SumoClient for accessing the case identified by "case_uuid*.""" - return SumoClient(env=self.env, verbosity=self._verbosity, - retry_strategy=self._retry_strategy, - timeout=self._timeout, case_uuid=case_uuid) + return SumoClient( + env=self.env, + verbosity=self._verbosity, + retry_strategy=self._retry_strategy, + timeout=self._timeout, + case_uuid=case_uuid, + ) @raise_for_status_async async def get_async(self, path: str, params: dict = None): From 74df5ef410c57bed03a84d8fe5a4d50f1275a5de Mon Sep 17 00:00:00 2001 From: Raymond Wiker Date: Thu, 19 Dec 2024 13:20:23 +0100 Subject: [PATCH 6/6] Typo. --- src/sumo/wrapper/sumo_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sumo/wrapper/sumo_client.py b/src/sumo/wrapper/sumo_client.py index 627c6f5..b5eddaa 100644 --- a/src/sumo/wrapper/sumo_client.py +++ b/src/sumo/wrapper/sumo_client.py @@ -423,7 +423,7 @@ def create_shared_access_key_for_case(self, case_uuid): def client_for_case(self, case_uuid): """Instantiate and return new SumoClient for accessing the - case identified by "case_uuid*.""" + case identified by *case_uuid*.""" return SumoClient( env=self.env, verbosity=self._verbosity,