Gerenciamento de segredos e configuração do app Streamlit¶
Os apps Streamlit geralmente precisam acessar informações confidenciais, como chaves deAPI, senhas e outras credenciais. A forma como você gerencia segredos no app Streamlit depende do ambiente de tempo de execução que você usa. O Streamlit in Snowflake oferece mecanismos seguros e integrados para acessar segredos nos tempos de execução tanto de warehouse quanto de contêiner. Para configuração do Streamlit, cada tempo de execução também tem restrições diferentes.
Na biblioteca Streamlit, os apps usam um diretório .streamlit/ para armazenar configurações e segredos:
.streamlit/config.toml: personaliza as configurações do app, como tema, layout e comportamento do servidor..streamlit/secrets.toml: armazena informações confidenciais, como chaves de API e credenciais (em desenvolvimento local).
O Streamlit in Snowflake oferece suporte a esses arquivos com algumas limitações, dependendo do seu ambiente de tempo de execução. A tabela a seguir resume o suporte para esses arquivos nos tempos de execução de warehouse e contêiner:
Recurso |
Tempo de execução de warehouse |
Tempo de execução de contêiner |
|---|---|---|
Suporte para |
Subconjunto limitado de opções de configuração |
Subconjunto mais amplo de opções de configuração |
Suporte para |
Sem suporte |
Com suporte, mas recomendado somente para variáveis de ambiente não secretas |
Para secrets.toml, o Streamlit in Snowflake fornece um sistema de gerenciamento de segredos integrado mais seguro, recomendado para o gerenciamento de informações confidenciais. As seções a seguir descrevem como usar os segredos do Snowflake em seus apps.
Gerenciamento da conexão com o Snowflake¶
Para gerenciar sua conexão com o Snowflake, você pode usar st.connection("snowflake"). Isso permite que você se conecte ao Snowflake do seu ambiente de desenvolvimento local e do seu app implantado.
import streamlit as st
conn = st.connection("snowflake")
session = conn.session()
session.sql("SELECT 1").collect()
Nos tempos de execução de warehouse, você também pode usar a função get_active_session() do Snowpark para obter a sessão ativa.
import streamlit as st
from snowflake.snowpark.context import get_active_session
# ONLY IN WAREHOUSE RUNTIMES
session = get_active_session()
session.sql("SELECT 1").collect()
Importante
get_active_session() não é thread-safe e não pode ser usado em tempos de execução de contêiner.
Segredos em tempos de execução de contêiner¶
Os tempos de execução de contêiner não têm acesso ao módulo _snowflake porque eles são executados fora do ambiente do procedimento armazenado. Para acessar segredos em um tempo de execução de contêiner, você deve criar funções SQL que usem o módulo _snowflake e, em seguida, chamar essas funções do seu app Streamlit. Para chamadas da Cortex API, você deve usar requests.
Se você atualizar um app Streamlit mais antigo para um tempo de execução de contêiner, as funções _snowflake a seguir deverão ser substituídas por procedimentos armazenados. Esse procedimento está descrito na próxima seção.
get_generic_secret_stringget_oauth_access_tokenget_username_passwordget_cloud_provider_tokenget_secret_type
Além disso, a função _snowflake a seguir deve ser substituída por uma chamada de API manual, autenticada com um token de sessão. Esse procedimento está descrito em uma seção posterior, Chamada de um Cortex Agent em tempo de execução de contêiner.
send_snow_api_request
Acesso a um segredo em um tempo de execução de contêiner¶
Para acessar um segredo em um tempo de execução de contêiner, siga as etapas abaixo:
Crie um segredo em sua conta Snowflake. Consulte CREATE SECRET.
CREATE OR REPLACE SECRET my_secret TYPE = GENERIC_STRING SECRET_STRING = 'my_secret_value';
Crie uma função para acessar o segredo. Consulte API de Python para acesso secreto.
CREATE OR REPLACE FUNCTION get_my_secret() RETURNS STRING LANGUAGE PYTHON RUNTIME_VERSION = 3.12 HANDLER = 'get_my_secret' EXTERNAL_ACCESS_INTEGRATIONS = (my_eai) SECRETS = ('my_secret' = my_secret) AS $$ import _snowflake def get_my_secret(): return _snowflake.get_generic_secret_string('my_secret') $$;
Crie seu app Streamlit com o seguinte tempo de execução de contêiner:
CREATE STREAMLIT my_container_app FROM '@my_stage/app_folder' MAIN_FILE = 'streamlit_app.py' RUNTIME_NAME = 'SYSTEM$ST_CONTAINER_RUNTIME_PY3_11' COMPUTE_POOL = my_compute_pool QUERY_WAREHOUSE = my_warehouse EXTERNAL_ACCESS_INTEGRATIONS = (my_eai);
No código do app Streamlit, chame a função SQL para recuperar o segredo:
import streamlit as st # Get the Snowflake connection conn = st.connection("snowflake") session = conn.session() # Call the function to retrieve the secret secret = session.sql("SELECT get_my_secret()").collect()[0][0]
Uso de .streamlit/secrets.toml para variáveis de ambiente não secretas¶
Você pode tecnicamente adicionar um arquivo .streamlit/secrets.toml ao diretório de origem do seu app, mas isso não é recomendado para armazenar segredos reais. O arquivo secrets.toml é armazenado como texto simples em seus arquivos preparados, o que não é uma prática recomendada de segurança.
Entretanto, o secrets.toml pode ser útil para armazenar valores de configuração não confidenciais ou configurações específicas do ambiente que você deseja acessar pelo st.secrets em seu código ou que uma dependência exige como variável de ambiente:
# .streamlit/secrets.toml
# ONLY USE FOR NON-SECRET CONFIGURATION VALUES
app_name = "My Streamlit App"
api_endpoint = "https://api.example.com"
max_results = 100
Em seguida, é possível acessar esses valores no app por meio do st.secrets ou como variáveis de ambiente:
import streamlit as st
import os
app_name = st.secrets["app_name"]
API_ENDPOINT = os.getenv("API_ENDPOINT")
Para segredos reais, como chaves de API, senhas e tokens, sempre use o sistema de gerenciamento de segredos integrado do Snowflake, conforme descrito na seção anterior.
Chamada de um Cortex Agent em tempo de execução de contêiner¶
Para chamar um Cortex Agent em um app de tempo de execução de contêiner, leia o token de sessão do contêiner Snowpark Container Services subjacente e use a biblioteca requests. Esse é o procedimento substituto recomendado para _snowflake.send_snow_api_request().
import requests
import json
import os
SNOWFLAKE_HOST = os.getenv("SNOWFLAKE_HOST")
SNOWFLAKE_ACCOUNT = os.getenv("SNOWFLAKE_ACCOUNT")
ANALYST_ENDPOINT = "/api/v2/cortex/analyst/message"
URL = "https://" + SNOWFLAKE_HOST + ANALYST_ENDPOINT
def get_token() -> str:
"""Read the oauth token embedded into SPCS container"""
return open("/snowflake/session/token", "r").read()
def send_request(semantic_model_file, prompt):
"""Sends the prompt using the semantic model file """
headers = {
"Content-Type": "application/json",
"accept": "application/json",
"Authorization": f"Bearer {get_token()}",
"X-Snowflake-Authorization-Token-Type": "OAUTH"
}
request_body = {
"messages": [
{
"role": "user",
"content": [{"type": "text", "text": prompt}],
}
],
"semantic_model_file": semantic_model_file,
}
return requests.post(URL, headers=headers, data=json.dumps(request_body))
Segredos em tempos de execução de warehouse¶
Em tempos de execução de warehouse, você pode usar o módulo _snowflake para acessar segredos diretamente no código do app Streamlit. Os tempos de execução de warehouse herdam o acesso ao módulo _snowflake dos procedimentos armazenados, o que permite recuperar segredos referenciados no objeto Streamlit.
Para usar segredos em um tempo de execução de warehouse:
Crie um objeto de segredo no Snowflake. Para obter mais informações, consulte CREATE SECRET.
CREATE OR REPLACE SECRET my_secret TYPE = GENERIC_STRING SECRET_STRING = 'my_secret_value';
Crie uma integração de acesso externo e atribua o segredo a ela.
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION my_eai ALLOWED_AUTHENTICATION_SECRETS = (my_secret) ENABLED = TRUE;
Faça referência ao segredo em seu objeto Streamlit usando o parâmetro SECRETS:
ALTER STREAMLIT my_warehouse_app SET EXTERNAL_ACCESS_INTEGRATIONS = (my_eai) SECRETS = ('my_secret_key' = my_secret);
Você deve atribuir a integração de acesso externo e o segredo ao objeto Streamlit. Não é possível atribuir apenas o segredo a um objeto Streamlit.
No código do app Streamlit, importe o módulo
_snowflakee recupere o segredo:import streamlit as st import _snowflake # Retrieve an API key from a generic string secret my_secret = _snowflake.get_generic_secret_string('my_secret_key')
Para obter mais informações sobre como acessar segredos com o módulo _snowflake, consulte API de Python para acesso secreto.
Configuração do Streamlit¶
Os apps Streamlit podem incluir um arquivo de configuração (.streamlit/config.toml). Esse arquivo permite que você personalize vários aspectos do seu app, como tema, layout e comportamento. O arquivo de configuração é escrito no formato TOML. Para obter mais informações sobre as opções de configuração disponíveis, consulte a documentação do Streamlit em config.toml.
O suporte para opções de configuração varia de acordo com o ambiente de tempo de execução. Os tempos de execução de contêiner geralmente oferecem suporte mais amplo para opções de configuração do que os tempos de execução de warehouse, em especial para serviços estáticos. A tabela a seguir mostra quais seções de configuração são compatíveis com os tempos de execução de warehouse e de contêiner:
Seção de configuração |
Tempo de execução de warehouse |
Tempo de execução de contêiner |
|---|---|---|
|
Sem suporte |
Suporte limitado ( |
|
Sem suporte |
Sem suporte |
|
Sem suporte |
Suporte limitado ( |
|
Sem suporte |
Com suporte |
|
Sem suporte |
Sem suporte |
|
Sem suporte |
Sem suporte |
|
Sem suporte |
Com suporte (obsoleto, use variáveis de ambiente em vez disso) |
|
Com suporte |
Com suporte |
|
Com suporte |
Com suporte |
|
Sem suporte |
Com suporte (mas recomendado apenas para variáveis de ambiente não secretas) |
|
Com suporte |
Não aplicável |
Para obter informações sobre como usar a seção [snowflake.sleep] para configurar temporizadores de suspensão em tempos de execução de warehouse, consulte Temporizador de sono personalizado para um aplicativo Streamlit.
A estrutura de diretório a seguir mostra um exemplo de um app Streamlit com um arquivo de configuração:
source_directory/
├── .streamlit/
│ └── config.toml
├── pyproject.toml
├── streamlit_app.py
└── uv.lock