Exemples d’accès au réseau externe

Cette rubrique fournit des exemples d’accès à des emplacements réseau externes à partir de fonctions et de procédures définies par l’utilisateur.

Accès à l’API Google Translate

Les étapes suivantes comprennent le code permettant de créer une intégration d’accès externe pour l’accès à l’API Google Translation. Les étapes ajoutent l’intégration de la sécurité et les autorisations nécessaires à l’exécution des instructions.

  1. Créez une règle réseau représentant l’emplacement externe.

    Pour plus d’informations sur le rôle d’une règle réseau dans l’accès externe, voir Création d’une règle de réseau pour représenter l’emplacement réseau externe.

    CREATE OR REPLACE NETWORK RULE google_apis_network_rule
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('translation.googleapis.com');
    
    Copy
  2. Créez une intégration de sécurité pour contenir les identifiants de connexion OAuth requis pour s’authentifier auprès de l’emplacement du réseau externe spécifié par la règle réseau google_apis_network_rule.

    Pour des informations de référence sur la commande, voir CREATE SECURITY INTEGRATION (authentification API externe).

    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. Créer un secret pour représenter les identifiants de connexion contenus dans l’intégration de sécurité google_translate_oauth.

    Pour plus d’informations sur le rôle du secret dans l’accès externe, voir Création d’un secret pour représenter les identifiants de connexion.

    Pour la valeur OAUTH_REFRESH_TOKEN, vous devez spécifier un jeton d’actualisation que vous obtenez du fournisseur de services (dans ce cas, pour le service de l’API Google Cloud Translation). Par exemple, pour obtenir le jeton d’actualisation, vous pouvez utiliser :

    • Google OAuth Playground. À l’étape 1, sélectionnez et autorisez l’API Cloud Translation. A l’étape 2, cliquez sur exchange authorization code for tokens, puis copiez la valeur du jeton refresh token.

    CREATE OR REPLACE SECRET oauth_token
      TYPE = oauth2
      API_AUTHENTICATION = google_translate_oauth
      OAUTH_REFRESH_TOKEN = 'my-refresh-token';
    
    Copy
  4. Créez un rôle developer et accordez-lui des privilèges READ sur le secret. Ce rôle sera attribué aux utilisateurs qui doivent créer une UDF ou une procédure utilisant le secret.

    Créez également le rôle que les utilisateurs utiliseront pour appeler la fonction.

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

    Accordez le privilège READ au rôle developer.

    GRANT READ ON SECRET oauth_token TO ROLE developer;
    
    Copy
  5. Créez une intégration d’accès externe à l’aide de la règle réseau et du secret, comme décrit dans Création d’une intégration d’accès externe.

    Pour exécuter cette commande, vous devez utiliser un rôle disposant du privilège CREATE INTEGRATION, que le rôle ACCOUNTADMIN possède par défaut.

    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. Accordez au rôle developer les privilèges USAGE sur le l’intégration afin que les développeurs d’UDF puissent l’utiliser. Pour utiliser l’intégration pour l’accès à un emplacement réseau externe dans une UDF ou une procédure, les utilisateurs doivent utiliser un rôle avec le privilège USAGE pour l’intégration.

    GRANT USAGE ON INTEGRATION google_apis_access_integration TO ROLE developer;
    
    Copy
  7. Créez une UDF google_translate_python qui traduit le texte spécifié en une phrase dans la langue spécifiée. Pour plus d’informations, reportez-vous à Utilisation de l’intégration de l’accès externe dans une fonction ou une procédure.

    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. Accordez le privilège USAGE à la fonction google_translate_python afin que les personnes ayant le rôle d’utilisateur puissent l’appeler.

    GRANT USAGE ON FUNCTION google_translate_python(string, string) TO ROLE user;
    
    Copy
  9. Exécutez la fonction google_translate_python pour traduire une phrase.

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

    Cette opération génère la sortie suivante.

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

Accès à une fonction lambda externe

Les étapes suivantes comprennent un exemple de code pour créer une intégration d’accès externe pour l’accès à une fonction lambda externe à Snowflake. L’exemple utilise un espace réservé pour le point de terminaison externe lui-même, mais il pourrait s’agir d’une fonction disponible sur un point de terminaison de service REST, par exemple.

L’accès externe est utilisé dans une UDF vectorisée Python qui reçoit un Pandas DataFrame contenant les données.

  1. Créez une règle réseau lambda_network_rule représentant l’emplacement externe my_external_service (ici, une valeur d’espace réservé pour l’emplacement d’un point de terminaison externe).

    Pour plus d’informations sur le rôle d’une règle réseau dans l’accès externe, voir Création d’une règle de réseau pour représenter l’emplacement réseau externe.

    CREATE OR REPLACE NETWORK RULE lambda_network_rule
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('my_external_service');
    
    Copy
  2. Créez un secret pour représenter les identifiants de connexion requis par le service externe.

    Le code du gestionnaire, plus loin dans cet exemple, récupère les identifiants de connexion du secret à l’aide d’une API Snowflake pour Python.

    Pour plus d’informations sur le rôle du secret dans l’accès externe, voir Création d’un secret pour représenter les identifiants de connexion.

    CREATE OR REPLACE SECRET secret_password
      TYPE = PASSWORD
      USERNAME = 'my_user_name'
      PASSWORD = 'my_password';
    
    Copy
  3. Créez un rôle developer et accordez-lui des privilèges READ sur le secret. Ce rôle sera attribué aux utilisateurs qui doivent créer une UDF ou une procédure utilisant le secret.

    Créez également le rôle que les utilisateurs utiliseront pour appeler la fonction.

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

    Accordez le privilège READ sur le secret au rôle developer.

    GRANT READ ON SECRET secret_password TO ROLE developer;
    
    Copy
  4. Créez une intégration d’accès externe pour spécifier le point de terminaison externe et les identifiants de connexion par le biais de la règle réseau et du secret que vous avez créés.

    Pour exécuter cette commande, vous devez utiliser un rôle disposant du privilège CREATE INTEGRATION, que le rôle ACCOUNTADMIN possède par défaut.

    Pour plus d’informations sur la création d’une intégration, voir Création d’une intégration d’accès externe.

    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. Créez une UDF vectorisée Python return_double_column qui accède à un emplacement réseau externe pour traiter les données reçues en tant que Pandas DataFrame.

    Pour plus d’informations sur l’utilisation de l’accès externe dans une UDF, voir Utilisation de l’intégration de l’accès externe dans une fonction ou une procédure.

    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. Accordez le privilège USAGE à la fonction return_double_column afin que les personnes ayant le rôle user puissent l’appeler.

    GRANT USAGE ON FUNCTION return_double_column(int) TO ROLE user;
    
    Copy
  7. Exécutez la fonction return_double_column, en adressant une demande au point de terminaison externe.

    Le code de l’exemple suivant crée une table à deux colonnes et insère 100 000 000 lignes contenant des entiers de 4 octets. Le code exécute ensuite la fonction return_double_column, transmettant les valeurs de la colonne a pour un traitement par le point de terminaison externe.

    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