11

I'm telling jupyter to execute a python script:

!python build_database.py

When executed from the terminal, the python script prints the progress during execution. However, in the jupyter notebook, I get all output printed as a list of strings, AFTER the execution. Is there a way to see the output live?

2
  • 2
    More full featured support in Jupyter is to use %run and not !python. In this example, that would be%run build_database.py. It often gives a different, better experience depending on your system. Plus, it has more options, see here. Commented Jan 28, 2022 at 4:37
  • 1
    There's some settings about buffering that can be adjusted. There's a related discussion on the Jupyter Discourse Community Forum here. Commented Jan 28, 2022 at 4:41

2 Answers 2

13

It looks like it is not possible out of the box. The output handling of shell commands is buried deep in ipython internals.

One of solutions i would recommend is to create custom magic method based on code below.

Check this answer

Based on it i created a simple magic method that you can use:

from subprocess import Popen, PIPE, STDOUT

from IPython.core.magic import register_line_magic


@register_line_magic
def runrealcmd(command):
    process = Popen(command, stdout=PIPE, shell=True, stderr=STDOUT, bufsize=1, close_fds=True)
    for line in iter(process.stdout.readline, b''):
        print(line.rstrip().decode('utf-8'))
    process.stdout.close()
    process.wait()

Or Popen can be used as context manager. So the code will be a bit more readable and reliable. See docs

Popen objects are supported as context managers via the with statement: on exit, standard file descriptors are closed, and the process is waited for.

from subprocess import Popen, PIPE, STDOUT

from IPython.core.magic import register_line_magic


@register_line_magic
def runrealcmd(command):
    with Popen(
        command, stdout=PIPE, shell=True, stderr=STDOUT, bufsize=1, close_fds=True
    ) as process:
        for line in iter(process.stdout.readline, b""):
            print(line.rstrip().decode("utf-8"))

Usage:

%runrealcmd ping -c10 www.google.com

Above code probably could be written better but for your needs it should be perfectly fine.

Sign up to request clarification or add additional context in comments.

11 Comments

It doesn´t change the fact for me that the result is returned after complete execution.
I will research the problem some more and get back to you.
Maybe an important detail: The script build_database.py uses print() to output the progress I want to see in realtime
I have updated my answer, take a look if that solution satisfies you
@LukeDavis great to hear that! You should also be able to use Popen as context manager. I've added example in my original answer.
|
3

I refer to this answer: How to show real time process command line in Jupyter Notebook?

Just execute your python script as:

%run build_database.py

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.