Automatically restart a Python program if it's killed - python

I run a Python Discord bot. I import some modules and have some events. Now and then, it seems like the script gets killed for some unknown reason. Maybe because of an error/exception or some connection issue maybe? I'm no Python expert but I managed to get my bot working pretty well, I just don't exactly understand how it works under the hood (since the program does nothing besides waiting for events). Either way, I'd like it to restart automatically after it stops.
I use Windows 10 and just start my program either by double-clicking on it or through pythonw.exe if I don't want the window. What would be the best approach to verify if my program is still running (it doesn't have to be instant, the verification could be done every X minutes)? I thought of using a batch file or another Python script but I have no idea how to do such thing.
Thanks for your help.

You can write another python code (B) to call your original python code (A) using Popen from subprocess. In python code (B), ask the program to wait for your python code (A). If 'A' exits with an error code, recall it from B.
I provide an example for python_code_B.py
import subprocess
filename = 'my_python_code_A.py'
while True:
"""However, you should be careful with the '.wait()'"""
p = subprocess.Popen('python '+filename, shell=True).wait()
"""#if your there is an error from running 'my_python_code_A.py',
the while loop will be repeated,
otherwise the program will break from the loop"""
if p != 0:
continue
else:
break
This will generally work well on Unix / Windows systems. Tested on Win7/10 with latest code update.
Also, please run python_code_B.py from a 'real terminal' which means running from a command prompt or terminal, and not in IDLE.

for problem you stated i prefer to use python subprocess call to rerun python script or use try blocks.
This might be helpful to you.
check this sample try block code:
try:
import xyz # consider it is not exist or any error code
except:
pass # go to next line of code to execute

Related

How to get a response from script when using subprocess.Popen(cmd,shell = True)

I am using the following code to execute a .py file that has some Selenium stuff:
cmd = 'python my_sellenium_script.py'
p = subprocess.Popen(cmd,shell = True)
out,err = p.communicate()
print(out)
print(err)
The problem is that sometimes the pages selenium should open crash or otherwise return a error. I need to know when this happens, so I can try to run the subprocess.Popen(cmd,shell = True) again. Or know if the code ran as expected so I can print a success message.
I have tried using out,err = p.communicate(), but it return none, regardless the outcome of the my_sellenium_script.py.
Is there something I can put on my_sellenium_script.py so it returns some value to the subprocess?
I am well aware that what I am doing is not good coding. I know I should learn how to use modules, etc... (Believe me, I am working on it). And although, I would appreciate the comments on how I could improve as a programer and stop doing things the wrong way, I would also like to know how can I solve this particular problem.
For more context:
I need to run this selenium file on schedule (on windows), but for some reason, the machine I am using goes to sleep after a while and does not run any scheduler (native windows task scheduler or third party), I have tried tweaking the configuration, but I just does not work. So I found a python script that keeps the PC wake (by turning the volume up and down every 3 minutes) and inside it I am creating my own scheduler (gross, I know, no need for codeshaming, I well aware that I am trash).

python prompt available whilst outputting data

I'm fairly new to python and need help with the following.
Say I have some code which is continually outputting data to the Python console, e.g.:
for x in range(10000): print x
I then want to be able to enter various commands which may affect the output immediately. For example, I enter a number which causes the loop to start again from this number, or I enter step=2, which causes the step level to change, etc.
Basically, I want the code to run and print in the background, while the prompt is still available.
Is such a thing possible? I'm guessing the output would have to be sent to a new window, but I am unsure how this would work out in practice. I would prefer no GUI at the moment, as I just want to keep things as simple as possible.
As #BlueRhine S says start a background thread. Here is a link to the standard library threading module docs. I would probably prefer to start a sub-process though and use a pipe to communicate between your foreground process and the worker process. Here is a link to those docs

Delay the execution of a Python script on Anaconda prompt?

I am running some scientific experiments that take a lot of time. Everything is written in Python 3 and I use the Anaconda Command Prompt to activate the Python scripts. I am working on Windows.
Right now, an experiment is running. I want to execute the next experiment as soon the current experiment is finished, however, I will not be near this computer when that happens. Is there a way to execute a Python script with, say, a 4 hour delay so I do not waste a night of precious computation time?
Potentially, adding a long sleep statement in my main python script could do the trick but I was wondering if any of you has a more elegant solution to the problem.
there is a way with Windows Task Scheduler, you should see the following:
https://www.youtube.com/watch?v=n2Cr_YRQk7o
when you set the trigger set it as you like (in 4 hours)
While sleep could be a dirty work around, you could also make use of the innate tasksceduler of windows, like XtoR stated.
You could also call to the other script at the end of your current one, by inserting the following bit of code into the first script.
import subprocess
import sys
sys.pid = subprocess.pOpen([path_to_python_executable, 'path_to_second_script'])
Personally I'm predisposed towards writing a quick wrapper script.
import subprocess
import sys
# We're just providing the python path here. Make sure to change according to system settings
python_path = 'C:\Python\python.exe'
# Here we specify the scripts you want to run.
run_script_one = 'C:\Path_to_first_script.py'
run_script_two = 'C:\Path_to_second_script.py'
sys.pid = subprocess.call([python_path, run_script_one])
sys.pid = subprocess.call([python_path, run_script_two])
sys.exit(0)

Python script to script enter and exit

I am trying to create a python script that on a click of a button opens another python script and closes itself and some return function in the second script to return to the original script hope you can help.
Thanks.
Since your question is very vague, here's a somewhat vague answer:
First, think about whether you really need to do this at all. Why can't the first script just import the second script as a module and call some function on it?
But let's assume you've got a good answer for that, and you really do need to "close" and run the other script, where by "close" you mean "make your GUI invisible".
def handle_button_click(button):
button.parent_window().hide()
subprocess.call([sys.executable, '/path/to/other/script.py'])
button.parent_window().show()
This will hide the window, run the other script, then show the window again when the other script is finished. It's generally a very bad idea to do something slow and blocking in the middle of an event handler, but in this case, because we're hiding our whole UI anyway, you can get away with it.
A smarter solution would involve some kind of signal that either the second script sends, or that a watcher thread sends. For example:
def run_other_script_with_gui_hidden(window):
gui_library.do_on_main_thread(window.hide)
subprocess.call([sys.executable, '/path/to/other/script.py'])
gui_library.do_on_main_thread(window.show)
def handle_button_click(button):
t = threading.Thread(target=run_other_script_with_gui_hidden)
t.daemon = True
t.start()
Obviously you have to replace things like button.window(), window.hide(), gui_library.do_on_main_thread, etc. with the appropriate code for your chosen window library.
If you'd prefer to have the first script actually exit, and the second script re-launch it, you can do that, but it's tricky. You don't want to launch the second script as a child process, but as a sibling. Ideally, you want it to just take over your own process. Except that you need to shut down your GUI before doing that, unless your OS will do that automatically (basically, Windows will, Unix will not). Look at the os.exec family, but you'll really need to understand how these things work in Unix to do it right. Unless you want the two scripts to be tightly coupled together, you probably want to pass the second script, on the command line, the exact right arguments to re-launch the first one (basically, pass it your whole sys.argv after any other parameters).
As an alternative, you can use execfile to run the second script within your existing interpreter instance, and then have the second script execfile you back. This has similar, but not identical, issues to the exec solution.

Python equivalent of IDL's stop and .reset

I'm relatively new to python but have a bit of experience using IDL. I was wondering if anyone knows if there are equivalent commands in python for IDL's stop and .reset commands.
If I'm running some IDL script I wrote that I put a stop command in, essentially what it does is stop the script there and give me access to the command line in the middle of the script. So I have access to all the functions and variables that I defined before the stop command, which I find really useful for debugging.
The .reset command I find extremely useful too. What it does is reset the the IDL environment (clears all variables, functions, etc.). It's as if I closed that session and opened a new one, but without having to exit and restart IDL. I find that if I'm trying to debug a script I wrote it's useful sometimes to start from scratch and not have to reset IDL (or python now). It would be useful also in python to be able to un-import any modules I had previously imported.
Any help with these issues would be greatly appreciated.
Cheers
Related
Python Drop into REPL
Is it possible to go into ipython from code?
IPython (aside from being a far nicer REPL than the standard python interpreter) may do what you want:
from IPython.Shell import IPShellEmbed
start_shell = IPShellEmbed()
def times_2(x):
return 2*x
a = 5
start_shell()
# now in IPython shell
# a -> 5
# times_2(a) -> 10
Note that any changes you make in the shell will not be sent back to the main python process on exit - if you set a = 10 in IPython (using the above example), a is still equal to 5 in the main python process.
edit: post on IPython-user mailing list where I first saw this technique.
stop sounds equivalent to use of the code module. .reset doesn't have an equivalent in Python short of gratuitous use of del.
Use pdb, as in this short script. Run it at the command line, and the PDB prompt will magically appear allowing single stepping, evaluation of arbitrary expressions, etc.
#!/usr/bin/env python
import pdb;
print 1
print 2
pdb.set_trace()
print 3
print 4
You could do %reset from within an IPython shell.
For stops, just add pydebug breakpoints as mentioned
pdb.set_trace() breaking out of code apparently does not allow you to ".continue" (IDL command) from that point (from http://pythondammit.blogspot.fr/2012/04/equivalent-of-idls-stop-command.html)
An update to redacted's solution.
The interactive IPython is much more powerful and convenient than pdb.set_trace.
Try this script
from IPython import embed
a = 1
b = 2
print('before')
embed()
print('after')
c = 3
Put embed() where you want to interrupt.
Run the script you will enter an interactive IPython Shell, you can view and modify the variables.
The script will continue after you exiting the shell.
You probably just want to use a Python debugger for this.
Welcome to the Python community! I'm still learning, but imo Python's nicer than the Interactive Data Language.
Anyway, Ignacio's answer about using the code module looks like it may provide what you want, at least as far as a parallel to IDL's stop.
Another thing you may find useful is to go into Python's interactive mode and import your program. You can then interact with it by running functions, etc. (Admittedly, I'm no expert at this.) If you do this, you'll need a main() function in the file which drives the program. For example, you'd have something like:
import sys
def main():
# do stuff
return(0)
if __name__ == '__main__':
sys.exit(main())
instead of just:
# do stuff
This prevents the execution of the program when you pull it into the Python interpreter. For more, see Guido's article about main functions.

Categories

Resources