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 Integration für den externen Zugriff 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, einschließlich der erforderlichen Berechtigungen, 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, einschließlich der erforderlichen Berechtigungen, 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, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen eines Geheimnisses zur Darstellung von Anmeldeinformationen.

    Das Geheimnis muss mit seinem Parameter OAUTH_REFRESH_TOKEN ein Aktualisierungstoken angeben. Um einen Aktualisierungstoken vom Dienstanbieter (in diesem Fall vom Google Cloud Translation API-Dienst) zu erhalten, können Sie eine vom Anbieter angebotene Methode oder die Snowflake-Systemfunktionen verwenden.

    Um ein Geheimnis mit einem Aktualisierungstoken zu erstellen, verwenden Sie entweder Google OAuth Playground- oder Snowflake-Systemfunktionen, wie im Folgenden beschrieben:

    • Snowflake-Systemfunktionen

      1. Führen Sie CREATE SECRET aus, um ein Geheimnis zu erstellen. Sie werden es in einem späteren Schritt mit dem Aktualisierungstoken aktualisieren.

        USE DATABASE my_db;
        USE SCHEMA secret_schema;
        
        CREATE OR REPLACE SECRET oauth_token
          TYPE = oauth2
          API_AUTHENTICATION = google_translate_oauth;
        
        Copy
      2. Führen Sie die Funktion SYSTEM$START_OAUTH_FLOW aus, um eine URL abzurufen, mit der Sie ein Aktualisierungstoken erhalten können, und geben Sie als Argument den Namen des zuvor erstellten Geheimnisses an.

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

        Die Funktion generiert eine URL, die Sie verwenden können, um den OAuth-Zustimmungsprozess abzuschließen.

      3. Wechseln Sie in einem Browser zu der generierten URL, und schließen Sie den OAuth2-Zustimmungsprozess ab. Wenn Sie fertig sind, lassen Sie den Browser auf der letzten Seite des Prozesses geöffnet.

      4. Kopieren Sie in der Adressleiste des Browsers von der URL der letzten Seite des Zustimmungsprozesses den gesamten Text, der nach dem Fragezeichen folgt.

      5. Führen Sie die Funktion SYSTEM$FINISH_OAUTH_FLOW aus, und geben Sie als Argument die Parameter an, die Sie gerade aus der Adressleiste des Browsers kopiert haben.

        Dadurch wird das Geheimnis mit einem Aktualisierungstoken aktualisiert.

        Achten Sie darauf, SYSTEM$FINISH_OAUTH_FLOW in der gleichen Sitzung wie SYSTEM$START_OAUTH_FLOW auszuführen. SYSTEM$FINISH_OAUTH_FLOW aktualisiert das in SYSTEM$START_OAUTH_FLOW angegebene Geheimnis mit dem Zugriffstoken und dem Aktualisierungstoken, die es vom OAuth-Server erhalten hat.

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

      1. Wählen Sie in Google OAuth Playground wie in Schritt 1 angegeben die Cloud Translation API aus, und autorisieren Sie sie.

      2. Klicken Sie in Schritt 2 auf exchange authorization code for tokens und kopieren Sie dann den Wert des Tokens refresh token.

      3. Führen Sie CREATE SECRET aus, um ein Geheimnis zu erstellen, das den von Ihnen kopierten Wert des Aktualisierungstokens angibt.

        Weitere Informationen zur Rolle eines Geheimnisses beim externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen eines Geheimnisses zur Darstellung von Anmeldeinformationen.

        CREATE OR REPLACE SECRET oauth_token
          TYPE = oauth2
          API_AUTHENTICATION = google_translate_oauth
          OAUTH_REFRESH_TOKEN = 'my-refresh-token';
        
        Copy
  4. Erstellen Sie eine Integration für den externen Zugriff unter Verwendung der Netzwerkregel und des Geheimnisses.

    Weitere Informationen zur Rolle einer Integration für den externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen einer Integration für den externen Zugriff.

    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. Erstellen Sie eine Rolle developer, die Benutzern zugewiesen wird, die eine UDF oder Prozedur erstellen müssen, die die Integration verwendet.

    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy
  6. Erteilen Sie der Rolle developer die erforderlichen Berechtigungen, um eine UDF zu erstellen, die die Objekte für den externen Zugriff verwendet. Dazu zählen:

    • READ-Berechtigungen für das Geheimnis.

    • USAGE-Berechtigung für das Schema, das das Geheimnis enthält.

    • USAGE-Berechtigungen für die Integration.

      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. 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 Integration für den externen Zugriff 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. Erteilen Sie die USAGE-Berechtigung an die Funktion google_translate_python, damit Personen mit der Rolle user 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 Integration für den externen 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.

    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy
  4. Erteilen Sie der Rolle developer die erforderlichen Berechtigungen, um eine UDF zu erstellen, die die Objekte für den externen Zugriff verwendet. Dazu zählen:

    • READ-Berechtigungen für das Geheimnis.

    • USAGE-Berechtigung für das Schema, das das Geheimnis enthält.

    GRANT READ ON SECRET secret_password TO ROLE developer;
    GRANT USAGE ON SCHEMA secret_schema TO ROLE developer;
    
    Copy
  5. Erstellen Sie eine Integration für den externen Zugriff, um den externen Endpunkt und die Anmeldeinformationen über die von Ihnen erstellte Netzwerkregel und das Geheimnis anzugeben.

    Weitere Informationen zur Rolle einer Integration für den externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen einer Integration für den externen Zugriff.

    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. 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 Integration für den externen Zugriff 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
  7. 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
  8. 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