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.
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');
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;
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';
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;
Conceda o privilégio READ à função
developer
.GRANT READ ON SECRET oauth_token TO ROLE developer;
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;
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;
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'] $$;
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;
Execute a função
google_translate_python
para traduzir uma frase.USE ROLE user; SELECT google_translate_python('Happy Thursday!', 'zh-CN');
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.
Crie uma regra de rede
lambda_network_rule
representando o local externomy_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');
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';
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;
Conceda o privilégio READ no segredo à função
developer
.GRANT READ ON SECRET secret_password TO ROLE developer;
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;
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] $$;
Conceda o privilégio USAGE na função
return_double_column
para que aqueles com a funçãouser
possam chamá-la.GRANT USAGE ON FUNCTION return_double_column(int) TO ROLE user;
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 colunaa
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;