So I am creating a script that needs to be run 24/7 on a server machine. I have created try/excepts to catch if the script stops for any reason and send me an email.
However, there is nothing that will happen if the command line is closed. Therefore, there will be no notification if the command line closes for any reason while the script stops.
I'm not sure how to add code to be able to do that, but it is important because I need to know anytime the script has been stopped. At the moment I can only check if it is stopped in any way except closing the window.
Here's a simple answer that I hope will work for you using python's atexit module:
import atexit
def exit_handler():
# do this stuff when the script exits
return
atexit.register(exit_handler)
Keep in mind the exit handler function won't execute if there is some sort of fatal internal error or it was terminated at a low level, but for this most part this should work :)
Related
I am running some Python code using a SLURM script on a remote server accessed through SSH. At some point, issues related to licenses on the SLURM platform may happen, generating errors in Python and ending the subprocess. I want to use try-except to let the Python subprocess wait until the issue is fixed, after that it can keep running from where it stopped.
What are some smart implementations for that?
My most obvious solution is just keeping Python inside a loop if the error occurs and letting it read a file every X seconds, when I finally fix the error and want it to keep running from where it stopped, I would write something on the file and break the loop. I wonder if there is a smarter way to provide input to the Python subprocess while it is running through the SLURM script.
One idea might be to add a signal handler for signal USR1 to your Python script like this.
In the signal handler function, you can set a global variable or send a message or set a threading.Event that the main process is waiting on.
Then you can signal the process with:
kill -USR1 <PID>
or with the Python os.kill() equivalent.
Though I do have to agree there is something to be said for the simplicity of your process doing:
touch /tmp/blocked.$$
and your program waiting in a loop with a 1s sleep for that file to be removed. This way you can tell which process id is blocked.
I have a python script that launches a subprocess which then opens a python terminal window that displays its running logs/status output.
If the user closes the window, the process terminates - this is desirable. However, I cannot figure out a way to "catch" and log if the user manually terminates the script (closes window).
I have tried putting my main() in a try/except block but it seems that no exceptions are being raised (like a KeyboardInterrupt).
Also tried atexit package - but this seems only to take into effect at normal script termination.
Is there a way to log/print to file when a user terminates a script mid run?
I am trying to implement some basic close out tasks for an automation script I have written in python using pyautogui. I open a program and click certain buttons every day to create daily reports. But if something goes wrong, I need it to close the program it is using.
I tried using atexit.register, but it didn't seem to run when I trigger sys.exit(). So I wrote a test script to verify that it was triggering, and it isn't.
import atexit as a
import sys
def closeout():
print("atexit triggered, closing out")
print("starting program")
print("Registering closeout with atexit")
a.register(closeout)
print(r"triggering sys.exit()")
sys.exit()
it should print out the following:
"starting program"
"Registering closeout with atexit"
"triggering sys.exit()"
"atexit triggered, closing out"
but I don't get the last line.
Any thoughts? I'm running 3.7.2 if it matters.
When you "run module" from IDLE, it uses the compile builtin to build a code object from the associated file, and then runs it with exec. The process that runs the code doesn't exit, and SystemExit is caught and silently ignored in the IDLE interpreter - otherwise a script that included it would cause IDLE to quit! - so the atexit handler isn't run.
Furthermore, the default build of IDLE is configured to delete any register atexit functions when exiting, so your handler isn't run when IDLE itself eventually exits. (See the exit function in the cpython repo.)
Basically I am writing a script that can be stopped and resumed at any time. So if the user uses, say PyCharm console to execute the program, he can just click on the stop button whenever he wants.
Now, I need to save some variables and let an ongoing function finish before terminating. What functions do I use for this?
I have already tried atexit.register() to no avail.
Also, how do I make sure that an ongoing function is completed before the program can exit?
Solved it using a really bad workaround. I used all functions that are related to exit in Python, including SIG* functions, but uniquely, I did not find a way to catch the exit signal when Python program is being stopped by pressing the "Stop" button in PyCharm application. Finally got a workaround by using tkinter to open an empty window, with my program running in a background thread, and used that to close/stop program execution. Works wonderfully, and catches the SIG* signal as well as executing atexit . Anyways massive thanks to #scrineym as the link really gave a lot of useful information that did help me in development of the final version.
It looks like you might want to catch a signal.
When a program is told to stop a signal is sent to the process from the OS, you can then catch them and do cleanup before exit. There are many diffferent signals , for xample when you press CTRL+C a SIGINT signal is sent by the OS to stop your process, but there are many others.
See here : How do I capture SIGINT in Python?
and here for the signal library: https://docs.python.org/2/library/signal.html
I want to invoke an external GUI application from a python script which will be triggered upon some file upload to the server.
I would like the process to be launched and kept running whereas the python script should continue and eventually finish its job and quit. I have tried different options but none proved successful.
Right now the script expects the application to be closed before script exits and sends the response.
I tried Subprocess, Popen, os.System, Spawnl, Spawnlp in the main thread as well by calling these API's in a separate thread. There are lot of questions asked in this regard in stackoverflow and other forums. But I couldn't get the exact solution for this yet.
Appreciate any help.
had exactly the same problem and took me friggin ages to find it, but here is your answer:
import win32api
win32api.ShellExecute(0, "open", "python.exe", 'blah.py', '', 1)
This guarantees you an independent process - even after you exit the calling python program, this will continue to work.