Show code optional wrapper

I am trying to create an optional st.echo that users of the app can look at the code whenever they are curious but hidden by default. To reduce the code for each of these occations, I though of a with st.opt_echo(): context.

My first attempt is the following:

import streamlit as st

class opt_echo:

    def __init__(self):
        self.checkbox = st.checkbox("show code")
        if self.checkbox:
            self.echo = st.echo()
    def __enter__(self):
        if self.checkbox:
            return self.echo.__enter__()
    def __exit__(self, type, value, traceback):
        if self.checkbox:
            self.echo.__exit__(type, value, traceback)

with opt_echo():
    st.write("hello.")

However, due to the way st.echo is implemented, this outputs not β€˜st.write(β€œhello”)’ to the app but the code of the __exit__ function.

I somehow would have to modify frame = _traceback.extract_stack()[-3] in
(https://github.com/streamlit/streamlit/blob/78f9b977da3ef25ef9cbc2d14007facdc4f23482/lib/streamlit/init.py#L529)https://github.com/streamlit/streamlit/blob/78f9b977da3ef25ef9cbc2d14007facdc4f23482/lib/streamlit/init.py:529

  1. What would be the solution that reuses most of the st.echo code?
  2. I am guessing this would be feature many users might be interested in so maybe this could even be added to the api?

Best

Hi @mwllwm. Challenge accepted!

Here’s an ungodly hack that will do what you want: https://gist.github.com/tvst/6e62360a712ed0595e7a0749127fba58

It works by replacing traceback.extract_stack when inside the context manager, and then restoring it afterward. Since it modifies a Python module (and modules are global) this means you can’t use this code when you have multiple threads that depend on traceback.extract_stack. Other than that, it should work!

1 Like