Friday 19 March 2021

Calling function of an R6 class within the initialize of R6

I am trying to build a reference implementation of our internal tooling for database connection boilerplate coding in R for other data scientists and data analyst

Our software developers made something similar to this in python:

class DataRepository:

    def __init__(self):
        if user is not None and account is not None and password is not None and warehouse is not None and role is not None and database is not None and schema is not None:
            self.ctx = snowflake.connector.connect(
                user=user,
                password=password,
                account=account,
                role=role,
                database=database,
                schema=schema,
                warehouse=warehouse,
                login_timeout=login_timeout,
                ocsp_fail_open=ocsp_fail_open
            )
        else:
            secret_str = self.get_secrets()

            self.ctx = snowflake.connector.connect(
                user=secret_str['user'],
                password=secret_str['password'],
                account=secret_str['account'],
                role=secret_str['role'],
                database=secret_str['database'],
                schema=secret_str['schema'],
                warehouse=secret_str['warehouse'],
                login_timeout=login_timeout,
                ocsp_fail_open=ocsp_fail_open
            )

    def get_secrets(self):
        my_session = boto3.session.Session(region_name=AWS_DEFAULT_REGION)
        client = my_session.client(
            service_name='secretsmanager',
            region_name=AWS_DEFAULT_REGION,
        )
        get_secret_value_response = client.get_secret_value(
            SecretId=SECRET_NAME
        )
        secret_str = json.loads(get_secret_value_response['SecretString'])
        return secret_str

I was trying to reproduce this with S3 as:

DataRepository <-
  R6Class(
    classname = "DataRepository",
    public = list(
      ctx = NULL,
      secrets = NULL,
      initialize = function() {
        if (length(user) == 1 &
            length(account) == 1 & length(password) == 1
            &
            length(warehouse) == 1 &
            length(role) == 1 & length(database) == 1) {
          self$ctx <- dbConnect(
            odbc::odbc(),
            Driver = "SnowflakeDSIIDriver",
            Database = database,
            Uid = user,
            Pwd = password,
            Server = paste0(account, ".snowflakecomputing.com"),
            role = role
          )
        } else {
          secret_dict <- self$getSecrets()
          self$ctx <- dbConnect(
            odbc::odbc(),
            Driver = secret_dict$user,
            Database = secret_dict$database,
            Uid = secret_dict$user,
            Pwd = secret_dict$password,
            Server = paste0(secret_dict$account, ".snowflakecomputing.com"),
            role = secret_dict$account
          )
        }
      },
      getSecrets = function() {
        secrets_client <- paws::secretsmanager(config =
                                                 list(region = AWS_REGION))
        get_secret_value_response <- secrets_client$get_secret_value(SecretId = SECRETS_NAME)
        secrets_str <-
          get_secret_value_response$SecretString %>% fromJSON()
        return(secrets_str)
      }
    )
    
  )

However it seems that I am not able to access the get_secrets function within the initializer as opposite as my colleagues do in python.

Is there any simple solution to this?

PS: I am not so familiar with the R6 system and I believe that my confusion is probably due to a conceptual error but I would more than happy to learn more :)



from Calling function of an R6 class within the initialize of R6

No comments:

Post a Comment