subprocess output -> Output widget not working

23 views
Skip to first unread message

Randy Heiland

unread,
Mar 7, 2018, 10:03:40 AM3/7/18
to Project Jupyter
I'd like to be able to display output from a program in an Output widget. (And I'd like to be able to kill the program from a widget too). Can someone offer advice?

import ipywidgets as widgets
import subprocess, os

run_output = widgets.Output(layout=widgets.Layout(width='500px', height='100px', border='solid'))
run_output

def run_cb(b):
    #global run_output
    print('run sim...')
    with run_output:
        print('trying subprocess - does hello output show up?')
        args = ['hello']
        run_proc = subprocess.Popen(args)
        #os.system('hello')
    
run_button = widgets.Button(
    description='Run',
    disabled=False,
    button_style='success', # 'success', 'info', 'warning', 'danger' or ''
    tooltip='Run simulation',
)
run_button.on_click(run_cb)
run_button
widgets.VBox([run_button, run_output])

where hello.c is simply:

#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv) {
  int idx;
  for (idx=0; idx<4; idx++) { printf("argc=%d, %d) hello, world...\n",argc,idx); fflush(stdout); sleep(1); }
}

Thomas Kluyver

unread,
Mar 7, 2018, 10:38:27 AM3/7/18
to Project Jupyter
It doesn't put output into a widget, but it's using print(), so it should be easy to combine with a widget.

If you're happy to kill the process by interrupting the kernel from Jupyter, then it's just a matter of catching KeyboardInterrupt in the Python code.

Thomas

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscribe@googlegroups.com.
To post to this group, send email to jup...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/ffd113b2-d2b9-46e1-99fc-ed17e05423cf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Randy Heiland

unread,
Mar 7, 2018, 2:22:51 PM3/7/18
to Project Jupyter
Thomas,  Thanks very much! Following that example, I am indeed able to capture the output in my Output widget. I'm less clear about how to kill the running job (and keep the rest of the notebook alive). Here's my latest code, fwiw:

import ipywidgets as widgets
from subprocess import Popen, PIPE, STDOUT

run_output = widgets.Output(layout=widgets.Layout(width='500px', height='100px', border='solid'))
def run_cb(b):
    global my_proc
    print('run sim...')
    with run_output:
        args = ['hello']
        my_proc = Popen(args, stdout=PIPE, stderr=STDOUT)
        
    # This should be safe because we're not piping stdin to the process.
    # It gets tricky if we are, because the process can be waiting for input while we're waiting for output.
    while True:
        # Wait for some output, read it and print it.
        with run_output:
            my_output = my_proc.stdout.read1(1024).decode('utf-8')
            print(my_output, end='')

        # Has the subprocess finished yet?
        if my_proc.poll() is not None:
            break

    if my_proc.returncode != 0:
        print("Exited with error code:", my_proc.returncode)
        
def kill_cb(b):
    global my_proc
    print('kill proc...')
    my_proc.terminate()
run_button = widgets.Button(
    description='Run',
    disabled=False,
    button_style='success' # 'success', 'info', 'warning', 'danger' or ''
)
kill_button = widgets.Button(
    description='Kill',
    disabled=False,
    button_style='danger'
)

run_button.on_click(run_cb)
kill_button.on_click(kill_cb)
widgets.VBox([run_button, kill_button, run_output])
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+u...@googlegroups.com.

Thomas Kluyver

unread,
Mar 7, 2018, 7:02:01 PM3/7/18
to Project Jupyter
It won't process the message from the kill button until after it's done running the process.

What I'm suggesting is that you rely on Jupyter's interrupt feature (the stop button in the toolbar) to stop the process, instead of making your own kill button. To do that, all you need to do is catch the KeyboardInterrupt exception and call my_proc.terminate() in the exception handler.

To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscribe@googlegroups.com.

To post to this group, send email to jup...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages