Conexão ao Snowflake com o conector Python

Este tópico explica as várias maneiras de se conectar ao Snowflake com o conector Python.

Verificação da conexão da rede ao Snowflake com SnowCD

Após configurar seu driver, você pode avaliar e solucionar problemas de conectividade de rede com o Snowflake usando o SnowCD.

Você pode usar o SnowCD durante o processo de configuração inicial e sob demanda para avaliar e solucionar problemas de sua conexão de rede ao Snowflake.

Importação do módulo snowflake.connector

Para importar o módulo snowflake.connector, execute o seguinte comando:

import snowflake.connector
Copy

Você pode ler as informações de login de variáveis de ambiente, da linha de comando, de um arquivo de configuração ou de outra fonte apropriada. Por exemplo:

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

Para o parâmetro ACCOUNT, use seu identificador da conta. Observe que o identificador da conta não inclui o sufixo snowflakecomputing.com.

Para detalhes e exemplos, consulte Notas de uso para o parâmetro account (para o método connect).

Nota

Para obter descrições dos parâmetros de conectores disponíveis, consulte os snowflake.connector métodos.

Se você copiar dados de seu próprio bucket S3 da Amazon, precisará dos buckets AWS_ACCESS_KEY_ID e 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

Nota

Se seus dados estiverem armazenados em um contêiner Microsoft Azure, forneça as credenciais diretamente na instrução COPY.

Após ler as informações de conexão, conecte usando o autenticador padrão ou a autenticação federada (se habilitada).

Definição dos parâmetros da sessão

Você pode definir parâmetros de sessão, como QUERY_TAG, de diversas maneiras ao usar o conector Python:

  • Você pode definir parâmetros em nível de sessão no momento em que se conectar ao Snowflake, passando o parâmetro de conexão opcional chamado session_parameters, conforme o seguinte:

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

    O dicionário de session_parameters passado para o método connect() pode conter um ou mais parâmetros em nível de sessão.

  • Você também pode definir parâmetros de sessão executando a instrução ALTER SESSION SET SQL após a conexão:

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

Para obter mais informações sobre os parâmetros da sessão, consulte as descrições dos parâmetros individuais na página geral Parâmetros.

Conexão usando o autenticador padrão

Conecte-se ao Snowflake usando os parâmetros de login:

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

Pode ser necessário adicionar outras informações.

Conexão usando o arquivo connections.toml

O conector Python permite adicionar definições de conexão a um arquivo de configuração connections.toml. Uma definição de conexão refere-se a uma coleção de parâmetros relacionados à conexão. Para obter mais informações sobre formatos de arquivo toml, consulte TOML (Tom’s Obvious Minimal Language). As bibliotecas Snowflake Python atualmente oferecem suporte a TOML versão 1.0.0.

O conector Python procura o arquivo connections.toml nos seguintes locais, na ordem:

  • Se existir um diretório ~/.snowflake em sua máquina, o Snowflake CLI usará o arquivo ~/.snowflake/connections.toml. Você pode substituir o diretório ~/.snowflake padrão definindo o local na variável de ambiente SNOWFLAKE_HOME.

  • Caso contrário, o Snowflake CLI usará o arquivo connections.toml em um dos seguintes locais, com base em seu sistema operacional:

    • Linux: ~/.config/snowflake/connections.toml, mas você pode atualizá-lo com XDG vars

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

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

Para adicionar credenciais em um arquivo de configuração de conexões:

  1. Em um editor de texto, abra o arquivo connections.toml para edição. Por exemplo, para abrir o arquivo no editor Linux vi:

    $ vi connections.toml
    
    Copy
  2. Adicione uma nova definição de conexão Snowflake.

    Por exemplo, para adicionar uma conexão Snowflake chamada myconnection com as credenciais de conta myaccount, usuário johndoe e senha, bem como informações do banco de dados, adicione as seguintes linhas ao arquivo de configuração:

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

    As definições de conexão oferecem suporte às mesmas opções de configuração disponíveis no Conector Python do Snowflake.

  3. Opcional: adicione mais conexões, conforme mostrado:

    [myconnection_test]
    account = "myaccount"
    user = "jdoe-test"
    password = "******"
    warehouse = "my-test_wh"
    database = "my_test_db"
    schema = "my_schema"
    
    Copy
  4. Salve as alterações no arquivo.

  5. No seu código Python, forneça o nome da conexão para snowflake.connector.connect, semelhante ao seguinte:

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

    Você também pode substituir os valores definidos para a conexão no arquivo connections.toml, da seguinte maneira:

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

Configuração de uma conexão padrão

Você pode definir uma conexão como padrão, para não precisar especificar uma sempre que chamar snowflake.connector.connect() para se conectar ao Snowflake. Você pode definir uma conexão padrão de qualquer uma das seguintes maneiras, listadas em ordem crescente de precedência:

  • Crie uma definição de conexão chamada default.

    1. No arquivo connections.toml, crie a definição de conexão e dê a ela o nome default, conforme mostrado:

      [default]
      account = "myaccount"
      user = "jdoe-test"
      password = "******"
      warehouse = "my-test_wh"
      database = "my_test_db"
      schema = "my_schema"
      
      Copy
    2. Salve o arquivo.

  • Especifique uma conexão nomeada como a conexão padrão no arquivo Snowflake config.toml, no mesmo diretório do arquivo connections.toml.

    1. Abra o arquivo config.toml para edição; então:

    2. Defina o parâmetro default_connection_name semelhante ao seguinte:

      default_connection_name = "myaccount"
      
      Copy
    3. Salve o arquivo.

  • Defina a variável de ambiente SNOWFLAKE_DEFAULT_CONNECTION_NAME.

    Às vezes, você pode querer substituir temporariamente a conexão padrão, como tentar uma conexão de teste, sem precisar alterar a conexão padrão normal. Você pode substituir a conexão padrão especificada nos arquivos connections.toml e config.toml definindo a variável de ambiente SNOWFLAKE_DEFAULT_CONNECTION_NAME da seguinte maneira:

    SNOWFLAKE_DEFAULT_CONNECTION_NAME = myconnection_test
    
    Copy

Para usar a conexão padrão, execute um código Python semelhante ao seguinte:

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

Nota

Se você optar por confiar em uma conexão padrão, não poderá substituir parâmetros de conexão, como username, database ou schema.

Uso de login único (SSO) para autenticação

Se você tiver configurado o Snowflake para usar o login único (SSO), pode configurar seu aplicativo cliente para usar o SSO para autenticação. Consulte Uso de SSO com aplicativos clientes que se conectam ao Snowflake para obter mais detalhes.

Uso da autenticação multifator (MFA)

O Snowflake permite armazenar tokens MFA em cache, incluindo combinar o cache de tokens MFA com SSO.

Para obter mais informações, consulte Uso do armazenamento em cache de tokens MFA para minimizar o número de tentativas durante a autenticação — opcional.

Uso de autenticação de pares de chaves e rotação de pares de chaves

O conector Python é compatível com a autenticação de par de chaves e o rodízio de chaves.

Para obter mais informações sobre como configurar a autenticação de par de chaves e o rodízio de chaves, consulte Autenticação de pares de chaves e rotação de pares de chaves.

  1. Após completar a configuração da autenticação de par de chaves, defina o parâmetro private_key na função connect com o caminho para o arquivo de chave privada.

  2. Modifique e execute o código de exemplo, abaixo. O código descriptografa o arquivo de chave privada e o passa para o driver Snowflake para criar uma conexão:

Código de exemplo

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

Uso de um servidor proxy

Para utilizar um servidor proxy, configure as seguintes variáveis de ambiente:

  • HTTP_PROXY

  • HTTPS_PROXY

  • NO_PROXY

Por exemplo:

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

Dica

O modelo de segurança do Snowflake não permite a utilização de proxies Secure Sockets Layer (SSL) (usando um certificado HTTPS). Seu servidor proxy deve usar uma Autoridade Certificadora (CA) disponível publicamente, reduzindo riscos potenciais de segurança, como um ataque MITM (Man In The Middle) através de um proxy comprometido.

Se você precisar usar seu proxy SSL, recomendamos fortemente que atualize a política do servidor para passar o certificado do Snowflake de modo que nenhum certificado seja alterado no meio das comunicações.

Opcionalmente NO_PROXY pode ser usado para ignorar o proxy para comunicações específicas. Por exemplo, o acesso ao Amazon S3 pode ignorar o servidor proxy especificando NO_PROXY=".amazonaws.com".

NO_PROXY não tem suporte para curingas. Cada valor especificado deve ser um dos seguintes:

  • O fim de um nome de host (ou um nome de host completo), por exemplo:

    • .amazonaws.com

    • minhaorganização-minhaconta.snowflakecomputing.com

  • Um endereço IP, por exemplo:

    • 192.196.1.15

Se for especificado mais de um valor, os valores devem ser separados por vírgulas; por exemplo:

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

Conexão com OAuth

Para conectar usando OAuth, a cadeia de conexão deve incluir o parâmetro authenticator definido como oauth e o parâmetro token definido como oauth_access_token. Para obter mais informações, consulte Clientes, drivers e conectores.

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

Gerenciamento de tempos limite de conexão

Chamar snowflake.connector.connect envia uma solicitação de login. Se uma solicitação de login falhar, o conector poderá reenviar a solicitação de conexão. Os parâmetros a seguir definem limites de tempo após os quais o conector para de repetir solicitações:

  • login_timeout: especifica por quanto tempo, em segundos, o reenvio da solicitação de conexão será mantido. Se a conexão não for bem-sucedida nesse período, o conector falhará com um erro de tempo limite após concluir a tentativa atual, em vez de continuar tentando novamente a solicitação de login. Depois que o tempo limite passar, novas tentativas serão evitadas. No entanto, a atual tentativa em curso termina naturalmente.

  • network_timeout: especifica quanto tempo esperar até que os problemas de rede sejam resolvidos para outras solicitações, como solicitações de consulta de cursor.execute. Quando network_timeout segundos tiverem passado, se a tentativa atual falhar, ocorre um tempo de execução e a solicitação em questão não é repetida. Após network_timeout segundos, a tentativa atual ainda poderá terminar (falhar por conta própria), depois disso ocorre o tempo limite.

  • socket_timeout: especifica os tempos limite de conexão e solicitação no nível do soquete.

O exemplo a seguir substitui o socket_timeout do autenticador 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

O exemplo a seguir demonstra o efeito de definir socket_timeout com um valor grande:

# 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

O exemplo a seguir mostra como substituir o tempo limite do soquete para o autenticador 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

Observe que a variável de ambiente MAX_CON_RETRY_ATTEMPTS limita o número máximo de novas tentativas para solicitações de login. Se uma solicitação não tiver expirado, mas o número máximo de novas tentativas for atingido, a solicitação falhará imediatamente. O valor padrão é 1, o que significa que o conector faz apenas uma nova tentativa.

Gerenciamento de políticas de espera de conexão para novas tentativas

Em algumas situações, talvez você queira variar a taxa ou frequência que o conector usa para repetir solicitações com falha devido a tempos limite. Por exemplo, se você perceber que um grande número de tentativas ocorre simultaneamente, você poderá distribuir essas solicitações definindo uma política de espera de novas tentativas. Uma política de espera especifica o tempo de espera entre novas tentativas.

O conector Snowflake para Python implementa políticas de espera com o parâmetro de conexão backoff_policy que especifica uma função geradora do Python. A função geradora permite especificar quanto tempo esperar (recuar) antes de enviar a próxima solicitação de nova tentativa.

Snowflake fornece os seguintes ajudantes para criar funções geradoras predefinidas com os parâmetros desejados. Você pode usá-los se não quiser criar o seu próprio:

  • linear_backoff, que aumenta a duração da espera em uma constante a cada iteração.

  • exponential_backoff, que multiplica a duração da espera por uma constante a cada iteração.

  • mixed_backoff, que escolhe aleatoriamente entre aumentar a duração da espera com exponential_backoff e deixá-la inalterada a cada iteração.

Essas funções geradoras predefinidas usam os seguintes parâmetros para especificar seus comportamentos:

  • base: tempo de espera inicial, em segundos (padrão = 1).

  • factor: coeficiente para incrementar o tempo de espera. O efeito depende da implementação (padrão = 2); linear_backup adiciona o valor, enquanto exponential_backup multiplica o valor.

  • cap: tempo máximo de espera, em segundos (padrão = 16).

  • enable_jitter: se o jitter deve ser ativado em durações calculadas (padrão = True). Para obter mais informações sobre jitter em espera exponencial, consulte o artigo Espera exponencial em AWS e jitter.

Por exemplo, você pode usar a política exponential_backoff com valores padrão ou com valores personalizados, conforme mostrado:

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

Você também pode criar suas próprias funções geradoras de política de espera, semelhantes a esta que define a função geradora my_backoff_policy:

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

Em seguida, defina o parâmetro de conexão backoff_policy como o nome da função geradora da seguinte maneira:

snowflake.connector.connect(
  backoff_policy=constant_backoff
)
Copy

OCSP

Quando o driver se conecta, o Snowflake envia um certificado para confirmar que a conexão é com o Snowflake e não com um host que está se fazendo passar pelo Snowflake. O driver envia esse certificado para um servidor OCSP (Online Certificate Status Protocol) para verificar se o certificado não foi revogado.

Se o driver não puder chegar ao servidor OCSP para verificar o certificado, ele pode usar “fail-open” ou “fail-close”.

Escolha do modo falha-abre ou falha-fecha

Versões do conector Snowflake para Python anteriores a 1.8.0 usam como padrão o modo falha-fecha. O padrão de versões 1.8.0 e posteriores é falha-abre. Você pode ignorar o comportamento padrão definindo o parâmetro de conexão opcional ocsp_fail_open ao chamar o método connect(). Por exemplo:

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

Verificação da versão do driver ou conector OCSP

A versão do driver ou conector e sua configuração determinam o comportamento OCSP. Para obter mais informações sobre a versão do driver ou conector, sua configuração e comportamento OCSP, consulte Configuração do OCSP.

Cache de respostas OCSP

Para garantir que todas as comunicações sejam seguras, o conector Snowflake para Python usa o protocolo HTTPS para se conectar ao Snowflake, bem como para se conectar a todos os outros serviços (por exemplo, Amazon S3 para arquivos de dados de preparação e Okta para autenticação federada). Além do protocolo HTTPS comum, o conector também verifica o status de revogação do certificado TLS/SSL em cada conexão via OCSP (Online Certificate Status Protocol) e cancela a conexão se o certificado estiver revogado ou se o status OCSP não for confiável.

Como cada conexão do Snowflake aciona até três idas e voltas com o servidor OCSP, vários níveis de cache para respostas OCSP foram introduzidos para reduzir a sobrecarga da rede adicionada à conexão:

  • Cache de memória, que persiste por toda a vida do processo.

  • Cache de arquivos, que persiste até que o diretório de cache (por exemplo, ~/.cache/snowflake) seja limpo.

  • Cache do servidor de resposta OCSP.

O cache também aborda questões de disponibilidade para servidores OCSP (ou seja, no caso do servidor OCSP real estar desligado). Desde que o cache seja válido, o conector ainda pode validar o status de revogação do certificado.

Se nenhuma das camadas de cache contiver a resposta OCSP, o cliente tentará obter o status de validação diretamente do servidor OCSP da CA.

Modificação do local do cache do arquivo de resposta OCSP

Por padrão, o cache de arquivos é habilitado nos seguintes locais; portanto, não são necessárias tarefas de configuração adicionais:

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

Entretanto, se você quiser especificar um local e/ou nome de arquivo diferente para o arquivo de cache de resposta OCSP, o método connect aceita o parâmetro ocsp_response_cache_filename, que especifica o caminho e nome para o arquivo de cache OCSP sob a forma de um URI.

Servidor de cache de resposta OCSP

Nota

O servidor de cache de resposta OCSP tem suporte do conector Snowflake para Python 1.6.0 e superior.

Os tipos de memória e arquivo do cache OCSP funcionam bem para aplicativos conectados ao Snowflake que usam um dos clientes que o Snowflake fornece, com um host persistente. Entretanto, eles não funcionam em ambientes provisionados dinamicamente, tais como AWS Lambda ou Docker.

Para resolver essa situação, o Snowflake fornece um terceiro nível de cache: o servidor de cache de resposta OCSP. O servidor de cache de resposta OCSP busca respostas OCSP de hora em hora nos servidores OCSP da CA e as armazena por 24 horas. Os clientes podem então solicitar o status de validação de um determinado certificado do Snowflake a partir deste cache do servidor.

Importante

Se a política de seu servidor negar acesso à maioria ou a todos os sites e endereços IP externos, você precisará permitir que o endereço do servidor de cache permita a operação normal do serviço. O URL do servidor de cache é ocsp*.snowflakecomputing.com:80.

Se você precisar desativar o servidor de cache por qualquer motivo, defina a variável de ambiente SF_OCSP_RESPONSE_CACHE_SERVER_ENABLED como false. Observe que o valor diferencia maiúsculas e minúsculas e precisa estar em minúsculas.