Killing Python webservers - python

I am looking for a simple Python webserver that is easy to kill from within code. Right now, I'm playing with Bottle, but I can't find any way at all to kill it in code. If you know how to kill Bottle (in code, no Ctrl+C) that would be super, but I'll take anything that's Python, simple, and killable.

We use this.
import os
os._exit(3)
To crash in a 'controlled' way.

If you want to kill a process from Python, on a Unix-like platform, you can send signals equivalent to Ctrl-C at the console using Pythons os module e.g.
# Get this processes PID
pid_of_process = os.getpid()
# Send the interrupt signal to this process
os.kill(pid_of_process, signal.SIGINT)

Raise exeption and handle it in main or use sys.exit

Try putting
import sys
at the top and the command
sys.exit(0)
In the code that handles the "kill request".

Related

Python: How to make the function run unconditionally when the program ends?

I must ensure that the end_event() function is executed at the end of the program. I tried to implement this as Python's atexit. However, when the .py file was converted to an exe file with a PyInstaller and closed with a click, it did not work. I would appreciate it if you could tell me a solution that always works. Have a good day.
import atexit
import signal
import pyupbit
def end_event():
for keys in buy_list.keys():
order = upbit.get_order(keys)
if "state" in order:
if(order['state'] == 'wait'):
upbit.cancel_order(keys)
exit(1)
atexit.register(end_event)
signal.signal(signal.SIGINT, end_event)
There is no way to guarantee that code will run when the process exits, because there are ways to exit which do not permit any code to run.
User may pull the power cable. No code can run because there is no power.
External events (power outage, lightning strike), same as above.
Kill -9 or equivalent, e.g. Windows' TerminateProcess
Patterns for emergency cleanup.
The best pattern is: Never be in a state which requires emergency cleanup.
There is no guarantee that your cleanup will run because you could have a kill -9 or a power outage.
Therefore you need to be able to recover in that scenario.
See also: What does the POSIX standard say about thread stacks in atexit() handlers? What's the OS practice?

Python subprocess kill is working for "notepad.exe" but not working for "calc.exe"

OS: Windows 10
Python: 3.5.2
I am trying to open calc.exe do some actions and than close it.
Here is my code sample
import subprocess, os, time
p = subprocess.Popen('calc.exe')
#Some actions
time.sleep(2)
p.kill()
So this is not working for calc.exe, it just opens the calculator, but does not close it, But same code is working fine for "notepad.exe".
I am guessing that there is a bug in subprocess lib for process kill method. so the notepad.exe process name in task manager is notepad.exe, but the calc.exe process name is calculator.exe, so I am guessing it is trying to kill by name and do not find it.
There's no bug in subprocess.kill. If you're really worried about that, just check the source, which is linked from the docs. The kill method just calls send_signal, which just calls os.kill unless the process is already done, and you can see the Windows implementation for that function. In short: subprocess.Process.kill doesn't care what name the process has in the kernel's process table (or the Task Manager); it remembers the PID (process ID) of the process it started, and kills it that way.
The most likely problem is that, like many Windows apps, calc.exe has some special "single instance" code: when you launch it, if there's already a copy of calc.exe running in your session, it just tells that copy to come to the foreground (and open a window, if it doesn't have one), and then exits. So, by the time you try to kill it 2 seconds later, the process has already exited.
And if the actual running process is calculator.exe, that means calc.exe is just a launcher for the real program, so it always tells calculator.exe to come to the foreground, launching it if necessary, and then exits.
So, how can you kill the new calculator you started? Well, you can't, because you didn't start a new one. You can kill all calc.exe and/or calculator.exe processes (the easiest way to do this is with a third-party library like psutil—see the examples on filtering and then kill the process once you've found it), but that will kill any existing calculator process you had open before running your program, not just the new one you started. Since calc.exe makes it impossible to tell if you've started a new process or not, there's really no way around that.
This is one way to kill it, but it will close every open calculator.
It calls a no window command prompt and gives the command to close the Calculator.exe process.
import subprocess, os, time
p = subprocess.Popen('calc.exe')
print(p)
#Some actions
time.sleep(2)
CREATE_NO_WINDOW = 0x08000000
subprocess.call('taskkill /F /IM Calculator.exe', creationflags=CREATE_NO_WINDOW)

lldb python handle process crash or killed

I want to do something when a process is crash or killed in a python script.
However I can't find anyway to know when a process is stop by lldb.
I've tried to catch a SIGKILL signal but no use.
import lldb
import signal
def debug(sig, frame):
print "stop!\n"
def listen():
signal.signal(signal.SIGKILL, debug) # Register handler
I've find that we can use this to handle a breakpoint hit, but it can't deal with my situation.
def breakpoint_function_wrapper(frame, bp_loc, dict):
Anyone has some solutions?
There's a little sample program in the lldb python examples that shows how to handle process events using the lldb library:
http://llvm.org/svn/llvm-project/lldb/trunk/examples/python/process_events.py
That might help get you started.

Execute a shell script with ampersand from a python program

I want to submit my long running Python job using ampersand. I'm going to kick this process off from an interactive Python program by using a sub process call it.
How would I keep track of the submitted job programmatically in case I want to end the job from a menu option?
Example of interactive program:
Main Menu
1. Submit long running job &
2. End long running job
If you're using python's subprocess module, you don't really need to background it again with & do you? You can just keep your Popen object around to track the job, and it will run while the other python process continues.
If your "outer" python process is going to terminate what sort of track do you need to keep? Would pgrep/pkill be suitable? Alternately, you could have the long running job log its PID, often under /var/run somewhere, and use that to track if the process is still alive and/or signal it.
You could use Unix signals. Here we capture SIGUSR1 to tell the process to communicate some info to STDOUT.
#!/usr/bin/env python
import signal
import sys
def signal_handler(signal, frame):
print('Caught SIGUSR1!')
print("Current job status is " + get_job_status())
signal.signal(signal.SIGUSR1, signal_handler)
and then from the shell
kill <pid> --signal SIGUSR1

simplest way to make two python scripts talk to each other?

I have a python script running on a vps. Now i just want to change 1 variable in the running script using my desktop computer.
What is the simplest way to that for a beginner?
If I were a beginner, I would have my remote script periodically check the value of the variable in a text file. When I needed to update the variable, I would just ssh to my remote machine and update the text file.
Using a text file that is polled at a regular interval is an easy way to go.
A more efficient and probably easier way is to register a signal handler in your python process that would force the process to reload the value in the text file when demanded rather than continuously polling. On linux you can use the kill command in the terminal to send the a signal after updating the file. This is actually probably simpler than implementing continuous polling.
import signal
import sys
import os
print os.getpid()
def signal_handler(signal, frame):
# open text file and check for new value
print "value reset"
signal.signal(signal.SIGUSR1, signal_handler)
Then in Linux terminal to trigger the value to be reloaded you can do:
kill -SIGUSR1 pidprinted
If you wanted to get really fancy, you could register a signal handler to start pdb (python's debugger), inject the value into the running process, and continue, but I think doing the above is easiest.

Categories