Initiate a Python Script via a Website (Click of a Button)
Question: I have a small web panel on which I would like to control a python script that
continuously collects data from a sensor (while loop). I would like to be able
to start and stop this script by simply clicking a button. I know of a method
of enabling the script to stop, but starting it seems to be a bit of a hassle.

I have tried several solutions that included jQuery.ajax requests, but that
sadly did not start the script. What should be noted is that I only want to
start the script, I do not want any output/return values from it, so the
script needs to run asynchronously in the background (which is what Ajax is
for after all).

Here are a few solutions that could potentially work: 1) Install Flask. The
thing is I actually really want to avoid that and instead find a direct way to
do this. After all, I just want to make a request to the script so it gets
executed. 2) Execute it by installing PHP on the server and use exec(). But
this again goes back to the point that I actually prefer to use Python
directly or do it through a jQuery/Ajax call that actually works.

Any suggestions on how to set this up? If there is really no other way, I
suppose that installing PHP and using it to execute the files is the only way.
If that is true, is it actually possible to have both Python scripts run
asynchronously through the PHP exec() call?


Answer: just wanted to answer my own question as, after extensive research, I found a
solution to my initial problem. Here is a description:

**The Button:** Here we simply have the onclick event for our Javascript
function.

    
    
    <div class="col-md-4"><button id="script_run" type="button" class="btn btn-primary" onclick="runscript()">Test</button></div>
    

**The Javascript Code:** On the Javascript side, I have created 2 functions.
One that is there to update the color of the button (so the user will know if
the script is currently running or not) and one script which actually makes an
HTTP request via Ajax to our Python script. What you will notice here is that
for the button, we are checking whether a local file (RUNNING.txt) exists.
This is because RUNNING.txt is a temporary file that is created when our
Python script is executed, here we store the ID's of our simultaneously
running processes so that we can later terminate them.

    
    
    function changebutton() {
        $.ajax({
            url: "RUNNING.txt",
            error: function() {
                document.getElementById('script_run').className = "btn btn-danger";
                document.getElementById('script_run').innerHTML = "OFFLINE";
            },
            success: function() {
                document.getElementById('script_run').className = "btn btn-success";
                document.getElementById('script_run').innerHTML = "ONLINE";
            }
        });
    }
    changebutton();
    
    function runscript() {
        if (document.getElementById('script_run').innerHTML == "ONLINE") {
            $.ajax({
                type: "POST",
                url: 'main.py',
                data: {offline: "True"}
            })
            .done(setTimeout(function(){
                changebutton();
            }, 50000));
        }
        else {
            $.ajax({
                url: 'main.py'
            })
            .done(setTimeout(function(){
                changebutton();
            }, 50000));
        }
    };
    

**The Python Code:** What we are doing here is that when the script is called,
we are creating the file RUNNING.txt. Then we actually get to the core part:
which is the asynchronous processing of our functions. This is achieved
through the _multiprocessing_ library. After that we save the process ID's in
RUNNING.txt and wait for an event. If the script is called again (this leads
us to the else statement), we execute the abort() function, which simply uses
the os.kill() function to kill our processes. That's it :)

    
    
    import multiprocessing
    import cgi
    import os
    import os.path
    import signal
    
    import YOURFUNCTION1
    import YOURFUNCTION2
    
    def abort():
        f = open('RUNNING.txt', 'r')
        process = f.readline()
        process = filter(None, process.split(","))
    
        for p in process:
            os.kill(int(p), signal.SIGQUIT)
    
        f.close()
        os.remove('RUNNING.txt')
    
    def main():
        if not os.path.isfile("RUNNING.txt"):
            f = open('RUNNING.txt', 'w+')
    
            for func in [YOURFUNCTION1, YOURFUNCTION2]:
                processes.append(multiprocessing.Process(target=func))
                processes[-1].start()
    
            for p in processes:
                f.write(str(p.pid))
                f.write(",")
            f.close()
    
            choice = raw_input("Press X to abort all processes: ")
            if choice == "X":
                abort()
        else:
            print "Processes already operational."
            if form.getvalue('offline') == "True":
                abort()
    

Hope that I could help someone with this :)

