Caching without hashing the code

Greetings,
Is there a hack, which does not involve modifying the streamlit library, to use st.cache() without it hashing the code? If not, why not?
(It would allow the developer to control exactly what is looked at. It might also break codes which first referenced a st object in the code which is to be decorated by st.cache, though I did not try. But then, doing so without removing the code hashing does not run already because the hashing would fail first.)

I am displaying a kind of DeepDream. In that version, there are several resizings interleaved with ‘‘dream’’ generations. After each ‘‘dream’’ at a size, I change the content of a st.image that I previous referenced (to see the intermediate results as they are being computed). After the last resize and ‘‘dream’’, I return the newly generated image and put into the previous reference of the st.image an ImageChops.blend of the original image and the generated image. I created a slider for the blending (the alpha argument).
Now, when moving the slider I only want the blending to be recalculated from the previously generated image (without generating again the ‘‘dream’’ image).
Because I have some ‘‘st.image’’ in the code (and some other things), the code hashing fails.

Two points:

  • I could sub-divide my function and make sub functions that only contain the computation part and then decorate just these. But that is going to require quite some efforts and suddenly streamlit would appear less appealing to me in its usage.
  • Commenting lines 522 to 524 of the caching.py file of the library allowed me to do just that at the cost of not working with the official branch of streamlit.

Just as an example of the problem caused by the code hashing (the ‘‘f function’’ I use for my application is way uglier, this f is enough to trigger the ‘‘TypeError: object supporting the buffer API required’’):


original_img = get_img_from_url(img_url) #where original_img is a PIL Image returned from a string containing a valid url of a png or jpg image
img2 = st.image(original_img)

def f(_img_url):
->img2
->return original_img

@st.cache()
def cached_dream(_img_url):
->return f(_img_url)

dreamed_img = cached_dream(img_url)

Hi @RR5555 - thanks for checking out Streamlit!

In the currently-released version of the library, there’s no way to achieve what you’re looking for.

However! There’s a feature in progress (the “cache escape hatch” - see this PR and this issue for more details) that will give you the ability to selectively override the caching mechanism that @st.cache uses.

When this lands in a Streamlit release, you’ll be able to do something like:

@st.cache(hash_funcs={PIL.Image: (lambda x: 1234)})  # Or any random constant
def cached_dream(_img_url):
    return f(_img_url)

This will tell the caching function to call your custom hashing function (a lambda that just returns a constant value) for image objects returned from cached_dream, which will effectively skip the hashing process that Streamlit uses under the hood.

This should appear in Streamlit in the next few weeks!