github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/clients/python-wrapper/lakefs/config.py (about)

     1  """
     2  Client configuration module
     3  """
     4  
     5  from __future__ import annotations
     6  
     7  import os
     8  from pathlib import Path
     9  from typing import Optional
    10  
    11  import yaml
    12  from lakefs_sdk import Configuration
    13  from lakefs.exceptions import NoAuthenticationFound
    14  from lakefs.namedtuple import LenientNamedTuple
    15  
    16  _LAKECTL_YAML_PATH = os.path.join(Path.home(), ".lakectl.yaml")
    17  _LAKECTL_ENDPOINT_ENV = "LAKECTL_SERVER_ENDPOINT_URL"
    18  _LAKECTL_ACCESS_KEY_ID_ENV = "LAKECTL_CREDENTIALS_ACCESS_KEY_ID"
    19  _LAKECTL_SECRET_ACCESS_KEY_ENV = "LAKECTL_CREDENTIALS_SECRET_ACCESS_KEY"
    20  
    21  
    22  class ClientConfig(Configuration):
    23      """
    24      Configuration class for the SDK Client.
    25      Instantiation will try to get authentication methods using the following chain:
    26  
    27      1. Provided kwargs to __init__ func (should contain necessary credentials as defined in lakefs_sdk.Configuration)
    28      2. Use LAKECTL_SERVER_ENDPOINT_URL, LAKECTL_ACCESS_KEY_ID and LAKECTL_ACCESS_SECRET_KEY if set
    29      3. Try to read ~/.lakectl.yaml if exists
    30      4. TBD: try and use IAM role from current machine (using AWS IAM role will work only with enterprise/cloud)
    31  
    32      This class also encapsulates the required lakectl configuration for authentication and used to unmarshall the
    33      lakectl yaml file.
    34      """
    35  
    36      class Server(LenientNamedTuple):
    37          """
    38          lakectl configuration's server block
    39          """
    40          endpoint_url: str
    41  
    42      class Credentials(LenientNamedTuple):
    43          """
    44          lakectl configuration's credentials block
    45          """
    46          access_key_id: str
    47          secret_access_key: str
    48  
    49      server: Server
    50      credentials: Credentials
    51  
    52      def __init__(self, verify_ssl: Optional[bool] = None, proxy: Optional[str] = None, **kwargs):
    53          super().__init__(**kwargs)
    54          if verify_ssl is not None:
    55              self.verify_ssl = verify_ssl
    56          if proxy is not None:
    57              self.proxy = proxy
    58  
    59          if kwargs:
    60              return
    61  
    62          found = False
    63  
    64          # Get credentials from lakectl
    65          try:
    66              with open(_LAKECTL_YAML_PATH, encoding="utf-8") as fd:
    67                  data = yaml.load(fd, Loader=yaml.Loader)
    68                  self.server = ClientConfig.Server(**data["server"])
    69                  self.credentials = ClientConfig.Credentials(**data["credentials"])
    70              found = True
    71          except FileNotFoundError:  # File not found, fallback to env variables
    72              self.server = ClientConfig.Server(endpoint_url="")
    73              self.credentials = ClientConfig.Credentials(access_key_id="", secret_access_key="")
    74  
    75          endpoint_env = os.getenv(_LAKECTL_ENDPOINT_ENV)
    76          key_env = os.getenv(_LAKECTL_ACCESS_KEY_ID_ENV)
    77          secret_env = os.getenv(_LAKECTL_SECRET_ACCESS_KEY_ENV)
    78  
    79          self.host = endpoint_env if endpoint_env is not None else self.server.endpoint_url
    80          self.username = key_env if key_env is not None else self.credentials.access_key_id
    81          self.password = secret_env if secret_env is not None else self.credentials.secret_access_key
    82          if len(self.username) > 0 and len(self.password) > 0:
    83              found = True
    84  
    85          # TODO: authentication via IAM Role
    86          if not found:
    87              raise NoAuthenticationFound