how to restart a python program after it crashes

Viewed 14740

I have a python script that starts a program and automates through it, continuously processing new data and saves to a pre-set directory.
What is the recommended way to run the Python script forever, logging errors when they occur, and restarting when it crashes?
so far I've came across the os.execv and have this to start:

import sys
import os
 
def pyexcept(t, v, tb):
   import traceback
## restarts the script
os.execv( sys.executable, '')

but I often get stuck trying to figure out the next step, could someone explain the next steps i could take, ty!

3 Answers

When the python script crashes, the program is not running anymore, therefore the script cannot execute more lines of code.

You have 2 options:

  1. Make sure your python script doesn't crash, which is very much recommended. You can do this by handling the exceptions thrown by your program.

Option 1

I assume you are new to python, so here is an example of a python script that handles an exception calls the same function again.

from time import sleep

def run_forever():
    try:
        # Create infinite loop to simulate whatever is running
        # in your program
        while True:
            print("Hello!")
            sleep(10)

            # Simulate an exception which would crash your program
            # if you don't handle it!
            raise Exception("Error simulated!")
    except Exception:
        print("Something crashed your program. Let's restart it")
        run_forever() # Careful.. recursive behavior
        # Recommended to do this instead
        handle_exception()

def handle_exception():
    # code here
    pass

run_forever()
  1. If you want to restart the python script you would need another python script (assuming you want to do this with python) that checks if the process is still alive and if not then run it again with python.

Option 2

This is the script that starts another python script called 'test.py' via the command python test.py. Make sure you have the right file path, if you put the scripts in the same folder, you usually don't need the full path and only the script name.

Notably, make sure that command 'python' is recognized by your system, it could in some cases by 'python3'

script_starter.py

from subprocess import run
from time import sleep

# Path and name to the script you are trying to start
file_path = "test.py" 

restart_timer = 2
def start_script():
    try:
        # Make sure 'python' command is available
        run("python "+file_path, check=True) 
    except:
        # Script crashed, lets restart it!
        handle_crash()

def handle_crash():
    sleep(restart_timer)  # Restarts the script after 2 seconds
    start_script()

start_script()

In case you are interested in the code I used for the test file: 'test.py', I post it here.

test.py

from time import sleep
while True:
    sleep(1)
    print("Hello")
    raise Exception("Hello")

It should be self-evident that if the Python script crashes, it cannot restart itself as it is no longer resident in memory. The answer, then, must come from something outside of Python operating at a lower level of abstraction than an application.

Linux often solves this with systemd. You could create a unit file describing the run of your application and start that service. systemd will then monitor the running process and restart it if it dies.

Windows usually solves this with Windows Services, which are executables with a special win32 API wrapper around them to allow the system to make calls into them to check their status, stop them, or restart them. NSSM (Non-Sucking Service Manager) is a helpful utility to create a service from any arbitrary command.

You have to use some external service to watch your python application. In windows you can run your python application as a windows service using Windows Service Wrapper.

Windows service wrapper (WinSW) is originally developed for run Jenkins client and server as a Windows service in Windows machine. But unlike other service wrappers, WinSW allow you to run any other applications like python.

You can provide all the configuration details as a XML file.

Few configurations you may interested

  • executable --> you can define which executable you wish to run (python in your case)
  • aruments --> you can provide arguments for the executable (ex - you can provide your application)
  • onFailure --> You can use onfailure configuration to specify what to do if your applications fails.
  • logpath --> you can specify the location for your logs.

and many more. Please read this file to know about all the configurations.

You should place your configuration XML file in the same directory where the WinSW executable located. Also there are few must implemented configurations which need to manage windows service (id, name, description, executable).

You can download the latest version from this link.

Related