In my previous article I introduced how to build a sql chatbot with langchain and streamlit. I was then thinking if I can use streamlit to manage my image gallery on cloudflare. I found it was as easy as I thought, of course with a bit help of chatgpt..

Why I need this

I have been using cloudflare images service for a while and satisfied with its speed. However, it doesn’t have a good UI tool. It’s OK to login to cloudflare and upload images, but lazy as me I want to do it in a more convenient way. So I thought I could use its API to build a tool to do uploading and manangement. The solutions for this could be a web app or a desktop app. I prefer the former one because I can use it anywhere as long as I have a browser.
To build a web app, you can use framworks like react or vue, but I am not sure if I can build it in a short time. So I turned to streamlit again. It allows you to build a web app with only python and have a decent amount of built-in components.


I would simply need the basic features like

  • upload images
  • delete images
  • display recent images

perhaps later I need advanced features like resizing, but for now I just need the basic ones.

Integrate with cloudflare images

What you need to prepare is a cloudflare account and an API key. You can find the API key in your cloudflare account settings. Keep in mind that you need to apply for a API Tokens instead of API Keys on this page.

They do have a quick start guide but what you need to check is actually this one. The API we gonna need here is list, upload and delete.

Build the app

Building a streamlit app for images is quite straightforward. You can simply use its image uploading component and display the images with st.image. The only thing you need to do is to hook up the cloudflare images API with streamlit.

Here is the snippet of the codes:

import streamlit as st
import requests
import json

# Cloudflare API details
API_TOKEN = "xxx"
ACCOUNT_ID = "yyy"

# Cloudflare Images API endpoint
API_BASE_URL =f"{ACCOUNT_ID}/images/v1"
# Streamlit app layout
def main():
    st.header("Upload to Cloudflare Images")
     # Image uploader
    uploaded_image = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])

    if uploaded_image is not None:
        metadata = st.text_input("Image Metadata (optional)", "")
        require_signed_urls = st.checkbox("Require Signed URLs")

        if st.button("Upload Image"):
            response = upload_image(uploaded_image,metadata, require_signed_urls)
            response_data = response.json()          

    st.header("Cloudflare Images Gallery")
    # Pagination
    pag_col1, pag_col2 = st.columns(2)
    with pag_col1:
        page_number = st.number_input("Page number", value=1, min_value=1, step=1)
    with pag_col2:
        per_page = st.number_input("Images per page", value=12, min_value=10, max_value=10000, step=10)

    # Fetch images using Cloudflare API
    response = fetch_images(page_number, per_page)
    images = response.get("result", {}).get("images", [])

    if not images:
        st.write("No images found.")
        st.write("Displaying {} images:".format(len(images)))

        #... Create a grid layout with st.columns and display images with st.image()
# Fetch images using Cloudflare API
def fetch_images(page_number, per_page):

# Upload image using Cloudflare API
def upload_image(image, metadata, require_signed_urls):

# Delete image using Cloudflare API
def delete_image(image_id):
    headers = {
        "Authorization": "Bearer {}".format(API_TOKEN),
        "Content-Type": "application/json"

    delete_url = f"{API_BASE_URL}/{image_id}"
    response = requests.delete(delete_url, headers=headers)
    return response
if __name__ == "__main__":

The UI looks like this:


Checkout the full code on

What’s next

The current app has already satisfied my basic needs as I only use cloudflare as an image bucket for now. Of course the UI is so basic and you can make it much better but It took me roughly 2-3 hours to build this, I think it’s a good investment of my time. Thanks to streamlit anyway for making this so easy.

Except resizing , more features I would like to consider adding later like adding a cloudflare worker to redirect the image url to private domain as this article suggested. It would be essential if you need to include images in your SEO strategy.