Beispiele für externen Netzwerkzugriff

Dieses Thema enthält Beispiele für den Zugriff auf externe Netzwerkstandorte über benutzerdefinierte Funktionen und Prozeduren.

Zugriff auf die Google Translate-API

Die folgenden Schritte umfassen Code zum Erstellen einer externen Zugriffsintegration für den Zugriff auf die Google Translate-API. Die Schritte fügen die Sicherheitsintegration und die für die Ausführung der Anweisungen erforderlichen Berechtigungen hinzu.

  1. Erstellen Sie eine Netzwerkregel, die den externen Standort repräsentiert.

    Weitere Informationen zur Rolle einer Netzwerkregel beim externen Zugriff finden Sie unter Erstellen einer Netzwerkregel zur Darstellung des externen Netzwerkstandorts.

    CREATE OR REPLACE NETWORK RULE google_apis_network_rule
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('translation.googleapis.com');
    
    Copy
  2. Erstellen Sie eine Sicherheitsintegration, die die OAuth-Anmeldeinformationen enthält, die für die Authentifizierung bei dem durch die Netzwerkregel google_apis_network_rule angegebenen externen Netzwerkstandort erforderlich sind.

    Referenzinformationen zu diesem Befehl finden Sie unter CREATE SECURITY INTEGRATION (Externe API-Authentifizierung).

    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. Erstellen Sie ein Geheimnis, das die in der Sicherheitsintegration google_translate_oauth enthaltenen Anmeldeinformationen darstellt.

    Weitere Informationen zur Rolle des Geheimnisses beim externen Zugriff finden Sie unter Erstellen eines Geheimnisses zur Darstellung von Anmeldeinformationen.

    Für den Wert OAUTH_REFRESH_TOKEN müssen Sie ein Aktualisierungstoken angeben, das Sie vom Dienstanbieter erhalten (in diesem Fall für den Google Cloud Translation-API-Dienst). Um zum Beispiel das Aktualisierungstoken zu erhalten, können Sie Folgendes verwenden:

    • Google OAuth Playground. Dort wählen Sie in Schritt 1 die Cloud Translation-API aus und autorisieren sie. Klicken Sie in Schritt 2 auf exchange authorization code for tokens und kopieren Sie dann den Wert des Tokens refresh token.

    CREATE OR REPLACE SECRET oauth_token
      TYPE = oauth2
      API_AUTHENTICATION = google_translate_oauth
      OAUTH_REFRESH_TOKEN = 'my-refresh-token';
    
    Copy
  4. Erstellen Sie eine Rolle developer und erteilen Sie ihr READ-Berechtigungen für das Geheimnis. Diese Rolle wird Benutzern zugewiesen, die eine UDF oder Prozedur erstellen müssen, die das Geheimnis verwendet.

    Erstellen Sie außerdem die Rolle, mit der die Benutzer die Funktion aufrufen werden.

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

    Erteilen Sie die READ-Berechtigung an die developer-Rolle.

    GRANT READ ON SECRET oauth_token TO ROLE developer;
    
    Copy
  5. Erstellen Sie eine externe Zugriffsintegration unter Verwendung der Netzwerkregel und des Geheimnisses, wie unter Erstellen einer externen Zugriffsintegration beschrieben.

    Um diesen Befehl auszuführen, müssen Sie eine Rolle mit der Berechtigung CREATE INTEGRATION verwenden, über das die Rolle ACCOUNTADMIN standardmäßig verfügt.

    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. Gewähren Sie die USAGE-Berechtigung für die Integration an die developer-Rolle, damit UDF-Entwickler sie verwenden können. Um die Integration für den Zugriff auf einen externen Netzwerkstandort in einer UDF oder Prozedur zu verwenden, müssen Benutzer eine Rolle mit der Berechtigung USAGE für die Integration verwenden.

    GRANT USAGE ON INTEGRATION google_apis_access_integration TO ROLE developer;
    
    Copy
  7. Erstellen Sie einer UDF google_translate_python, die den angegebenen Text in einen Ausdruck in der angegebenen Sprache übersetzt. Weitere Informationen dazu finden Sie unter Verwendung der externe Zugriffsintegration in einer Funktion oder Prozedur.

    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. Gewähren Sie die Berechtigung USAGE für die Funktion google_translate_python, sodass diejenigen mit der Rolle des Benutzers sie aufrufen können.

    GRANT USAGE ON FUNCTION google_translate_python(string, string) TO ROLE user;
    
    Copy
  9. Führen Sie die Funktion google_translate_python aus, um einen Ausdruck zu übersetzen.

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

    Dies erzeugt die folgende Ausgabe.

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

Zugriff auf eine externe Lambda-Funktion

Die folgenden Schritte umfassen Beispielcode zum Erstellen einer externen Zugriffsintegration für den Zugriff auf eine Lambda-Funktion außerhalb von Snowflake. Im Beispiel wird ein Platzhalter für den externen Endpunkt selbst verwendet, es könnte sich aber auch um eine Funktion handeln, die z. B. an einem REST-Dienstendpunkt verfügbar ist.

Der externe Zugriff wird in einer vektorisierten Python-UDF verwendet, die ein Pandas-DataFrame mit den Daten erhält.

  1. Erstellen Sie eine Netzwerkregel lambda_network_rule, die den externen Standort my_external_service repräsentiert (hier ein Platzhalterwert für den Standort eines externen Endpunkts).

    Weitere Informationen zur Rolle einer Netzwerkregel beim externen Zugriff finden Sie unter Erstellen einer Netzwerkregel zur Darstellung des externen Netzwerkstandorts.

    CREATE OR REPLACE NETWORK RULE lambda_network_rule
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('my_external_service');
    
    Copy
  2. Erstellen Sie ein Geheimnis, das die für den externen Dienst erforderlichen Anmeldeinformationen darstellt.

    Der Handler-Code später in diesem Beispiel ruft die Anmeldeinformationen aus dem Geheimnis mit einer Snowflake-API für Python ab.

    Weitere Informationen zur Rolle des Geheimnisses beim externen Zugriff finden Sie unter Erstellen eines Geheimnisses zur Darstellung von Anmeldeinformationen.

    CREATE OR REPLACE SECRET secret_password
      TYPE = PASSWORD
      USERNAME = 'my_user_name'
      PASSWORD = 'my_password';
    
    Copy
  3. Erstellen Sie eine Rolle developer und erteilen Sie ihr READ-Berechtigungen für das Geheimnis. Diese Rolle wird Benutzern zugewiesen, die eine UDF oder Prozedur erstellen müssen, die das Geheimnis verwendet.

    Erstellen Sie außerdem die Rolle, mit der die Benutzer die Funktion aufrufen werden.

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

    Erteilen Sie die READ-Berechtigung an die developer-Rolle für das Geheimnis.

    GRANT READ ON SECRET secret_password TO ROLE developer;
    
    Copy
  4. Erstellen Sie eine externe Zugriffsintegration, um den externen Endpunkt und die Anmeldeinformationen über die von Ihnen erstellte Netzwerkregel und das Geheimnis anzugeben.

    Um diesen Befehl auszuführen, müssen Sie eine Rolle mit der Berechtigung CREATE INTEGRATION verwenden, über das die Rolle ACCOUNTADMIN standardmäßig verfügt.

    Weitere Informationen zur Erstellung einer Integration finden Sie unter Erstellen einer externen Zugriffsintegration.

    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. Erstellen Sie eine vektorisiertes Python-UDF return_double_column, die auf einen externen Netzwerkstandort zugreift, um als Pandas-DataFrame empfangene Daten zu verarbeiten.

    Weitere Informationen zur Verwendung des externen Zugriffs in einer UDF finden Sie unter Verwendung der externe Zugriffsintegration in einer Funktion oder Prozedur.

    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. Erteilen Sie die USAGE-Berechtigung an die Funktion return_double_column, damit Personen mit der Rolle user sie aufrufen können.

    GRANT USAGE ON FUNCTION return_double_column(int) TO ROLE user;
    
    Copy
  7. Führen Sie die Funktion return_double_column aus und stellen Sie eine Anfrage an den externen Endpunkt.

    Der Code im folgenden Beispiel erstellt eine zweispaltige Tabelle und fügt 100.000.000 Zeilen mit 4-Byte-Ganzzahlen ein. Der Code führt dann die Funktion return_double_column aus und übergibt Werte aus Spalte a zur Verarbeitung durch den externen Endpunkt.

    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