Connexion à Snowflake avec le connecteur Python

Cette rubrique explique les différentes manières de vous connecter à Snowflake avec le connecteur Python.

Vérification de la connexion réseau à Snowflake avec SnowCD

Après avoir configuré votre pilote, vous pouvez évaluer et dépanner votre connectivité réseau à Snowflake en utilisant SnowCD.

Vous pouvez utiliser SnowCD pendant le processus de configuration initiale et à la demande pour évaluer et dépanner votre connexion réseau à Snowflake.

Importation du module snowflake.connector

Pour importer le module snowflake.connector, exécutez la commande suivante :

import snowflake.connector
Copy

Vous pouvez obtenir des informations de connexion à partir des variables d’environnement, de la ligne de commande, d’un fichier de configuration ou d’une autre source appropriée. Par exemple :

PASSWORD = os.getenv('SNOWSQL_PWD')
WAREHOUSE = os.getenv('WAREHOUSE')
...
Copy

Pour le paramètre ACCOUNT, utilisez votre identificateur de compte. Notez que l’identificateur du compte ne comprend pas le suffixe snowflakecomputing.com.

Pour plus de détails et des exemples, voir Notes sur l’utilisation pour le paramètre account (pour la méthode connect).

Note

Pour les descriptions des paramètres de connecteurs disponibles, voir les snowflake.connector méthodes.

Si vous copiez des données depuis votre propre compartiment Amazon S3, vous avez besoin de AWS_ACCESS_KEY_ID et de AWS_SECRET_ACCESS_KEY.

import os

AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
Copy

Note

Si vos données sont stockées dans un conteneur Microsoft Azure, fournissez les informations d’identification directement dans l’instruction COPY.

Après avoir lu les informations de connexion, connectez-vous à l’aide de l’authentificateur par défaut ou de l’authentification fédérée (si activée).

Définition des paramètres de session

Vous pouvez définir les paramètres de session, tels que QUERY_TAG, de plusieurs manières lorsque vous utilisez le connecteur Python :

  • Vous pouvez définir des paramètres au niveau de la session au moment où vous vous connectez à Snowflake en transmettant le paramètre de connexion facultatif nommé session_parameters, comme suit :

    con = snowflake.connector.connect(
        user='XXXX',
        password='XXXX',
        account='XXXX',
        session_parameters={
            'QUERY_TAG': 'EndOfMonthFinancials',
        }
    )
    
    Copy

    Le dictionnaire session_parameters transmis à la méthode connect() peut contenir un ou plusieurs paramètres au niveau de la session.

  • Vous pouvez également définir des paramètres de session en exécutant l’instruction ALTER SESSION SET SQL après la connexion :

    con.cursor().execute("ALTER SESSION SET QUERY_TAG = 'EndOfMonthFinancials'")
    
    Copy

Pour plus d’informations sur les paramètres de session, consultez les descriptions des paramètres individuels sur la page générale Paramètres.

Connexion à l’aide de l’authentificateur par défaut

Connectez-vous à Snowflake en utilisant les paramètres de connexion :

conn = snowflake.connector.connect(
    user=USER,
    password=PASSWORD,
    account=ACCOUNT,
    warehouse=WAREHOUSE,
    database=DATABASE,
    schema=SCHEMA
    )
Copy

Vous devrez peut-être étendre cela à d’autres informations.

Connexion à l’aide du fichier connections.toml

Le connecteur Python vous permet d’ajouter des définitions de connexion à un fichier de configuration connections.toml. Une définition de connexion fait référence à un ensemble de paramètres liés à la connexion. Pour plus d’informations sur les formats de fichiers toml, consultez TOML (Tom’s Obvious Minimal Language). Les bibliothèques Python de Snowflake prennent en charge actuellement la version TOML de 1.0.0.

Le connecteur Python recherche le fichier connections.toml dans les emplacements suivants, dans l’ordre :

  • Si un répertoire ~/.snowflake existe sur votre machine, Snowflake CLI utilise le fichier ~/.snowflake/connections.toml. Vous pouvez remplacer le répertoire ~/.snowflake par défaut en définissant l’emplacement dans la variable d’environnement SNOWFLAKE_HOME.

  • Sinon, Snowflake CLI utilise le fichier connections.toml dans l’un des emplacements suivants, en fonction de votre système d’exploitation :

    • Linux : ~/.config/snowflake/connections.toml, mais vous pouvez le mettre à jour avec des variables XDG.

    • Windows : %USERPROFILE%\AppData\Local\snowflake\connections.toml

    • Mac : ~/Library/Application Support/snowflake/connections.toml

Pour ajouter des identifiants de connexion dans un fichier de configuration des connexions :

  1. Dans un éditeur de texte, ouvrez le fichier connections.toml pour le modifier. Par exemple, pour ouvrir le fichier dans l’éditeur Linux vi :

    $ vi connections.toml
    
    Copy
  2. Ajouter une nouvelle définition de connexion Snowflake.

    Par exemple, pour ajouter une connexion Snowflake appelée myconnection avec les identifiants de connexion du compte myaccount, de l’utilisateur johndoe et du mot de passe, ainsi que les informations relatives à la base de données, ajoutez les lignes suivantes au fichier de configuration :

    [myconnection]
    account = "myaccount"
    user = "jdoe"
    password = "******"
    warehouse = "my-wh"
    database = "my_db"
    schema = "my_schema"
    
    Copy

    Les définitions de connexion prennent en charge les mêmes options de configuration que celles disponibles dans le connecteur Python Snowflake.

  3. Facultatif : ajoutez d’autres connexions, comme indiqué :

    [myconnection_test]
    account = "myaccount"
    user = "jdoe-test"
    password = "******"
    warehouse = "my-test_wh"
    database = "my_test_db"
    schema = "my_schema"
    
    Copy
  4. Enregistrez les modifications dans le fichier.

  5. Dans votre code Python, fournissez le nom de la connexion à snowflake.connector.connect, comme suit :

    with snowflake.connector.connect(
          connection_name="myconnection",
    ) as conn:
    
    Copy

    Vous pouvez également remplacer les valeurs définies pour la connexion dans le fichier connections.toml, comme suit :

    with snowflake.connector.connect(
          connection_name="myconnection",
          warehouse="test_xl_wh",
          database="testdb_2"
    ) as conn:
    
    Copy

Définition d’une connexion par défaut

Vous pouvez définir une connexion par défaut, afin de ne pas avoir à en spécifier une à chaque fois que vous appelez snowflake.connector.connect() pour vous connecter à Snowflake. Vous pouvez définir une connexion par défaut de l’une des manières suivantes, énumérées par ordre croissant de priorité :

  • Créez une définition de connexion nommée default.

    1. Dans le fichier connections.toml, créez la définition de la connexion et donnez-lui le nom default, comme indiqué :

      [default]
      account = "myaccount"
      user = "jdoe-test"
      password = "******"
      warehouse = "my-test_wh"
      database = "my_test_db"
      schema = "my_schema"
      
      Copy
    2. Sauvegardez le fichier.

  • Spécifiez une connexion nommée comme connexion par défaut dans le fichier config.toml de Snowflake, dans le même répertoire que le fichier connections.toml.

    1. Ouvrez le fichier config.toml pour le modifier ; ensuite :

    2. Réglez le paramètre default_connection_name de la manière suivante :

      default_connection_name = "myaccount"
      
      Copy
    3. Sauvegardez le fichier.

  • Définissez la variable d’environnement SNOWFLAKE_DEFAULT_CONNECTION_NAME.

    Il peut arriver que vous souhaitiez remplacer temporairement la connexion par défaut, par exemple pour essayer une connexion de test, sans avoir à modifier la connexion normale par défaut. Vous pouvez remplacer la connexion par défaut spécifiée dans les fichiers connections.toml et config.toml en définissant la variable d’environnement SNOWFLAKE_DEFAULT_CONNECTION_NAME comme suit :

    SNOWFLAKE_DEFAULT_CONNECTION_NAME = myconnection_test
    
    Copy

Pour utiliser la connexion par défaut, exécutez un code Python similaire au suivant :

with snowflake.connector.connect() as conn:
    with conn.cursor() as cur:
        print(cur.execute("SELECT 1;").fetchall())
Copy

Note

Si vous choisissez de vous appuyer sur une connexion par défaut, vous ne pouvez pas modifier les paramètres de connexion, tels que username, database ou schema.

Utilisation de la connexion unique (SSO) pour l’authentification

Si vous avez configuré Snowflake pour utiliser la connexion unique (SSO), vous pouvez configurer votre application cliente pour utiliser SSO pour l’authentification. Voir Utilisation de SSO avec des applications clientes qui se connectent à Snowflake pour plus de détails.

Utilisation de l’authentification multifactorielle (MFA)

Snowflake prend en charge la mise en cache des jetons MFA, y compris la combinaison de la mise en cache des jetons MFA avec le SSO.

Pour plus d’informations, voir Utilisation de la mise en cache des jetons MFA pour réduire le nombre d’invites lors de l’authentification — Facultatif.

Utilisation de l’authentification par paire de clés et rotation de paires de clés

Le connecteur Python prend en charge l’authentification par paire de clés et la rotation des clés.

Pour plus d’informations sur la manière de configurer l’authentification de la paire de clés et la rotation des clés, voir Authentification par paire de clés et rotation de paires de clés.

  1. Après avoir terminé la configuration de l’authentification par paire de clés, définissez le paramètre private_key de la fonction connect comme le chemin d’accès au fichier de la clé privée.

  2. Modifiez et exécutez l’exemple de code ci-dessous. Le code déchiffre le fichier de la clé privée et le transmet au pilote Snowflake pour créer une connexion :

Exemple de code

import snowflake.connector
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric import dsa
from cryptography.hazmat.primitives import serialization
with open("<path>/rsa_key.p8", "rb") as key:
    p_key= serialization.load_pem_private_key(
        key.read(),
        password=os.environ['PRIVATE_KEY_PASSPHRASE'].encode(),
        backend=default_backend()
    )

pkb = p_key.private_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption())

ctx = snowflake.connector.connect(
    user='<user>',
    account='<account_identifier>',
    private_key=pkb,
    warehouse=WAREHOUSE,
    database=DATABASE,
    schema=SCHEMA
    )

cs = ctx.cursor()
Copy

Utilisation d’un serveur proxy

Pour utiliser un serveur de proxy, configurez les variables d’environnement suivantes :

  • HTTP_PROXY

  • HTTPS_PROXY

  • NO_PROXY

Par exemple :

Linux ou macOS:
export HTTP_PROXY='http://username:password@proxyserver.company.com:80'
export HTTPS_PROXY='http://username:password@proxyserver.company.com:80'
Copy
Windows:
set HTTP_PROXY=http://username:password@proxyserver.company.com:80
set HTTPS_PROXY=http://username:password@proxyserver.company.com:80
Copy

Astuce

Le modèle de sécurité de Snowflake ne permet pas les proxys Secure Sockets Layer (SSL) (utilisant un certificat HTTPS). Votre serveur de proxy doit utiliser une autorité de certification accessible au public (CA), réduisant ainsi les risques potentiels de sécurité tels qu’une attaque MITM (Man In The Middle) via un proxy compromis.

Si vous devez utiliser votre proxy SSL, nous vous recommandons fortement de mettre à jour la politique du serveur pour passer par le certificat Snowflake, afin qu’aucun certificat ne soit modifié au milieu des communications.

En option, NO_PROXY peut être utilisé pour contourner le proxy pour des communications spécifiques. Par exemple, l’accès à Amazon S3 peut contourner le serveur proxy en spécifiant NO_PROXY=".amazonaws.com".

NO_PROXY ne prend pas en charge les caractères génériques. Chaque valeur spécifiée doit être l’une des suivantes :

  • La fin d’un nom d’hôte (ou d’un nom d’hôte complet), par exemple :

    • .amazonaws.com

    • myorganization-myaccount.snowflakecomputing.com

  • Une adresse IP, par exemple :

    • 192.196.1.15

Si plusieurs valeurs sont spécifiées, elles doivent être séparées par des virgules, par exemple :

localhost,.my_company.com,.snowflakecomputing.com,192.168.1.15,192.168.1.16
Copy

Connexion avec OAuth

Pour vous connecter à l’aide de OAuth, la chaîne de connexion doit inclure le jeu de paramètres authenticator à oauth et le jeu de paramètres token à oauth_access_token. Pour plus d’informations, voir Clients, pilotes et connecteurs.

ctx = snowflake.connector.connect(
    user="<username>",
    host="<hostname>",
    account="<account_identifier>",
    authenticator="oauth",
    token="<oauth_access_token>",
    warehouse="test_warehouse",
    database="test_db",
    schema="test_schema"
)
Copy

Gestion des délais d’expiration de connexion

L’appel de snowflake.connector.connect soumet une demande de connexion. Si une demande de connexion échoue, le connecteur peut renvoyer la demande de connexion. Les paramètres suivants définissent des délais après lesquels le connecteur arrête de réessayer les requêtes :

  • login_timeout : spécifie la durée, en secondes, pendant laquelle il faut continuer à renvoyer la demande de connexion. Si la connexion échoue dans ce délai, le connecteur échoue avec une erreur de délai d’attente après avoir terminé la tentative en cours au lieu de continuer à réessayer la demande de connexion. Une fois le délai écoulé, toute nouvelle tentative est empêchée. Cependant, la tentative en cours se termine naturellement.

  • network_timeout : spécifie combien de temps attendre la résolution des problèmes de réseau pour d’autres requêtes, telles que les requêtes d’interrogation de cursor.execute. Lorsque network_timeout secondes se sont écoulées, si la tentative en cours échoue, un délai d’attente s’écoule et la requête en question n’est pas réessayée. Après network_timeout secondes, la tentative en cours est toujours autorisée à se terminer (elle échoue d’elle-même), après quoi le délai d’expiration se produit.

  • socket_timeout : spécifie les délais d’attente de connexion et de demande au niveau du socket.

L’exemple suivant remplace le socket_timeout pour l’authentificateur SNOWFLAKE_JWT :

# this request itself stops retrying after 60 seconds as it is a login request
conn = snowflake.connector.connect(
login_timeout=60,
network_timeout=30,
socket_timeout=10
)

# this request stops retrying after 30 seconds
conn.cursor.execute("SELECT * FROM table")
Copy

L’exemple suivant montre l’effet de la définition de socket_timeout sur une valeur élevée :

# even though login_timeout is 1, connect will take up to n*300 seconds before failing
# (n depends on possible socket addresses)
# this issue arises because socket operations cannot be cancelled once started
conn = snowflake.connector.connect(
login_timeout=1,
socket_timeout=300
)
Copy

L’exemple suivant montre comment remplacer le délai d’expiration du socket pour l’authentificateur SNOWFLAKE_JWT :

# socket timeout for login request overriden by env variable JWT_CNXN_WAIT_TIME
conn = snowflake.connector.connect(
authenticator="SNOWFLAKE_JWT",
socket_timeout=300
)

# socket timeout for this request is still 300 seconds
conn.cursor.execute("SELECT * FROM table")
Copy

Notez que la variable d’environnement MAX_CON_RETRY_ATTEMPTS limite le nombre maximum de nouvelles tentatives pour les requêtes de connexion. Si une requête n’a pas expiré mais que le nombre maximum de tentatives est atteint, la requête échoue immédiatement. La valeur par défaut est 1, ce qui signifie que le connecteur effectue une seule nouvelle tentative.

Gestion des politiques d’interruption de connexion pour les tentatives

Dans certaines situations, vous souhaiterez peut-être faire varier le taux ou la fréquence utilisée par le connecteur pour relancer les requêtes ayant échoué en raison d’expirations de délais d’attente. Par exemple, si vous remarquez qu’un très grand nombre de tentatives se produisent simultanément, vous pouvez répartir ces requêtes en définissant une stratégie d’interruption entre les tentatives. Une politique d’interruption spécifie le temps d’attente entre les nouvelles tentatives.

Le connecteur Snowflake pour Python implémente des politiques d’interruption avec le paramètre de connexion backoff_policy qui spécifie une fonction de générateur Python. La fonction de générateur vous permet de spécifier combien de temps attendre (interrompre) avant d’envoyer la prochaine requête de nouvelle tentative.

Snowflake fournit les aides suivantes pour créer des fonctions de générateur prédéfinies avec les paramètres souhaités. Vous pouvez les utiliser si vous ne souhaitez pas créer les vôtres :

  • linear_backoff, qui augmente la durée d’interruption d’une constante à chaque itération.

  • exponential_backoff, qui multiplie la durée d’interruption par une constante à chaque itération.

  • mixed_backoff, qui choisit aléatoirement entre incrémenter la durée d’interruption avec exponential_backoff et la laisser inchangée à chaque itération.

Ces fonctions de générateur prédéfinies utilisent les paramètres suivants pour spécifier leurs comportements :

  • base : temps d’interruption initial, en secondes (par défaut = 1).

  • factor : coefficient d’incrémentation du temps d’interruption. L’effet dépend de l’implémentation (par défaut = 2) ; linear_backup ajoute la valeur, tandis que exponential_backup multiplie la valeur.

  • cap : temps d’attente maximum, en secondes (par défaut = 16).

  • enable_jitter : s’il faut activer la gigue sur les durées calculées (par défaut = True). Pour plus d’informations sur l’instabilité lors de l’interruption exponentielle, consultez l’article Interruption et gigue exponentielles sur AWS.

Par exemple, vous pouvez utiliser la politique exponential_backoff avec des valeurs par défaut ou avec des valeurs personnalisées, comme indiqué :

from snowflake.connector.backoff_policies import exponential_backoff

# correct, no required arguments
snowflake.connector.connect(
backoff_policy=exponential_backoff()
)

# correct, parameters are customizeable
snowflake.connector.connect(
backoff_policy=exponential_backoff(
    factor=5,
    base=10,
    cap=60,
    enable_jitter=False
  )
)
Copy

Vous pouvez également créer vos propres fonctions de générateur de politique d’interruption, similaires à celles qui suivent qui définissent la fonction de générateur my_backoff_policy :

def my_backoff_policy() -> int:
  while True:
    # yield the desired backoff duration
Copy

Vous définissez ensuite le paramètre de connexion backoff_policy sur le nom de votre fonction de générateur comme suit :

snowflake.connector.connect(
  backoff_policy=constant_backoff
)
Copy

OCSP

Lorsque le pilote se connecte, Snowflake envoie un certificat confirmant que la connexion est établie avec Snowflake plutôt qu’avec un hôte empruntant l’identité de Snowflake. Le pilote envoie ce certificat à un serveur OCSP (protocole de statut de certificat en ligne) pour vérifier que le certificat n’a pas été révoqué.

Si le pilote ne peut pas atteindre le serveur OCSP pour vérifier le certificat, il peut entrainer un comportement « Fail open » ou « Fail closed ».

Choix du mode Fail-Open ou Fail-Close

Les versions du connecteur Snowflake pour Python antérieures à 1.8.0 sont en mode Fail-Close par défaut. Les versions 1.8.0 et ultérieures sont en mode Fail-Open par défaut. Vous pouvez remplacer le comportement par défaut en définissant le paramètre de connexion facultatif ocsp_fail_open lors de l’appel de la méthode connect(). Par exemple :

con = snowflake.connector.connect(
    account=<account_identifier>,
    user=<user>,
    ...,
    ocsp_fail_open=False,
    ...);
Copy

Vérification de la version du connecteur ou du pilote OCSP

La version du pilote ou du connecteur et sa configuration déterminent le comportement OCSP. Pour plus d’informations sur la version du pilote ou du connecteur, leur configuration et le comportement de OCSP, voir Configuration d’OCSP.

Mise en cache des réponses OCSP

Pour assurer la sécurité de toutes les communications, le connecteur Snowflake pour Python utilise le protocole HTTPS pour se connecter à Snowflake, ainsi que pour se connecter à tous les autres services (par ex. Amazon S3 pour la mise en zone de préparation de fichiers de données et Okta pour l’authentification fédérée). Outre le protocole HTTPS classique, le connecteur vérifie également le statut de révocation du certificat TLS/SSL sur chaque connexion via OCSP (Online Certificate Status Protocol) et interrompt la connexion si le certificat est révoqué ou si le statut OCSP n’est pas fiable.

Comme chaque connexion Snowflake déclenche jusqu’à trois allers-retours avec le serveur OCSP, plusieurs niveaux de cache pour les réponses OCSP ont été introduits pour réduire la surcharge réseau ajoutée à la connexion :

  • La mémoire cache, qui continue d’exister durant la vie du processus.

  • Le cache de fichier, qui continue d’exister jusqu’à ce que le répertoire de cache (par exemple ~/.cache/snowflake) soit purgé.

  • Cache de serveur de réponse OCSP.

La mise en cache traite également les problèmes de disponibilité des serveurs OCSP (c’est-à-dire dans le cas où le serveur OCSP réel est en panne). Tant que le cache est valide, le connecteur peut toujours valider le statut de révocation du certificat.

Si aucune des couches du cache ne contient la réponse OCSP, le client tente de récupérer le statut de validation directement depuis le serveur OCSP du CA.

Modification de l’emplacement du cache de fichier de réponse OCSP

Par défaut, le cache de fichier est activé dans les emplacements suivants, de sorte qu’aucune tâche de configuration supplémentaire n’est nécessaire :

Linux:

~/.cache/snowflake/ocsp_response_cache.json

macOS:

~/Library/Caches/Snowflake/ocsp_response_cache.json

Windows:

%USERPROFILE%\AppData\Local\Snowflake\Caches\ocsp_response_cache.json

Cependant, si vous voulez spécifier un emplacement et/ou un nom de fichier différent pour le fichier de cache de OCSP réponse, la méthode connect accepte le paramètre ocsp_response_cache_filename, qui spécifie le chemin et le nom du fichier de cache OCSP sous la forme d’un URI.

Serveur de cache de réponse OCSP

Note

Le serveur de cache de réponse OCSP est actuellement pris en charge par le connecteur Snowflake pour Python 1.6.0 et ultérieur.

Les types de mémoire et de fichier de cache OCSP fonctionnent bien pour les applications connectées à Snowflake utilisant un des clients que Snowflake fournit, avec un hôte persistant. Cependant, ils ne fonctionnent pas dans des environnements à alimentation dynamique tels que AWS Lambda ou Docker.

Pour remédier à cette situation, Snowflake fournit un troisième niveau de mise en cache : le serveur de cache de réponse OCSP. Le serveur de cache de réponse OCSP récupère les réponses OCSP toutes les heures sur les serveurs OCSP du CA et les stocke pendant 24 heures. Les clients peuvent alors interroger le statut de validation d’un certificat Snowflake donné à partir de ce cache de serveur.

Important

Si votre politique de serveur refuse l’accès à la plupart ou à la totalité des adresses IP et sites Web externes, vous devez autoriser l’adresse du serveur de cache pour permettre le fonctionnement normal du service. L” URL du serveur de cache est ocsp*.snowflakecomputing.com:80.

Si vous avez besoin de désactiver le serveur de cache pour une raison quelconque, réglez la variable d’environnement SF_OCSP_RESPONSE_CACHE_SERVER_ENABLED sur false. Notez que la valeur est sensible à la casse et doit être en minuscules.