From 5af7ce8513846004309fa4d5fcf8496d8e8f04a8 Mon Sep 17 00:00:00 2001 From: Christopher Bonilla Date: Thu, 9 Jan 2025 13:15:24 +0100 Subject: [PATCH] feat: optional base64 encoding for local cred When using token from environment variable or file or client secret from file, not all data sources require base64 encoding, i.e. Databricks does not but BigQuery does. Boolean to encode or not added as optional parameter, with default et to True for token for backwards compatability, but False for client secret since it is new use case. JIRA: LX-691 risk: low --- gooddata-sdk/gooddata_sdk/catalog/entity.py | 50 ++++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/gooddata-sdk/gooddata_sdk/catalog/entity.py b/gooddata-sdk/gooddata_sdk/catalog/entity.py index 289d0156c..be3eadf07 100644 --- a/gooddata-sdk/gooddata_sdk/catalog/entity.py +++ b/gooddata-sdk/gooddata_sdk/catalog/entity.py @@ -182,9 +182,23 @@ def from_api(cls, entity: dict[str, Any]) -> TokenCredentialsFromFile: raise NotImplementedError @staticmethod - def token_from_file(file_path: Union[str, Path]) -> str: + def token_from_file(file_path: Union[str, Path], base64_encode: bool = True) -> str: + """ + Reads a token from a file and optionally base64 encodes it. + + Args: + file_path (Union[str, Path]): The path to the file containing the token. + base64_encode (bool): Whether to base64 encode the token. Defaults to True. + + Returns: + str: The token, optionally base64 encoded. + + Raises: + FileNotFoundError: If the file does not exist. + """ with open(file_path, "rb") as fp: - return base64.b64encode(fp.read()).decode("utf-8") + content = fp.read() + return base64.b64encode(content).decode("utf-8") if base64_encode else content.decode("utf-8") @attr.s(auto_attribs=True, kw_only=True) @@ -208,11 +222,24 @@ def from_api(cls, entity: dict[str, Any]) -> TokenCredentialsFromEnvVar: raise NotImplementedError @staticmethod - def token_from_env_var(env_var_name: str) -> str: + def token_from_env_var(env_var_name: str, base64_encode: bool = True) -> str: + """ + Retrieves a token from an environment variable. + + Args: + env_var_name (str): The name of the environment variable containing the token. + base64_encode (bool): Whether to base64 encode the token. Defaults to True for backwards compatibility. + + Returns: + str: The token, optionally base64 encoded. + + Raises: + ValueError: If the environment variable is not set or is empty. + """ token = os.getenv(env_var_name) if token is None or token == "": raise ValueError(f"Environment variable {env_var_name} is not set") - return base64.b64encode(token.encode("utf-8")).decode("utf-8") + return base64.b64encode(token.encode("utf-8")).decode("utf-8") if base64_encode else token @attr.s(auto_attribs=True, kw_only=True) @@ -299,6 +326,17 @@ def from_api(cls, entity: dict[str, Any]) -> ClientSecretCredentialsFromFile: raise NotImplementedError @staticmethod - def client_secret_from_file(file_path: Union[str, Path]) -> str: + def client_secret_from_file(file_path: Union[str, Path], base64_encode: bool = False) -> str: + """ + Reads the client secret from a file. + + Args: + file_path (Union[str, Path]): The path to the file containing the client secret. + base64_encode (bool): Whether to base64 encode the client secret or not. Defaults to False. + + Returns: + str: The client secret, optionally base64 encoded. + """ with open(file_path, "rb") as fp: - return base64.b64encode(fp.read()).decode("utf-8") + content = fp.read() + return base64.b64encode(content).decode("utf-8") if base64_encode else content.decode("utf-8")