8

How can I redirect/show the console output (including outputs I print inside the program) so it would appear inside a Dash app (On the screen the user sees)?

Daniel F
  • 13,684
  • 11
  • 87
  • 116
Roee Anuar
  • 3,071
  • 1
  • 19
  • 33

3 Answers3

7

I didn't find a way for Dash to read the console output directly, so I used a workaround using a text file. Here is a sample code which prints the last 20 lines of the console output to an Iframe (as to keep the line breaks, which do not show in other text/div components):

import dash_core_components as dcc
import dash_html_components as html
import dash
import sys

f = open('out.txt', 'w')
f.close()


app = dash.Dash()

app.layout = html.Div([
    dcc.Interval(id='interval1', interval=1 * 1000, 
n_intervals=0),
    dcc.Interval(id='interval2', interval=5 * 1000, 
n_intervals=0),
    html.H1(id='div-out', children=''),
    html.Iframe(id='console-out',srcDoc='',style={'width': 
'100%','height':400})
])

@app.callback(dash.dependencies.Output('div-out', 
'children'),
    [dash.dependencies.Input('interval1', 'n_intervals')])
def update_interval(n):
    orig_stdout = sys.stdout
    f = open('out.txt', 'a')
    sys.stdout = f
    print 'Intervals Passed: ' + str(n)
    sys.stdout = orig_stdout
    f.close()
    return 'Intervals Passed: ' + str(n)

@app.callback(dash.dependencies.Output('console-out', 
'srcDoc'),
    [dash.dependencies.Input('interval2', 'n_intervals')])
def update_output(n):
    file = open('out.txt', 'r')
    data=''
    lines = file.readlines()
    if lines.__len__()<=20:
        last_lines=lines
    else:
        last_lines = lines[-20:]
    for line in last_lines:
        data=data+line + '<BR>'
    file.close()
    return data

app.run_server(debug=False, port=8050)
Roee Anuar
  • 3,071
  • 1
  • 19
  • 33
2

Create a custom LoggerHandler, and use dcc.Interval for refreshing.

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import dash
import logging

class DashLoggerHandler(logging.StreamHandler):
    def __init__(self):
        logging.StreamHandler.__init__(self)
        self.queue = []

    def emit(self, record):
        msg = self.format(record)
        self.queue.append(msg)

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
dashLoggerHandler = DashLoggerHandler()
logger.addHandler(dashLoggerHandler)

app = dash.Dash()

app.layout = html.Div([
    dcc.Interval(id='interval1', interval=5 * 1000, n_intervals=0),
    html.H1(id='div-out', children='Log'),
    html.Iframe(id='console-out',srcDoc='',style={'width': '100%','height':400})
])

@app.callback(
    Output('console-out', 'srcDoc'),
    Input('interval1', 'n_intervals'))
def update_output(n):
    return ('\n'.join(dashLoggerHandler.queue)).replace('\n', '<BR>')

app.run_server(debug=False, port=8050)

betontalpfa
  • 3,454
  • 1
  • 33
  • 65
0

One possible way to do this is supply it as input to Dash Core Component Text Area's value property. This should work if its a string.

Haskar P
  • 420
  • 4
  • 9