Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Images sometimes do not appear #1294

Closed
m-ad opened this issue Apr 2, 2020 · 50 comments · Fixed by #1494
Closed

Images sometimes do not appear #1294

m-ad opened this issue Apr 2, 2020 · 50 comments · Fixed by #1494
Assignees
Labels
type:bug Something isn't working type:regression This bug is a regression

Comments

@m-ad
Copy link

m-ad commented Apr 2, 2020

Summary

The site randomly shows "0" for images inserted via st.image() and MediaFileManager logs "Missing file".

More information

I have a couple of jpg images embedded with st.image() and randomly they will not render, instead there will just be a 0 shown instead. Reloading the page or rerunning the code fixes the problem. When I reload the page often enough one ore several of the images will break again and just show a 0.

In the terminal with --log_level error I receive

MediaFileManager: Missing file d8a7ff62725a8ab1609c9335ba2e85375f491027d91b3badb27a6ccd

In my complex multi-page streamlit app this happens very often, if I reload the page two or three times, one out of five images is likely broken. The simpler toy example below takes much longer to show the undesired behaviour, but it does so fairly consistently.

Steps to reproduce

Run this code (ideally with --log_level error):

import streamlit as st
if st.checkbox('checkbox'):
    st.image("foo.jpg")

Toggle that checkbox repeatedly (this method is quicker than reloading the page) and look at the console output. Maybe rerun the code once in a while. (Of course you need to put any jpg image named "foo.jpg" in the same folder).

Actual behaviour

Sooner or later (5-50 clicks) the image will not be shown. Instead, in its place a 0 appears. A "MediaFileManager: Missing file" error is shown in the terminal.

Expected behaviour

Images should always be shown.

Debug info

  • Streamlit version: 0.57.1
  • Python version: 3.6.9
@nthmost
Copy link
Contributor

nthmost commented Apr 6, 2020

Hi @m-ad,

Thanks for the detailed report! This is a known issue with some changes we made in #415 and I have a fix already in flight.

I'll close this bug as soon as the fix is pushed into the next release. Thanks for your patience!

@nthmost nthmost self-assigned this Apr 6, 2020
@nthmost nthmost added type:bug Something isn't working type:regression This bug is a regression labels Apr 6, 2020
@danielvarga
Copy link

Hi @nthmost,

Is this bug fixed? It's causing a lot of trouble for me, and I'd love to upgrade if it's fixed. Unfortunately it's not trivial for me to check if it's fixed or not, because of two reasons:

  • @m-ad's short example worksforme already in my 0.52.2 installation, even thought my real-life app breaks often. I tried to play around with bigger and smaller images to reproduce, to no avail.
  • It's not trivial to upgrade my app from 0.52 to latest, because it's full of SessionState and such, and various hopefully-minor backward-incompatible changes break my code before I can even verify the "images sometimes do not appear" situation.

I'd rather not suffer with the upgrade unless it's worth it, so even a simple yes/no would be greatly helpful. (A timeline if no is the answer, even more so.)

@jrhone
Copy link
Contributor

jrhone commented May 4, 2020

Hi @danielvarga ,

The fix was merged 5 days ago. It's available now on the nightly build.

SessionState should work fine with the current version of Streamlit. Have you tried with the updated gist?

@danielvarga
Copy link

Thanks! I haven't tried until you brought it to my attention, now I have. Indeed it seems to fix issue #1294, thanks a lot! But my code does not fully work with the new version, as it broke this hack by Tim Conkling: https://discuss.streamlit.io/t/show-more-items-functionality/1139/2 (Sorry for moving off topic. I'll stop discussing it here, and raise the issue there.)

@thomelane
Copy link

thomelane commented May 7, 2020

Still experiencing an issue with this one, even on nightly (v0.59.1.dev20200506).

Can see the issue with streamlit hello (Animation Demo) running on a web server. More of an issue over https, compared to http, but still get dropped frames either way.

Seeing these errors scattered in the console...

GET https://example.com/media/fc5c3cc4b370b667d407fa2ac2a808348815d93eae8229f04ba030a1.jpeg 404
GET https://example.com/media/e8c9d0a5997976f844e0886a2702f6f083647828c73e8354fcb64c06.jpeg 404
GET https://example.com/media/55c9e43090bd59da85388e171d1f5d558775f5aca80567b7d019ae53.jpeg 404
...

@JohnPaton
Copy link

JohnPaton commented May 13, 2020

I can confirm this is still an issue in 0.59.1.dev20200511 on Python 3.7.7

Edit: For people Googling, we "solved" this by downgrading to streamlit 0.55

@danielvarga
Copy link

Indeed, I was too quick to report that the issue is gone, sorry, it was probably just a statistical fluke. Frequency of occurrence might or might not have decreased, hard to tell.

@sabualkaz
Copy link

I am experiencing the same behaviour with matplotlib plot that the are generated with input from sliders. Is this covered under this issue or should I create a new one?

@emanoelbarreiros
Copy link

I have the same issue. I am trying to display two different pyplot charts on the same script, more often than not the first chart is not displayed.

@madpowah
Copy link

madpowah commented Jun 8, 2020

Same issue on my side with the version 0.61. It happens when displaying 2 pie chart created by the same function called twice. The first st.pyplot is not displayed.

Edit : adding a sleep(0.2) after the pyplot() seems work as workaround

@KyotoSunshine
Copy link

KyotoSunshine commented Jun 24, 2020

I have the same issue, when using streamlit==0.61.0. Images will randomly be displayed as 0s.
Adding sleep(0.2) after st.image() does not help.

@KyotoSunshine
Copy link

KyotoSunshine commented Jun 24, 2020

Tried it with the current streamlit-nightly==0.62.1.dev20200621 and the issue still appears there as well, though perhaps a bit less often.
Also, in my case, reloading (by pressing "r"), does not help to make the image appear.

@nthmost
Copy link
Contributor

nthmost commented Jun 30, 2020

@KyotoSunshine -- is it possible you can share a snippet of code that causes the problem to occur?

@nthmost nthmost reopened this Jun 30, 2020
@MauGal
Copy link

MauGal commented Jul 7, 2020

In my script that it shows 8 charts taken data by csv, with the version 0.56.0 was all ok (in local, in docker container local and in docker container on app engine (GCP)).
This issue started with version 0.59.0: the first 3 charts disappear.
With the version 0.62.0 in local and in docker container local the issue there isn't but on gcp i have the issue (more of 3 charts doesn't visualize) .

Other problem: with the latest version (0.62.0) the script is slower to execute

@jrhone
Copy link
Contributor

jrhone commented Jul 7, 2020

Hi @MauGal, could you share sample code that we can copy/paste and run to reproduce the issue? I'll be sure to try it both locally and on GCP.

Also, could you give a bit more info on what you're seeing with regards to the script being slower to execute?

@MauGal
Copy link

MauGal commented Jul 20, 2020

Hi @jrhone .
I apologize if I haven't answered before.
About the longest time, in version 0.56.0 my script from when I see running appearing in the upper right corner to when it disappears takes 5 or 6 seconds.
In version 0.62.0 the same script takes 11 o 13 seconds.
But I thought it depended on the grace period (KEEP_DELAY = 5)

@chakra-ai
Copy link

Hi,
I am experiencing the same issue with my app. My app works fine in local but once deployed into azure server the image is not rendering properly. This happens random and even for static images as well for WordCloud images. Do we have a fix for that? I am using the latest version. 0.71.0

@kmcgrady
Copy link
Collaborator

kmcgrady commented Dec 1, 2020

Hi @chakra-ai !

It will be really difficult to debug without being able to run the code, so if you are able to share your code (or better, provide a toy example that illustrates the problem simply, that would make life a lot easier.

Here are a couple thoughts that might help us solve the problem.

The MediaFileManager manages all the media in memory. At the end of the script run, all media that was not used in that run, is deleted (to conserve memory). Based on this, we should ensure everything working though I’m curious with race cases (for example, is this an issue with multiple people requesting the website, perhaps that causes a problem)? Does this occur standalone when one user interacts with it?

MatPlotlib is unfortunately not thread safe. So, one should not use st.pyplot with no figure. Even more protection is needed and matplotlib offers a locking mechanism, In another application, I wrote:

import matplotlib
from matplotlib.figure import Figure

matplotlib.use("agg")

_lock = RendererAgg.lock

# ...code...

with _lock:
    fig = Figure()
    ax = fig.subplots()
    # ...perform work on ax
    st.pyplot(fig)

You can see it in action here: https://github.com/kmcgrady/book_reco/blob/master/books.py#L16

Hopefully that helps with a solution. If not and you can provide a simple example that causes the problem, please let me know.

@chakra-ai
Copy link

Hi @kmcgrady , Thanks for the quick reply.

The issue of image rendering I am facing is mostly after I deploy to azure machine. In local its working. I have 2 parts to it.

  1. Static Image (Logo) - sometimes it render but sometimes just the broken image icon. if I right click on the image and do a reload the image loads as it should be.
    image

  2. I am plotting a Word Cloud here. wordcloud

def TextWordCloud(app_name):
    default_inputs = st.selectbox("", 
    [
            "Choose your data",
            "Sample Document : I recently joined Cloudera after working in ...",
            "Upload your own file"

    ])
    if (default_inputs == "Sample Document : I recently joined Cloudera after working in ..."):
        with open('input/Sample_1_WordCloud.txt','r') as f:
            text = f.read()
            st.text_area("Sample Document - Text Preview",text, height=200, key='dsta1')
            if st.button("Run>", key='wc_b_1'):
                doc_wc_str_data = [{"text":text}]
                response = get_response(build_response(doc_wc_str_data),app_name)
                word_dict, noun_dict = get_word_cloud_array(response)
                wc = WordCloud(background_color ='white', margin=2,min_font_size=6).fit_words(word_dict)
                nc = WordCloud(background_color ='white', margin=2,min_font_size=6).fit_words(noun_dict)
                time.sleep(2)
                col1, col2 = st.beta_columns(2)
                col1.markdown("#### Word Cloud ")
                col1.image(wc.to_array(),use_column_width=True)
                col2.markdown("#### Noun Cloud ")
                col2.image(nc.to_array(),use_column_width=True) 
    elif (default_inputs == "Upload your own file"):
        st.markdown('###### * Uploaded file with atleast 50 words!')
        wc_uploaded_file = st.file_uploader("", type="txt", key='wc-up1')
        print(wc_uploaded_file)
        if wc_uploaded_file is not None:
            #print(wc_uploaded_file)
            bytes_data = wc_uploaded_file.read()
            wc_str_data = bytes_data.decode("utf-8")
            wc_text = st.text_area("Document Text Preview",wc_str_data, height=200, key='wcta1')
            if st.button("Run>", key='wc_b_2'):
                doc_wc_str_data = [{"text":wc_str_data}]
                response = get_response(build_response(doc_wc_str_data),app_name)
                word_dict, noun_dict = get_word_cloud_array(response)
                wc = WordCloud(background_color ='white', margin=2,min_font_size=6).fit_words(word_dict)
                nc = WordCloud(background_color ='white', margin=2,min_font_size=6).fit_words(noun_dict)
                time.sleep(2)
                col1, col2 = st.beta_columns(2)
                col1.markdown("#### Word Cloud ")
                col1.image(wc.to_array(),use_column_width=True)
                col2.markdown("#### Noun Cloud ")
                col2.image(nc.to_array(),use_column_width=True)   
    else:
        st.write("** Select data from the above dropdown")

And the image rendering happens like shown below;
image

image

It would be great if you can help on this. Thanks.

@chakra-ai
Copy link

Adding to the above issue; while I inspect the application on the browser for the image component, the image url generated as;
https://<Application URL>/media/1b25254261af69495b4fc9a637472aacad81157493ba5f698288e9da.png

In the console I see;

GET https:///media/1b25254261af69495b4fc9a637472aacad81157493ba5f698288e9da.png 404 status. for the broken image.

@kmcgrady
Copy link
Collaborator

kmcgrady commented Dec 3, 2020

@chakra-ai hmmmmm. I wonder if you can get logs from the server or perhaps run it in debug logging mode? I wonder if there's some caching layer in Azure that's breaking. The sidebar logo, should not be a problem at the very least, so I'd target that as a trivial example to see if we can deduce why that image cannot appear.

Alternatively, I wonder if you deploy the application on Streamlit Share, does the issue still occur?

@tylerjrichards
Copy link
Collaborator

hey @kmcgrady, i'm having this issue on Streamlit Share with my books app (https://share.streamlit.io/tylerjrichards/book_reco/books.py)
I've tried switching over to the newest Streamlit release (0.73), I have '_lock = RendererAgg.lock
' in my code already, and I always use st.pyplot() with an explicit figure, but I keep getting a broken image and the 'MediaFileManager: Missing file' error.

this only happens on Streamlit sharing, but doesn't happen when I run the app locally. Any ideas?

@kmcgrady
Copy link
Collaborator

@tylerjrichards I'll take a look and see if I can figure out the problem. It will be a couple weeks due to the holidays. I'll put something on my calendar in my new year to follow up.

@kmcgrady
Copy link
Collaborator

kmcgrady commented Jan 6, 2021

Hey @tylerjrichards Just want to follow up. I spent some time today investigating it. I am reasonably confident on the problem and can reproduce it. In essence:

  • One specific process is running Streamlit and images (from pyplot in this case) are generated and stored in memory for that process.
  • Streamlit Share has multiple processes and a system designed to have messages/requests target the same process to grab the correct custom generated image/video/media.
  • That process fails when making image (and probably other media) requests. It's targeting any process, and if it targets the wrong one, the image will not be found. This is why you see some requests work and some don't (that may seem random).

I had trouble by uploading the same code to my personal Streamlit share because there was no problem. That is because my service is only one process. When a process gets too much attention (as in your case when we marketed it for Streamlit Share), we add more resources to it and now we have multiple processes causing the issue. I was able to demonstrate this on my system by upping the number of processes.

So the easy workaround for you is to delete the app and redeploy it (thereby making it seem like a new single process app for now). I believe that would work and would bypass some internal communication chain to reduce resources. If the app gets more attention, we can increase those resources again, but hopefully we'll have a fix in time. If you do that, let me know if that works/doesn't work. If that's unacceptable, I can look through my end and see if I can reduce the resources, just a little more red tape.

To summarize for @chakra-ai I wonder if your Azure solution is creating multiple processes (at least more than 1) and creates the same problem above. If that's the case, I don't have a clear solution. We are spending a lot of time figuring our the solution for Streamlit Share that I can't speak for on Azure, but I am bringing it up as a big point for the team to think about prioritization at the very least.

@tylerjrichards
Copy link
Collaborator

tylerjrichards commented Jan 7, 2021

hey @kmcgrady! Thank you for the incredibly detailed response. I've been trying to fix this issue on my end as well the past couple days. I tried the solution of just deleting the app and redeploying it, but even after a day of the app being in the oven, it never actually built.
My next effort was to make an entirely new repo with the same files but a different repo name, and push that to Streamlit sharing, which ended up working perfectly well. My guess is that something on your end didn't allow my app to go from the multiple processes to single process for an app with the same repo name, but you definitely know better than me. Also, if I change the name of my original github repo, and then redeploy, everything works great again.

thank you for your help, i'm super grateful for it.

@kmcgrady
Copy link
Collaborator

kmcgrady commented Jan 7, 2021

Thanks @tylerjrichards! I informed our cloud team of the challenge you had redeploying. Hopefully they'll sort something out. Glad redeploying under a name worked.

@Suvoo
Copy link

Suvoo commented Jan 17, 2021

I am still facing the same issue, any help is appreciated

@tvst
Copy link
Contributor

tvst commented Jan 20, 2021

Hey Suvoo, can you open a new bug and include some more info?

In particular:

  1. Steps to reproduce (with example app or code, if possible!)
  2. Streamlit version
  3. Do you see this in Streamlit sharing? Or when deployed some other way?
  4. Do you see any errors in the browser's devtools' console and network tab?

Thanks!

@Suvoo
Copy link

Suvoo commented Jan 20, 2021

st.image("C:\\Users\\91865\\Desktop\\Streamlit Demo\\data\\sal.jpg")
This produces an error and shows a 0 icon when used on the page, but using

from PIL import Image
image = Image.open('C:\\Users\\91865\\Desktop\\Streamlit Demo\\data\\sal.jpg') 
st.image(image) 

While this works totally fine. I don't see why this happens

@knorthover
Copy link

knorthover commented Jan 22, 2021

Thanks Suvoo. I just encountered this issue and your workaround using PIL fixed it. Streamlit, version 0.73.0, Windows 10. What baffles me is that the st.image/st.sidebar.image call is in a page base class for a multi-page app that has been running reliably for over a year - I'm getting this testing standalone a new page subclassed from the same base class as the others. It's the first time I've ever seen this issue. Weird.

@tvst This is happening in the application we talked about a while back. Here's a screen snip of a test. The sidebar image is using Suvoo's workaround, the main frame one is the same filepath but provided directly to st.image. The sidebar one is called from the base class, the main frame from the sub-classed application page

image

Kevin

@jeffreyssimon
Copy link

I was having this same issue when deploying to GCP App Engine and was able to solve it with help from the @kmcgrady post above (thank you!). The key is multiple instances. If you use the default configs on App Engine you are going to have multiple instances (VMs) underlying your application and this is going to cause 404s to from the HTTP image fetch outside the websocket. When I force the instance count to 1, this issue goes away and all of the images render properly. Of course, I loose autoscaling which isn't ideal but at least the app works properly.

@XDynames
Copy link

XDynames commented May 19, 2021

For those using GKE you can resolve this by making sure the application container's replicas is set to one

spec:
  replicas: 1

@igormintzviz
Copy link

I had "0" showing instead of an image when trying to get the image from a server. My mistake was not writing "http://" before the url. adding it resolved the problem.

@aaossa
Copy link

aaossa commented Apr 6, 2022

I was having this same issue when deploying to GCP App Engine and was able to solve it with help from the @kmcgrady post above (thank you!). The key is multiple instances. If you use the default configs on App Engine you are going to have multiple instances (VMs) underlying your application and this is going to cause 404s to from the HTTP image fetch outside the websocket. When I force the instance count to 1, this issue goes away and all of the images render properly. Of course, I loose autoscaling which isn't ideal but at least the app works properly.

Hi, is there any workaround for this? I'm deploying to GCP and several images are generated dynamically, so when using multiple instances some of them are replaces by the "0" and some of them are displayed. Of course this is not optimal and we're hoping to use Streamlit in production, but at the moment there's no reliable way to display all the images consistently. Is this address by Streamlit somehow or it's not fixable and should I try another library?

@tzoukritzou
Copy link

Hi there, I'm having the same issue. When I run the app locally it works fine, but when I deploy on Heroku, random plots everytime show "0" instead.

I'm not even loading an image, what I'm doing is:

fig, ax = plt.subplots()
df.plot(..., ax=ax)
st.pyplot(fig)

I'm having multiple pieces of code like this with different plots in the same streamlit page, every time, some are shown and some are not but they are not always the same.

@yucsong
Copy link

yucsong commented Apr 20, 2022

Streamlit, version 1.8.1 still has the issue ...

2022-04-20 08:45:37.024 InMemoryFileManager: Missing file 8f38e6ff47a0a683fe589238cf5f5db9c04efeaf6ed930e129ea082e.png

@mark-foerster
Copy link

Same problem (Streamlit 1.8.1):

2022-04-28 10:53:36.820 InMemoryFileManager: Missing file c669431943be2067b62db57fdf9ba81deec9f17f2bdfaaa2df6fdc09.png

@rd-andreas-lay
Copy link

Can confirm the issue. Only occurs in deployment though, not when running streamlit locally. It's a simple

st.image("logo.webp")

Error message: InMemoryFileManager: Missing file 1156bb4e04fc0aaf71e4a8dfcf917b11a54797812e23e860bf0dae28.jpeg

@kalfasyan
Copy link

kalfasyan commented Jun 17, 2022

Facing the same issue with version 1.10.0 when running on streamlit-cloud.

This error shows: streamlit InMemoryFileManager: Missing file x.jpeg and then logged out of my app.

I'm using streamlit-authenticator but I don't think it has something to do with that according to what I read here.

@kmcgrady
Copy link
Collaborator

I see numerous more cases of this issue happening in this thread. To be clear, here's what goes on below the hood:

  • images are loaded and stored in memory per script run.
  • images are only removed when the latest script run does not use images from the previous script run.

With that in mind, this leads to some important outcomes.

  • If you have your streamlit app running with replicas behind a load balancer, you will see issues. The image is stored in the memory of the app where the script ran and is connected. If your request for the image is received with a different replica, it will not respond. The best solution is to enable some sort of sticky routing. We have some thoughts on this, but it's going to be a longer time to a solution.
  • If you are assuming that images are being received past the script run will be generated, this may present a problem. I imagine this less a use case.

Outside of above, if you have a simple code example/repro steps to demonstrate the issue. It would be very helpful.

@mikeolubode
Copy link

I see numerous more cases of this issue happening in this thread. To be clear, here's what goes on below the hood:

  • images are loaded and stored in memory per script run.
  • images are only removed when the latest script run does not use images from the previous script run.

With that in mind, this leads to some important outcomes.

  • If you have your streamlit app running with replicas behind a load balancer, you will see issues. The image is stored in the memory of the app where the script ran and is connected. If your request for the image is received with a different replica, it will not respond. The best solution is to enable some sort of sticky routing. We have some thoughts on this, but it's going to be a longer time to a solution.
  • If you are assuming that images are being received past the script run will be generated, this may present a problem. I imagine this less a use case.

Outside of above, if you have a simple code example/repro steps to demonstrate the issue. It would be very helpful.

Thanks for explaining the problem. My app runs with replicas behind a load balancer, I solved the 0-image problem by using sticky routing. Adding the sticky-cookies-services annotation here worked for me.

@jayne-urbansim
Copy link

FYI in case other folks come across this, we were able to fix our images loading issue with this:
https://cloud.google.com/run/docs/configuring/session-affinity

@christopher-w-murphy
Copy link

My team solved this issue on Kubernetes on Azure by enabling Cookie Based Affinity, https://azure.github.io/application-gateway-kubernetes-ingress/features/cookie-affinity/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:bug Something isn't working type:regression This bug is a regression
Projects
None yet
Development

Successfully merging a pull request may close this issue.