Emulate Terminal Output in Dash UI Textarea Component

Viewed 327

My goal is to have a dcc.Textarea that the user will not interact with, but will be shown details about actions taken on the server side. Ideally, I would like to reuse my print() commands and take what is displayed in my terminal to the Dash UI textarea.

Since I do not have another Dash UI component driving the Input of the callback, how can I make a function call with the message to display, then append and scroll the textarea as my terminal behaves?

Here is some code to outline the problem, and print the list to the textarea. The callback decorator is commented out as it will cause an error without the Input() defined.

Thanks much for any and all assistance!

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import dash_bootstrap_components as dbc

app = dash.Dash(__name__)
app.layout = html.Div([

    dcc.Textarea(
        id='log_output_textarea',
            title='Actions Executed Will Be Output Here',
            value='',
            cols=100,
            disabled=True,
    )

])


#@app.callback(
#    Output('log_output_textarea', 'value'),
#    [Input()],
#    [State('log_output_textarea','value')]
#)
def log_to_textarea():
    example_log_items_to_display = ['API Call Executed', 'Database Updated', 'Calculation Details']
    for log in example_log_items_to_display:
        print(log) # Instead of printing to std.out, log to UI textarea

if __name__ == '__main__':
    app.run_server(debug=True)
    log_to_textarea()
1 Answers

The way the project I'm working on captures the stdout is with contextlib. Below is a small code sample that should get the information you are looking for, which you can then append to the value of the textarea:

from contextlib import redirect_stdout
import io

with redirect_stdout(io.StringIO()) as output:
    # Your code that generates output here
    ...

    # This will get the lines from the output
    lines = output.getvalue().splitlines()

    # Append `lines` to the textarea content here
    ...
Related