Hirschdude
Hirschdude

Reputation: 145

How to display code in Streamlit based on user answer?

I'm trying to create a tutorial for a library with Streamlit. My overall idea ist to walk through the different functions and classes and explain them together with user based Input, so everything becomes a litte bit more understandable for beginners. However, I've written 5 Tutorials previously for more experienced users and would like to reuse some of that code by calling it from within my app and to only maintain it once.

Additionally, I'm walking through a lot of functions and classes, example config files e.g. and I'm calling them from a dict.

As Streamlit offers with st.echo an Option to run code and and then display it I've tried this. Also I've tried to use the python inspect Element together with st.write. However, st.echo simply displays the function name, and st.write together with inspect simply displays a string.


display_code = st.radio("Would you like to display the code?", ("Yes", "No"))

    if display_code == "Yes":
        with st.echo():
            example_function_1()



    else:
        example_function_1()

Basically I'm looking for an option to pass a function and based on user Input simply run it or run it and display the code and comments to it.

So if the user selected "Yes", the Output would be, while also x,y are returned.

def example_function_1():
     """ 
     This is and example functions that is now displayed. 
     """ 
     Some Magic
     return x, y 

And if the user selected No, then only x,y are returned

Upvotes: 1

Views: 4580

Answers (3)

Antoine Roland
Antoine Roland

Reputation: 1

For this task you can use st.code().

import streamlit as st

with open("test.py") as f:
    lines_to_display = f.read()
st.code(lines_to_display, "python")

Upvotes: 0

Tim Conkling
Tim Conkling

Reputation: 121

Here's a modified version of Streamlit's st.echo() that includes a checkbox:

import contextlib
import textwrap
import traceback

import streamlit as st
from streamlit import source_util


@contextlib.contextmanager
def maybe_echo():
    if not st.checkbox("Show Code"):
        yield
        return

    code = st.empty()
    try:
        frame = traceback.extract_stack()[-3]
        filename, start_line = frame.filename, frame.lineno

        yield

        frame = traceback.extract_stack()[-3]
        end_line = frame.lineno
        lines_to_display = []
        with source_util.open_python_file(filename) as source_file:
            source_lines = source_file.readlines()
            lines_to_display.extend(source_lines[start_line:end_line])
            initial_spaces = st._SPACES_RE.match(lines_to_display[0]).end()
            for line in source_lines[end_line:]:
                indentation = st._SPACES_RE.match(line).end()
                # The != 1 is because we want to allow '\n' between sections.
                if indentation != 1 and indentation < initial_spaces:
                    break
                lines_to_display.append(line)
        lines_to_display = textwrap.dedent("".join(lines_to_display))

        code.code(lines_to_display, "python")

    except FileNotFoundError as err:
        code.warning("Unable to display code. %s" % err)

You can use it exactly as you'd use st.echo. For example:

with maybe_echo():
    some_computation = "Hello, world!"
    st.write(some_computation)

Upvotes: 2

Cloudkollektiv
Cloudkollektiv

Reputation: 14699

You can use session state to pass on user input into on-screen actions. A clear example with radio buttons can be found here. Generally speaking, you need to use st.write() to accomplish this. A simplified example with a slider:

import streamlit as st

x = st.slider('Select a value')
st.write(x, 'squared is', x * x)

What you are looking for is not exactly possible, since you have to specify the function within the with st.echo() block. You can see it here:

import inspect
import streamlit as st

radio = st.radio(label="", options=["Yes", "No"])

if radio == "Yes":
    with st.echo():
        def another_function():
            pass
        # Print and execute function
        another_function()
elif radio == "No":
    # another_function is out of scope here..
    another_function()

Upvotes: 0

Related Questions