시크릿 관리 및 Streamlit 앱 구성하기¶
Streamlit 앱은 API 키, 비밀번호 및 기타 자격 증명과 같은 민감한 정보에 액세스해야 하는 경우가 많습니다. Streamlit 앱에서 시크릿을 관리하는 방법은 사용 중인 런타임 환경에 따라 다릅니다. Streamlit in Snowflake 는 Warehouse Runtime 및 Container Runtime 모두에서 시크릿에 액세스하기 위한 안전한 기본 제공 메커니즘을 제공합니다. Streamlit 구성의 경우 각 런타임에는 다른 제한 사항도 있습니다.
Streamlit 라이브러리에서 앱은 .streamlit/ 디렉터리를 사용하여 구성 및 시크릿을 저장합니다.
.streamlit/config.toml: 테마, 레이아웃, 서버 동작과 같은 앱 설정을 사용자 지정합니다..streamlit/secrets.toml: API 키 및 자격 증명과 같은 민감한 정보를 저장합니다(로컬 개발 시).
Streamlit in Snowflake 는 런타임 환경에 따라 몇 가지 제한 사항이 있지만 이러한 파일을 지원합니다. 다음 테이블에는 Warehouse Runtime 및 Container Runtime에서의 해당 파일에 대한 지원이 요약되어 있습니다.
특징 |
Warehouse Runtime |
Container Runtime |
|---|---|---|
|
구성 옵션의 제한된 하위 세트 |
구성 옵션의 광범위한 하위 세트 |
|
지원되지 않음 |
지원되지만, 시크릿이 아닌 환경 변수에만 권장됨 |
:file:`secrets.toml`의 경우, Streamlit in Snowflake 는 민감한 정보를 관리하는 데 권장되는 보다 안전한 기본 제공 시크릿 관리 시스템을 제공합니다. 다음 섹션에서는 앱에서 Snowflake 시크릿을 사용하는 방법을 설명합니다.
Snowflake에 대한 연결 관리하기¶
Snowflake에 대한 연결을 관리하기 위해 |st.connection|을 사용할 수 있습니다. 이를 통해 로컬 개발 환경과 배포된 앱 모두에서 Snowflake에 연결할 수 있습니다.
import streamlit as st
conn = st.connection("snowflake")
session = conn.session()
session.sql("SELECT 1").collect()
Warehouse Runtime에서는 Snowpark의 get_active_session() 함수를 사용하여 활성 세션을 가져올 수도 있습니다.
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()
중요
:code:`get_active_session()`은 스레드로부터 안전하지 않으며 Container Runtime에서 사용할 수 없습니다.
Container Runtime의 시크릿¶
Container Runtime은 저장 프로시저 환경 외부에서 실행되기 때문에 _snowflake 모듈에 액세스할 수 없습니다. Container Runtime에서 시크릿에 액세스하려면 _snowflake 모듈을 사용하는 SQL 함수를 생성한 후 Streamlit 앱에서 해당 함수를 호출해야 합니다. Cortex API 호출의 경우 ``requests``를 사용해야 합니다.
이전 Streamlit 앱을 Container Runtime으로 업그레이드하는 경우 다음 _snowflake 함수는 저장 프로시저로 대체되어야 합니다. 이에 대해서는 다음 섹션에서 설명합니다.
get_generic_secret_stringget_oauth_access_tokenget_username_passwordget_cloud_provider_tokenget_secret_type
또한, 다음 _snowflake 함수는 세션 토큰으로 인증된 수동 API 호출로 대체되어야 합니다. 이에 대해서는 이후 섹션 :ref:`label-calling_a_cortex_agent_in_a_container_runtime`에서 설명합니다.
send_snow_api_request
Container Runtime에서 시크릿에 액세스하기¶
Container Runtime에서 시크릿에 액세스하려면 다음 단계를 수행합니다.
Snowflake 계정에서 시크릿을 만듭니다. CREATE SECRET 섹션을 참조하십시오.
CREATE OR REPLACE SECRET my_secret TYPE = GENERIC_STRING SECRET_STRING = 'my_secret_value';
시크릿에 액세스하는 함수를 만듭니다. 시크릿 액세스를 위한 Python API 섹션을 참조하십시오.
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') $$;
Container Runtime으로 Streamlit 앱을 만듭니다.
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);
Streamlit 앱 코드에서 SQL 함수를 호출하여 시크릿을 검색합니다.
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]
시크릿이 아닌 환경 변수의 경우 :code:`.streamlit/secrets.toml`을 사용합니다.¶
기술적으로 .streamlit/secrets.toml 파일을 앱의 소스 디렉터리에 추가할 수 있지만 이는 실제 시크릿을 저장하는 데 권장되지 않습니다. secrets.toml 파일은 스테이징된 파일에 일반 텍스트로 저장되며, 이는 보안 모범 사례가 아닙니다.
그러나 :code:`secrets.toml`은 코드에서 :code:`st.secrets`를 통해 액세스하려는 민감하지 않은 구성 값 또는 환경별 설정을 저장하거나 종속성이 환경 변수로 필요한 경우 유용할 수 있습니다.
# .streamlit/secrets.toml
# ONLY USE FOR NON-SECRET CONFIGURATION VALUES
app_name = "My Streamlit App"
api_endpoint = "https://api.example.com"
max_results = 100
그런 다음 :code:`st.secrets`를 통해 또는 환경 변수로 앱에서 이러한 값에 액세스할 수 있습니다.
import streamlit as st
import os
app_name = st.secrets["app_name"]
API_ENDPOINT = os.getenv("API_ENDPOINT")
API 키, 비밀번호, 토큰과 같은 실제 시크릿의 경우, 이전 섹션에서 설명한 대로 항상 Snowflake의 기본 제공 시크릿 관리 시스템을 사용합니다.
Container Runtime에서 Cortex Agent 호출하기¶
Container Runtime 앱에서 Cortex Agent를 호출하려면 기본 Snowpark Container Services 컨테이너에서 세션 토큰을 읽은 후 requests 라이브러리를 사용합니다. 이는 :code:`_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))
Warehouse Runtime의 시크릿¶
Warehouse Runtime에서는 _snowflake 모듈을 사용하여 Streamlit 앱 코드에서 직접 시크릿에 액세스합니다. Warehouse Runtime은 저장 프로시저의 _snowflake 모듈에 대한 액세스 권한을 상속하며, 이를 통해 Streamlit 오브젝트에서 참조되는 시크릿을 검색할 수 있습니다.
Warehouse Runtime에서 시크릿을 사용하려면 다음을 수행합니다.
Snowflake에서 시크릿 오브젝트를 만듭니다. 자세한 내용은 CREATE SECRET 섹션을 참조하십시오.
CREATE OR REPLACE SECRET my_secret TYPE = GENERIC_STRING SECRET_STRING = 'my_secret_value';
외부 액세스 통합을 만들고 여기에 시크릿을 할당합니다.
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION my_eai ALLOWED_AUTHENTICATION_SECRETS = (my_secret) ENABLED = TRUE;
SECRETS 매개 변수를 사용하여 Streamlit 오브젝트에서 시크릿을 참조합니다.
ALTER STREAMLIT my_warehouse_app SET EXTERNAL_ACCESS_INTEGRATIONS = (my_eai) SECRETS = ('my_secret_key' = my_secret);
외부 액세스 통합 및 시크릿 모두를 Streamlit 오브젝트에 할당해야 합니다. Streamlit 오브젝트에 시크릿을 단독으로 할당할 수는 없습니다.
Streamlit 앱 코드에서
_snowflake모듈을 가져와 시크릿을 검색합니다.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')
_snowflake 모듈을 사용한 시크릿 액세스에 대한 자세한 내용은 시크릿 액세스를 위한 Python API 섹션을 참조하세요.
Streamlit 구성¶
Streamlit 앱에는 구성 파일(.streamlit/config.toml)이 포함될 수 있습니다. 이 파일을 사용하면 테마, 레이아웃, 동작 등 앱의 다양한 측면을 사용자 지정할 수 있습니다. 구성 파일은 TOML 형식으로 작성됩니다. 사용 가능한 구성 옵션에 대한 자세한 내용은 |config.toml|에 대한 Streamlit 설명서를 참조하세요.
구성 옵션에 대한 지원은 런타임 환경에 따라 다릅니다. Container Runtime은 일반적으로 특히 정적 서비스의 경우 Warehouse Runtime보다 구성 옵션에 대한 광범위한 지원을 제공합니다. 다음 테이블은 Warehouse Runtime 및 Container Runtime에서 지원되는 구성 섹션을 보여줍니다.
구성 섹션 |
Warehouse Runtime |
Container Runtime |
|---|---|---|
|
지원되지 않음 |
제한된 지원( |
|
지원되지 않음 |
지원되지 않음 |
|
지원되지 않음 |
제한된 지원( |
|
지원되지 않음 |
지원됨 |
|
지원되지 않음 |
지원되지 않음 |
|
지원되지 않음 |
지원되지 않음 |
|
지원되지 않음 |
지원됨(사용 중단됨, 대신 환경 변수 사용) |
|
지원됨 |
지원됨 |
|
지원됨 |
지원됨 |
|
지원되지 않음 |
지원됨(단, 시크릿이 아닌 환경 변수에만 권장됨) |
|
지원됨 |
해당 없음 |
[snowflake.sleep] 섹션을 통해 Warehouse Runtime에서 슬립 타이머를 구성하는 방법에 대한 자세한 내용은 Streamlit 앱용 사용자 지정 슬립 타이머 섹션을 참조하세요.
다음 디렉터리 구조는 구성 파일이 있는 Streamlit 앱의 예를 보여줍니다.
source_directory/
├── .streamlit/
│ └── config.toml
├── pyproject.toml
├── streamlit_app.py
└── uv.lock