Retrieve url where image is served / Image ID

Hello dear community,

My streamlit app is running locally streamlit==1.30.0 on python==3.11.7

I am currently building a Streamlit App that leverages different StableDiffusion APIs. For ComfyUIs Controlnet to work I need to serve an image at an URL.

From my understanding streamlits MediaFileManager does just that. → Right click and copy image url will provide me with an url to my image on localhost.

I could not find a way to access neither this image url or the image id to build this url:
http://localhost:8501/media/87af0b27e083a7ab10e58a185c8ea600697a7.png

Maybe someone is able to help me with that :smile:

→ My fallback solution would be to save the generated image to a folder and use Streamlits ability for static file serving Static file serving - Streamlit Docs. But then I would have to worry about cleaning up the files after a session ends.

Thanks for the help!

Hello @haasan,

You could implement your fallback solution in a Streamlit app, along with a simple cleanup mechanism:

import streamlit as st
import os
import shutil
from PIL import Image
import uuid

# Directory where images will be saved
IMAGES_DIR = "served_images"

# Create the directory if it does not exist
if not os.path.exists(IMAGES_DIR):
    os.makedirs(IMAGES_DIR)

# Function to save an image and return its URL
def save_image(image_data):
    image_id = str(uuid.uuid4())
    image_path = os.path.join(IMAGES_DIR, f"{image_id}.png")
    image_data.save(image_path)
    return st.experimental_get_server_url() + image_path

# Example usage
uploaded_file = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
if uploaded_file:
    image = Image.open(uploaded_file)
    image_url = save_image(image)
    st.write(f"Image URL: {image_url}")

    # Display the image using the URL
    st.image(image_url)

# Optional: Cleanup images directory upon session end
# This can be more complex depending on your app's logic and needs
@st.experimental_singleton
def cleanup_images_dir():
    def cleanup():
        if os.path.exists(IMAGES_DIR):
            shutil.rmtree(IMAGES_DIR)
    return cleanup

st.experimental_on_session_end(cleanup_images_dir())

Kind Regards,
Sahir Maharaj
Data Scientist | AI Engineer

P.S. Lets connect on LinkedIn!

➤ Website: https://sahirmaharaj.com
➤ Email: sahir@sahirmaharaj.com
➤ Want me to build your solution? Lets chat about how I can assist!
➤ Join my Medium community of 30k readers! Sharing my knowledge about data science and AI
➤ 100+ FREE Power BI Themes: Download Now

You need to use your publicly accesible address. locahost is accesible only from the same machine.

Hi,

I also needed a solution to generate external URL for images available in bytes array or local path.
I came up with this quick and dirty solution based on image_to_url, the function used by st.image() to share images :

import streamlit.elements.image as st_image

BASE_URL="www.mywebsite.com"

def image_to_url(image: st_image.AtomicImage) -> str:
    """Generate a URL for an image

    Args:
        image (image.AtomicImage): URL, path, buffer, PIL, ...

    Returns:
        str: URL to image
    """
    # generate an ID 
    image_id = str(hash(image)) # only tested on path
    image_url = st_image.image_to_url(
        image=image,
        width=st_image.WidthBehaviour.AUTO,
        clamp=False,
        channels="RGB",
        output_format="auto",
        image_id=image_id,
    )
    image_full_url = BASE_URL + image_url
    return image_full_url

Why it’s dirty :

  • I don’t think it’s part of the streamlit API, streamlit upgrade might brake it
  • If you also use st.image() to display the image, the image is probably cached 2x times (one for the html, one to generate your link)