Upload Files to Streamlit App

@tc1 I created an app using the new file upload feature, it allows uploading an image and running object detection on it, as well as adjusting the confidence threshold. As an experiment I developed it using a devcontainer and deployed via docker, and it is working rather nicely. Link below.


Hey @robmarkcole, this looks awesome, thanks for sharing it! Not going to have a ton of service this week [out of town for the holidays], but definitely excited to play around with it more next week.

@amineHY, thanks for posting the question and hopefully Robin’s response in the GitHub issue helped [thanks for the assist Robin].

@ifeherva, good question, would you mind asking this in a separate new forum topic?

Also, happy holidays to everyone if you’re celebrating and hope everyone is doing well :heart:

Hi @tc1,

Yes @robmarkcole workaround does the job for an image.
Sorry, I wasn’t specific in the description, my concern is for processing video frames.
I usually use OpenCV to read the frames and process them, but I am unable to do that using PIL for now. Any help is more than welcome.

Thank you in advance.


I have updated Adrien’s code to make it work with recursive subdirectories.

import os
import streamlit as st

def st_file_selector(st_placeholder, path='.', label='Please, select a file/folder...'):
    # get base path (directory)
    base_path = '.' if path is None or path is '' else path
    base_path = base_path if os.path.isdir(
        base_path) else os.path.dirname(base_path)
    base_path = '.' if base_path is None or base_path is '' else base_path
    # list files in base path directory
    files = os.listdir(base_path)
    if base_path is not '.':
        files.insert(0, '..')
    files.insert(0, '.')
    selected_file = st_placeholder.selectbox(
        label=label, options=files, key=base_path)
    selected_path = os.path.normpath(os.path.join(base_path, selected_file))
    if selected_file is '.':
        return selected_path
    if os.path.isdir(selected_path):
        selected_path = st_file_selector(st_placeholder=st_placeholder,
                                         path=selected_path, label=label)
    return selected_path

It uses the following code to handle the persistence of session states:

The st_file_selector function can be invoked in the following way:

    st_session_state = get(input_path='.')
    st_session_state.input_path = st_file_selector(st_placeholder=st.empty(), path=st_session_state.input_path, label=f'Input path')
    st.text(f'> Selected \'{st_session_state.input_path}\'.')

Hope it helps.



Here is an App implementing the drop/ upload image: https://github.com/amineHY/WebApp-Computer-Vision-streamlit
Feel free to fork/contribute.

1 Like

Any pointers?

Hi Marc,

Thank you for introducing me to Droopy. I was able to make it work by itself, but can you show me how to embed the Droopy file uploader widget into a Streamlit app?


Hi @namong

I don’t think you should be using droopy now that the file uploader is available in Streamlit. Does it not work for you?

Thank you for your quick response, Marc. Much appreciated!
I missed that new feature, it works perfectly.


Is there anyway to get the file name or file suffix from the extension, I’m using filemagic, but it’s weird


Not as far as I know.

Hi Adrien, I created a .html file by folium displaying a heatmap. I want to display the .html in a small window within my streamlit app. Or open the .html file in another tab with a clickable button

I have a situation like this. I need to load data from my local. (set of pdf files) When I am giving a path inside my local both for input and output it should read the data. in the local host streamlit I am able to achieve it but when I deployed using heroku-github its not happening.
I need to develop this app in a feasible way. What do you suggest?


Hi folks,

to be honest, I don’t know if the question is justified or meaningful. Please let me have your opinion on this.

I tried to save a CSV-file in a subfolder (shared/data/*.csv) during the air-time of @streamlit #sharing.

There is an error:

Is it possible to enable the permissions?
Does anyone know another work-around how or where you can simply save csv-files without much hassle?

This error usually arises when the file you are trying to write/edit is already open or being used by another application.

1 Like

Hi everyone,


Is there a way to add delimiters to CSV files? When I use:

data_file = st.file_uploader(‘Weekly Sales Data’,type=[‘csv’,’txt’,’xlsx’])
if data_file:
if data_file.name[-3:] == ‘csv’:
df_data = pd.read_csv(data_file, delimiter=’|’)
elif data_file.name[-3:] == ‘txt’:
df_data = pd.read_csv(data_file, delimiter=’|’)
df_data = pd.read_excel(data_file)

It gives me ValueError: I/O operation on closed file. But then try:

data_file = st.file_uploader(‘Weekly Sales Data’,type=[‘csv’,’txt’,’xlsx’])
if data_file:
if data_file.name[-3:] == ‘csv’:
df_data = pd.read_csv(io.StringIO(data_file.read().decode(‘utf-8′)), delimiter=’|’)
elif data_file.name[-3:] == ‘txt’:
df_data = pd.read_csv(io.StringIO(data_file.read().decode(‘utf-8′)), delimiter=’|’)
df_data = pd.read_excel(data_file)

It reads the file fine, but if I change any parameters but leave the file in the upload it says the same thing.

So I added:

if data_file:
del data_file

under. It doesn’t work.

Any advice?

Ok managed to fix it. I forgot that txt and csv files need to have seek(0) added

data_file = st.file_uploader(‘Weekly Sales Data’,type=[‘csv’,‘txt’,‘xlsx’])

if data_file:

if data_file.name[-3:] == 'csv':


    df_data = pd.read_csv(io.StringIO(data_file.read().decode('utf-8')), delimiter='\|')

elif data_file.name[-3:] == 'txt':


    df_data = pd.read_csv(io.StringIO(data_file.read().decode('utf-8')), delimiter='\|')


    df_data = pd.read_excel(data_file)

I created this script on top of your function so you can select files recursively, which means you can select any file (not folder) path with any depth from your given path as you wish.

def file_selector(folder_path='.', target="background"):
    filenames = [f for f in os.listdir(folder_path) if
                 not f[0] == "."]  # get file names from dir excluding hidden files
    selected_filename = st.selectbox(f'Select a {target}', filenames)
    abs_path = os.path.join(folder_path, selected_filename)
    if os.path.isdir(abs_path):
        return file_selector(abs_path, target)
    return os.path.join(folder_path, selected_filename)

It works something like this. If you have a better solution to get files recursively from multiple levels from a directory, let me know.

(post deleted by author)

uploaded_file = st.file_uploader(
    "Upload your csv file", type=["csv", "json"], accept_multiple_files=False