In my last article, I showed two ways to add images to your Streamlit in Snowflake app – one from an external link and another from the same internal stage as the app. What if the images or other resources needed for your app aren’t in the same internal stage or even in Snowflake at all? Below I walk through two more options for displaying images in a Streamlit in Snowflake app.
“Other” Internal Stage
In the previous demo, I simply loaded the images I wanted to display into a folder in the same internal stage as the app. Perhaps you have a set of “common” images for your Streamlit apps – this is where a common stage would come in handy.
Create Stage
First, create a new stage in your Snowflake. In this example, I’ll include it in the same database and schema as my app, but as long you set permissions correctly, the location of the stage shouldn’t matter. When creating the stage, you’ll want to set the encryption to SNOWFLAKE-SSE and enable DIRECTORY. SNOWFLAKE-SSE uses Snowflake Server Side Encryption on the files in the stage so that they can be accessed outside of Snowflake with a PRESIGNED URL. Enabling the directory allows us to query the stage using the DIRECTORY table function that we’ll need to get our image URLs.
/*SET ENVIRONMENT*/
USE ROLE ST_DEMO_ROLE;
USE WAREHOUSE STREAMLIT_XS_WH;
USE DATABASE STREAMLIT_DB;
USE SCHEMA STREAMLIT_STAGES;
/*CREATE DEDICATED INTERNAL IMAGES STAGE*/
CREATE OR REPLACE STAGE STG_IMAGES
ENCRYPTION = (TYPE='SNOWFLAKE_SSE')
DIRECTORY = (ENABLE=TRUE)
;
Once the stage is created, upload the app images using your preferred method. For this demo, I grabbed three images and uploaded them using Snowsight.
Get Images
Next, using the GET_PRESIGNED_URL function and the DIRECTORY table function, build a query against the stage to return the relative path of the images and a URL for accessing them. If you have a complex folder structure on the stage you may also want to include a column to parse out the file name from the relative path.
SET STAGE_NAME = '@STREAMLIT_DB.STREAMLIT_STAGES.STG_IMAGES';
SELECT
RELATIVE_PATH AS FILE_NAME,
GET_PRESIGNED_URL($STAGE_NAME,RELATIVE_PATH) AS IMG_URL
FROM DIRECTORY($STAGE_NAME);
Add Images to Streamlit
Using the query created in the previous step, add a few lines of code to your app to retrieve the image information from your stage. In this example, I’m looping through all the images on the stage and displaying them to the screen with the relative path added as a caption to the image.
stg_name = "@STREAMLIT_DB.STREAMLIT_STAGES.STG_IMAGES"
img_sql = f"""
SELECT
RELATIVE_PATH AS FILE_NAME,
GET_PRESIGNED_URL({stg_name},RELATIVE_PATH) AS IMG_URL
FROM DIRECTORY({stg_name})
"""
img_df = session.sql(img_sql).collect()
for img in img_df:
st.image(image=img["IMG_URL"],caption=img["FILE_NAME"],width=200)
link = f'[Download {img["FILE_NAME"]}]({img["IMG_URL"]})'
st.markdown(link)
External Stage
What if you already have all your images or assets located externally from Snowflake? Perhaps they’re on Amazon S3 or Microsoft Azure – no worries, we can do that too!
External S3 Bucket
The external stage implementation of this method only differs from using an internal stage in the setup of the stage. For this example, I created an S3 bucket in my AWS account and generated an Access Key and Secret for it. Note: connecting to S3 buckets using Access Key and Secret is allowable, but not recommended best practice. Using a storage integration is the recommended best practice; however, the Access Key and Secret are “good enough” for this demo. I also loaded the same three images to the S3 bucket as my internal stage.
CREATE OR REPLACE STAGE STG_S3_IMAGES
URL = 's3://eheilman-streamlit-images'
CREDENTIALS = (AWS_KEY_ID = 'YOUR KEY' AWS_SECRET_KEY = 'YOUR SECRET')
ENCRYPTION = (TYPE = 'AWS_SSE_S3') /*MATCH YOUR S3 BUCKET ENCRYPTION*/
DIRECTORY = (ENABLE=TRUE)
;
Use External Stage in Streamlit
Switching to the external stage in the app is as easy as changing the name of the stage in the variable. Since we enabled directory access to the external stage during creation, we can reuse the same query for the internal stage.
stg_name = "@STREAMLIT_DB.STREAMLIT_STAGES.STG_S3_IMAGES"
img_sql = f"""
SELECT
RELATIVE_PATH AS FILE_NAME,
GET_PRESIGNED_URL({stg_name},RELATIVE_PATH) AS IMG_URL
FROM DIRECTORY({stg_name})
"""
img_df = session.sql(img_sql).collect()
for img in img_df:
st.image(image=img["IMG_URL"],caption=img["FILE_NAME"],width=200)
link = f'[Download {img["FILE_NAME"]}]({img["IMG_URL"]})'
st.markdown(link)
Conclusion
In this demo, we walked through two additional methods for incorporating images into a Streamlit in Snowflake application. Through the methods shown, you can efficiently display images within your Streamlit in Snowflake apps, whether the images are stored internally within Snowflake or externally on platforms like Amazon S3 or Microsoft Azure.

