I want to deploy my ML model using streamlit but streamlit can only allow users upload a file at a time. As a result I am trying to allow user upload a zip file containing images so that the images can be extracted at the backed end and use for prediction. Anytime I test the below code, it keeps throwing:
AttributeError: ‘list’ object has no attribute ‘seek’.
How can I solve this.
import altair as alt
import streamlit as st
from PIL import Image
from pathlib import Path
import base64
import io
import pandas as pd
import zipfile
import filetype
st.set_page_config(page_title='Br Classifier', page_icon = 'nm.jpg', layout = 'wide',
initial_sidebar_state = 'expanded')
image = Image.open(r"C:\Users\taiwo\Desktop\image.jfif")
st.image(image, use_column_width=True)
st.write("""
#CLASSIFICATION
This application helps to classify different classes
***
""")
# pylint: enable=line-too-long
from typing import Dict
import streamlit as st
@st.cache(allow_output_mutation=True)
def get_static_store() -> Dict:
"""This dictionary is initialized once and can be used to store the files uploaded"""
return {}
def main():
"""Run this function to run the app"""
static_store = get_static_store()
st.info(__doc__)
file_uploaded = st.file_uploader("Upload", type=["png","jpg","jpeg", "zip"],
accept_multiple_files=True,)
with zipfile.ZipFile(file_uploaded,"r") as z:
z.extractall(".")
selected_model = st.sidebar.selectbox(
'Pick an image classifier model',
('CNN_CLASSIFIER', 'Neural Network'))
st.write('You selected:', selected_model)
if __name__ == "__main__":
main()
Since you’ve set accept_multiple_files=True, the file uploader returns a list. A zip file may be an element of the list. You can replace the with block with the snippet below:
# Check if files were uploaded
if len(file_uploaded) > 0:
for file in file_uploaded:
# If zip file, extract contents
if file.type == "application/zip":
with zipfile.ZipFile(file, "r") as z:
z.extractall(".")
View entire script
import base64
import io
import zipfile
from pathlib import Path
import altair as alt
# import filetype
import pandas as pd
from PIL import Image
import streamlit as st
st.set_page_config(
page_title="Br Classifier",
page_icon="nm.jpg",
layout="wide",
initial_sidebar_state="expanded",
)
image = Image.open(r"C:\Users\taiwo\Desktop\image.jfif")
st.image(image, use_column_width=True)
st.write(
"""
#CLASSIFICATION
This application helps to classify different classes
***
"""
)
# pylint: enable=line-too-long
from typing import Dict
import streamlit as st
@st.experimental_memo
def get_static_store() -> Dict:
"""This dictionary is initialized once and can be used to store the files uploaded"""
return {}
def main():
"""Run this function to run the app"""
static_store = get_static_store()
st.info(__doc__)
file_uploaded = st.file_uploader(
"Upload",
type=["png", "jpg", "jpeg", "zip"],
accept_multiple_files=True,
)
# Check if files were uploaded
if len(file_uploaded) > 0:
for file in file_uploaded:
# If zip file, extract contents
if file.type == "application/zip":
with zipfile.ZipFile(file, "r") as z:
z.extractall(".")
selected_model = st.sidebar.selectbox(
"Pick an image classifier model", ("CNN_CLASSIFIER", "Neural Network")
)
st.write("You selected:", selected_model)
if __name__ == "__main__":
main()
Hi @snehankekre. Thanks for your response. What i am trying to achieve is that if the user decide not to upload the images one after the other but decide to upload a zip file instead. I want to check the file type first, secondly, if it is a png, jpeg, then it should open (Image.open()) and st.image(). 3rd if it is a zip file, then it should extract all images
You should be able to adapt the above example to your use-case. The basic logic is the same. The snippet already checks if the file type is a zip. If so, the contents are extracted.
Thanks, it worked. I just included an else statement to open the image if it is not zipped
if len(file_uploaded) > 0:
for file in file_uploaded:
# If zip file, extract contents
if file.type == "application/zip":
with zipfile.ZipFile(file, "r") as z:
z.extractall(".")
else:
test=Image.open(file)
st.image(test)