Exemplos de acesso à rede externa

Este tópico fornece exemplos de acesso a locais de rede externos a partir de funções e procedimentos definidos pelo usuário.

Acesso ao Google Translate API

As etapas a seguir incluem código para criar uma integração de acesso externo para acesso ao Google Translation API. As etapas adicionam a integração de segurança e as permissões necessárias para executar as instruções.

  1. Crie uma regra de rede representando o local externo.

    Para obter mais informações sobre a função de uma regra de rede no acesso externo, consulte Criação de uma regra de rede para representar o local da rede externa.

    CREATE OR REPLACE NETWORK RULE google_apis_network_rule
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('translation.googleapis.com');
    
    Copy
  2. Crie uma integração de segurança para manter as credenciais OAuth necessárias para autenticação no local de rede externo especificado pela regra de rede google_apis_network_rule.

    Para obter informações de referência sobre o comando, consulte CREATE SECURITY INTEGRATION (Autenticação de API externa).

    CREATE OR REPLACE SECURITY INTEGRATION google_translate_oauth
      TYPE = API_AUTHENTICATION
      AUTH_TYPE = OAUTH2
      OAUTH_CLIENT_ID = 'my-client-id'
      OAUTH_CLIENT_SECRET = 'my-client-secret'
      OAUTH_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token'
      OAUTH_AUTHORIZATION_ENDPOINT = 'https://accounts.google.com/o/oauth2/auth'
      OAUTH_ALLOWED_SCOPES = ('https://www.googleapis.com/auth/cloud-platform')
      ENABLED = TRUE;
    
    Copy
  3. Crie um segredo para representar as credenciais contidas na integração de segurança google_translate_oauth.

    Para obter mais informações sobre a função do segredo no acesso externo, consulte Criação de um segredo para representar credenciais.

    Para o valor OAUTH_REFRESH_TOKEN, você precisará especificar um token de atualização obtido do provedor de serviços (nesse caso, para o serviço Google Cloud Translation API). Por exemplo, para obter o token de atualização, você pode usar:

    • Google OAuth Playground. Lá, na etapa 1, selecione e autorize o Cloud Translation API. Na etapa 2, clique em exchange authorization code for tokens e copie o valor do token refresh token.

    CREATE OR REPLACE SECRET oauth_token
      TYPE = oauth2
      API_AUTHENTICATION = google_translate_oauth
      OAUTH_REFRESH_TOKEN = 'my-refresh-token';
    
    Copy
  4. Crie uma função developer e conceda a ela os privilégios READ no segredo. Essa função será atribuída aos usuários que precisam criar uma UDF ou procedimento que use o segredo.

    Além disso, crie a função que os usuários usarão para chamar a função.

    USE ROLE USERADMIN;
    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy

    Conceda o privilégio READ à função developer.

    GRANT READ ON SECRET oauth_token TO ROLE developer;
    
    Copy
  5. Crie uma integração de acesso externo usando a regra e o segredo da rede, conforme descrito em Criação de uma integração de acesso externo.

    Para executar este comando, você deve usar uma função que tenha o privilégio CREATE INTEGRATION, que a função ACCOUNTADMIN possui por padrão.

    USE ROLE ACCOUNTADMIN;
    
    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION google_apis_access_integration
      ALLOWED_NETWORK_RULES = (google_apis_network_rule)
      ALLOWED_AUTHENTICATION_SECRETS = (oauth_token)
      ENABLED = TRUE;
    
    Copy
  6. Conceda privilégios USAGE na integração à função developer para que os desenvolvedores da UDF possam usá-la. Para usar a integração para acessar um local de rede externo em uma UDF ou procedimento, os usuários devem usar uma função com o privilégio USAGE para a integração.

    GRANT USAGE ON INTEGRATION google_apis_access_integration TO ROLE developer;
    
    Copy
  7. Crie uma UDF google_translate_python que traduza o texto especificado em uma frase no idioma especificado. Para obter mais informações, consulte Uso da integração de acesso externo em uma função ou procedimento.

    USE ROLE developer;
    
    CREATE OR REPLACE FUNCTION google_translate_python(sentence STRING, language STRING)
    RETURNS STRING
    LANGUAGE PYTHON
    RUNTIME_VERSION = 3.8
    HANDLER = 'get_translation'
    EXTERNAL_ACCESS_INTEGRATIONS = (google_apis_access_integration)
    PACKAGES = ('snowflake-snowpark-python','requests')
    SECRETS = ('cred' = oauth_token )
    AS
    $$
    import _snowflake
    import requests
    import json
    session = requests.Session()
    def get_translation(sentence, language):
      token = _snowflake.get_oauth_access_token('cred')
      url = "https://translation.googleapis.com/language/translate/v2"
      data = {'q': sentence,'target': language}
      response = session.post(url, json = data, headers = {"Authorization": "Bearer " + token})
      return response.json()['data']['translations'][0]['translatedText']
    $$;
    
    Copy
  8. Conceda o privilégio USAGE na função google_translate_python para que aqueles com a função de usuários possam chamá-la.

    GRANT USAGE ON FUNCTION google_translate_python(string, string) TO ROLE user;
    
    Copy
  9. Execute a função google_translate_python para traduzir uma frase.

    USE ROLE user;
    SELECT google_translate_python('Happy Thursday!', 'zh-CN');
    
    Copy

    Isso gera a seguinte saída.

    -------------------------------------------------------
    | GOOGLE_TRANSLATE_PYTHON('HAPPY THURSDAY!', 'ZH-CN') |
    -------------------------------------------------------
    | 快乐星期四!                                          |
    -------------------------------------------------------
    

Acesso a uma função lambda externa

As etapas a seguir incluem o código de exemplo para criar uma integração de acesso externo para acesso a uma função lambda externa ao Snowflake. O exemplo usa um espaço reservado para o próprio ponto de extremidade externo, mas poderia ser uma função disponível em um ponto de extremidade do servidor REST, por exemplo.

O acesso externo é utilizado em uma UDF vetorizada de Python que recebe um Pandas DataFrame contendo os dados.

  1. Crie uma regra de rede lambda_network_rule representando o local externo my_external_service (aqui, um valor de espaço reservado para o local de um ponto de extremidade externo).

    Para obter mais informações sobre a função de uma regra de rede no acesso externo, consulte Criação de uma regra de rede para representar o local da rede externa.

    CREATE OR REPLACE NETWORK RULE lambda_network_rule
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('my_external_service');
    
    Copy
  2. Crie um segredo para representar as credenciais exigidas pelo serviço externo.

    O código do manipulador posteriormente neste exemplo recupera as credenciais do segredo usando um Snowflake API para Python.

    Para obter mais informações sobre a função do segredo no acesso externo, consulte Criação de um segredo para representar credenciais.

    CREATE OR REPLACE SECRET secret_password
      TYPE = PASSWORD
      USERNAME = 'my_user_name'
      PASSWORD = 'my_password';
    
    Copy
  3. Crie uma função developer e conceda a ela os privilégios READ no segredo. Essa função será atribuída aos usuários que precisam criar uma UDF ou procedimento que use o segredo.

    Além disso, crie a função que os usuários usarão para chamar a função.

    USE ROLE USERADMIN;
    
    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy

    Conceda o privilégio READ no segredo à função developer.

    GRANT READ ON SECRET secret_password TO ROLE developer;
    
    Copy
  4. Crie uma integração de acesso externo para especificar o ponto de extremidade externo e as credenciais por meio da regra e do segredo de rede que você criou.

    Para executar este comando, você deve usar uma função que tenha o privilégio CREATE INTEGRATION, que a função ACCOUNTADMIN possui por padrão.

    Para obter mais informações sobre como criar uma integração, consulte Criação de uma integração de acesso externo.

    USE ROLE ACCOUNTADMIN;
    
    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION lambda_external_access_integration
      ALLOWED_NETWORK_RULES = (lambda_network_rule)
      ALLOWED_AUTHENTICATION_SECRETS = (secret_password)
      ENABLED = TRUE;
    
    Copy
  5. Crie uma UDF vetorizada de Python return_double_column que acesse um local de rede externo para processar dados recebidos como um Pandas DataFrame.

    Para obter mais informações sobre como usar o acesso externo em uma UDF, consulte Uso da integração de acesso externo em uma função ou procedimento.

    CREATE OR REPLACE FUNCTION return_double_column(x int)
    RETURNS INT
    LANGUAGE PYTHON
    EXTERNAL_ACCESS_INTEGRATIONS = (lambda_external_access_integration)
    SECRETS = ('cred' = secret_password)
    RUNTIME_VERSION = 3.8
    HANDLER = 'return_first_column'
    PACKAGES = ('pandas', 'requests')
    AS $$
    import pandas
    import numpy as np
    import json
    import requests
    import base64
    import _snowflake
    from _snowflake import vectorized
    from requests.auth import HTTPBasicAuth
    from requests.adapters import HTTPAdapter
    from requests.packages.urllib3.util.retry import Retry
    
    session = requests.Session()
    retries = Retry(total=10, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], allowed_methods = None)
    
    session.mount('https://', HTTPAdapter(max_retries=retries))
    
    @vectorized(input=pandas.DataFrame)
    def return_first_column(df):
      request_rows = []
    
      df.iloc[:,0] = df.iloc[:,0].astype(int)
      request_rows = np.column_stack([df.index, df.iloc[:,0]]).tolist()
    
      request_payload = {"data" : request_rows}
    
      username_password_object = _snowflake.get_username_password('cred');
      basic = HTTPBasicAuth(username_password_object.username, username_password_object.password)
    
      url = 'my_external_service'
    
      response = session.post(url, json=request_payload, auth=basic)
    
      response.raise_for_status()
      response_payload = json.loads(response.text)
    
      response_rows = response_payload["data"]
    
      return pandas.DataFrame(response_rows)[1]
    $$;
    
    Copy
  6. Conceda o privilégio USAGE na função return_double_column para que aqueles com a função user possam chamá-la.

    GRANT USAGE ON FUNCTION return_double_column(int) TO ROLE user;
    
    Copy
  7. Execute a função return_double_column, fazendo uma solicitação ao ponto de extremidade externo.

    O código no exemplo a seguir cria uma tabela de duas colunas e insere 100.000.000 linhas contendo números inteiros de 4 bytes. O código então executa a função return_double_column, passando valores da coluna a para processamento pelo ponto de extremidade externo.

    CREATE OR REPLACE TABLE t1 (a INT, b INT);
    INSERT INTO t1 SELECT SEQ4(), SEQ4() FROM TABLE(GENERATOR(ROWCOUNT => 100000000));
    
    SELECT return_double_column(a) AS retval FROM t1 ORDER BY retval;
    
    Copy