Launching Programs

Sub-Process

If you want to execute another program on your machine, regardless of whether it’s a Python program or something else, you can use the subprocess module.

Let’s say you have another Python script called hello.py:

print("hello there!")

We could use subprocess from another Python program (say launch.py) to call this Python program like this:

import subprocess
import sys

completed = subprocess.run([sys.executable, 'hello.py'])
if completed.returncode == 0:
    print('Program excited successfully')
else:
    print('Program exited with an error code')
$ python launch.py
hello there!
Program excited successfully

To avoid having to make a list of all our arguments, we can set the shell argument to True and pass in a string:

import subprocess
import sys

completed = subprocess.run(f"{sys.executable} hello.py", shell=True)
if completed.returncode == 0:
    print('Program excited successfully')
else:
    print('Program exited with an error code')
$ python launch.py
hello there!
Program excited successfully

Capturing Output

If we wanted to capture standard output, we could do this:

import subprocess
import sys

completed = subprocess.run(f"{sys.executable} hello.py", capture_output=True, shell=True)
if completed.returncode == 0:
    print('Program excited successfully')
else:
    print('Program exited with an error code')
print('Output from subprocess:\n' + completed.stdout.decode('utf-8'), end='')

Note that on Windows you’ll likely need to decode with utf-16-le character encoding.

$ python launch.py
Program excited successfully
Output from subprocess:
hello there!

Asynchronous Execution

Let’s make our subprocess take a while to run and see what happens:

from time import sleep

print("hello there!")
sleep(2)
print("program ending")

Now when we run launch.py we’ll see our program hangs for a few seconds while it’s waiting for the subprocess to finish executing:

$ python launch.py
Program excited successfully
Output from subprocess:
hello there!

If we didn’t want to wait for our subprocess to complete before continuing execution, we could use the lower-level subprocess.Popen instead.

import subprocess
import sys

process = subprocess.Popen(
    [sys.executable, 'hello.py'],
    stdout=subprocess.PIPE,
)

# We can execute whatever we want here before we start waiting
print("The subprocess is executing now!")

process.wait()  # Wait for process to complete
if process.returncode == 0:
    print('Program excited successfully')
else:
    print('Program exited with an error code')
print('Output from subprocess:\n' + process.stdout.read().decode('utf-8'), end='')
$ python launch.py
The subprocess is executing now!
Program excited successfully
Output from subprocess:
hello there!
program ending

For more on subprocess, see the documentation and Python Module of the week.