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, incluindo os privilégios exigidos, 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, incluindo os privilégios exigidos, 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, incluindo os privilégios exigidos, consulte Criação de um segredo para representar credenciais.

    O segredo deve especificar um token de atualização com seu parâmetro OAUTH_REFRESH_TOKEN. Para obter um token de atualização do provedor de serviços (neste caso, do serviço Google Cloud Translation API), você pode usar um método oferecido pelo provedor ou usar as funções do sistema Snowflake.

    Para criar um segredo com um token de atualização, use as funções do sistema Google OAuth Playground ou Snowflake, conforme descrito a seguir:

    • Funções do sistema do Snowflake

      1. Execute CREATE SECRET para criar um segredo. Você irá atualizá-lo com o token de atualização em uma etapa posterior.

        USE DATABASE my_db;
        USE SCHEMA secret_schema;
        
        CREATE OR REPLACE SECRET oauth_token
          TYPE = oauth2
          API_AUTHENTICATION = google_translate_oauth;
        
        Copy
      2. Execute a função SYSTEM$START_OAUTH_FLOW para recuperar um URL com o qual você pode obter um token de atualização, especificando como argumento o nome do segredo criado anteriormente.

        SYSTEM$START_OAUTH_FLOW( 'my_db.secret_schema.oauth_token' )
        
        Copy

        A função gerará um URL que você pode usar para concluir o processo de consentimento de OAuth.

      3. Em um navegador, visite o URL gerado e conclua o processo de consentimento do OAuth2. Ao terminar, deixe o navegador aberto na última página do processo.

      4. Na barra de endereço do navegador, copie todo o texto após o ponto de interrogação no URL da última página do processo de consentimento.

      5. Execute a função SYSTEM$FINISH_OAUTH_FLOW, especificando como argumento os parâmetros que você acabou de copiar da barra de endereço do navegador.

        Isso atualiza o segredo com um token de atualização.

        Certifique-se de executar SYSTEM$FINISH_OAUTH_FLOW na mesma sessão que SYSTEM$START_OAUTH_FLOW. SYSTEM$FINISH_OAUTH_FLOW atualizará o segredo especificado em SYSTEM$START_OAUTH_FLOW com o token de acesso e o token de atualização obtido do servidor OAuth.

        SYSTEM$FINISH_OAUTH_FLOW( 'state=<remaining_url_text>' )
        
        Copy
    • Google OAuth Playground

      1. No Google OAuth Playground, selecione e autorize a Cloud Translation API conforme especificado na etapa 1.

      2. Na etapa 2, clique em exchange authorization code for tokens e copie o valor do token refresh token.

      3. Execute CREATE SECRET para criar um segredo que especifique o valor do token de atualização que você copiou.

        Para obter mais informações sobre a função de um segredo no acesso externo, incluindo os privilégios exigidos, consulte Criação de um segredo para representar credenciais.

        CREATE OR REPLACE SECRET oauth_token
          TYPE = oauth2
          API_AUTHENTICATION = google_translate_oauth
          OAUTH_REFRESH_TOKEN = 'my-refresh-token';
        
        Copy
  4. Crie uma integração de acesso externo usando a regra e o segredo da rede.

    Para obter mais informações sobre a função de uma integração de acesso externo, incluindo os privilégios exigidos, consulte Criação de uma integração de acesso externo.

    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
  5. Crie uma função developer que será atribuída aos usuários que precisam criar uma UDF ou procedimento que use a integração.

    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy
  6. Conceda à função developer os privilégios necessários para criar uma UDF que use os objetos para acesso externo. Isso inclui o seguinte:

    • O privilégio READ no segredo.

    • O privilégio USAGE no esquema contendo o segredo.

    • O privilégio USAGE na integração.

      GRANT READ ON SECRET oauth_token TO ROLE developer;
      GRANT USAGE ON SCHEMA secret_schema TO ROLE developer;
      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 user 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.

    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy
  4. Conceda à função developer os privilégios necessários para criar uma UDF que use os objetos para acesso externo. Isso inclui o seguinte:

    • O privilégio READ no segredo.

    • O privilégio USAGE no esquema contendo o segredo.

    GRANT READ ON SECRET secret_password TO ROLE developer;
    GRANT USAGE ON SCHEMA secret_schema TO ROLE developer;
    
    Copy
  5. 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 obter mais informações sobre a função de uma integração de acesso externo, incluindo os privilégios exigidos, consulte Criação de uma integração de acesso externo.

    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION lambda_external_access_integration
      ALLOWED_NETWORK_RULES = (lambda_network_rule)
      ALLOWED_AUTHENTICATION_SECRETS = (secret_password)
      ENABLED = TRUE;
    
    Copy
  6. 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
  7. 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
  8. 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