Uploading and reading a tif file in streamlit

uploaded_file = st.file_uploader("Upload TIFF file", type=["tif", "tiff"])

if uploaded_file is not None:
    with rasterio.open(uploaded_file) as src:
        st.write(f"Number of bands: {src.count}")
        st.write(f"Width: {src.width}")
        st.write(f"Height: {src.height}")
        
        st.subheader("Visualizing the TIFF file")
        show(src)

I am trying to upload and read a tif file but I am getting the following error
SystemError: <class ‘rasterio._err.CPLE_OpenFailedError’> returned a result with an exception set

1 Like

Hi @rutvij-25,

Thanks for sharing this question!

You can try saving the uploaded file temporarily to disk before opening with rasterio.

I gave it a spin with some example code I expanded from your example below and it worked:

import streamlit as st
import rasterio
from rasterio.plot import show
from tempfile import NamedTemporaryFile
import os
import matplotlib.pyplot as plt

uploaded_file = st.file_uploader("Upload TIFF file", type=["tif", "tiff"])

if uploaded_file is not None:
    # Create a temporary file to save the uploaded file
    with NamedTemporaryFile(delete=False, suffix=".tif") as tmp:
        tmp.write(uploaded_file.getvalue())
        tmp_path = tmp.name

    with rasterio.open(tmp_path) as src:
        st.write(f"Number of bands: {src.count}")
        st.write(f"Width: {src.width}")
        st.write(f"Height: {src.height}")
        
        st.subheader("Visualizing the TIFF file")
        fig, ax = plt.subplots()
        show(src, ax=ax)
        st.pyplot(fig)

    # Clean up the temporary file
    os.unlink(tmp_path)

Here’s a screenshot of the code above running with an example .tiff file.

Let me know if this resolves the issue.

For whatever reason rasterio cannot handle UploadedFile, but it will be happy if you wrap the bytes in an io.BytesIO. This should be way faster and cheaper than using temporary files because it doesn’t copy the data.

with rasterio.open(io.BytesIO(uploaded_file.getvalue())) as src:

This is really unexpected, since UploadedFile is a subclass of io.BytesIO and as far as I can tell it works exactly the same.

Even more puzzling, SystemErroris supposed to be an internal errror and should be reported to the maintainers of the interpreter.

2 Likes