2

I don't have much knowledge with web development so I want to make this very basic. I have a python project with a very simple website that has two text fields and a "submit" button. When the button is pressed I want it to run the python program with the user's arguments. I have a single page index.html with the website and below to launch the python web server:

import http.server
import socketserver

PORT = 8080
Handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()

What is the easiest way to run python scripts when the "Submit" button is clicked?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214

2 Answers2

3

What you have to understand is that there is two part in your code : the server and the client. So here you want to do something on the server side, when the client does something. For that the client have to do a request to the server and the server process it and respond.

It turns out that SimpleHTTPRequestHandler is not really made for this. But you can still do it^^

Client side

Here you show (using html) to the client, a button that will make a request if he click it.

<body>
   <form action="/test.html">
      <input type="hidden" name="isButtonPressed" value="true">
      <input type="submit">
   </form>
 </body>

Server side

import http.server
import socketserver

#here you create a new handler, you had a new way to handle get request
class Handler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
       #this code execute when a GET request happen, then you have to check if the request happenned because the user pressed the button
        if self.path.find("isButtonPressed=true") != -1:
            print("Button clicked")
            #do whatever you want
        return super().do_GET()


PORT = 8080
myHandler = Handler


with socketserver.TCPServer(("", PORT), myHandler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()
1

Use a CGIHTTPRequestHandler instead of the SimpleHTTPRequestHandler.

This defaults to executing scripts in the folder cgi-bin, so create that folder and put your Python scripts there. Then you can do the following:

server.py

import http.server
import socketserver

PORT = 8080
handler = http.server.CGIHTTPRequestHandler

with http.server.HTTPServer(("", PORT), handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()

index.html

<!DOCTYPE html>

<h1>Hello!</h1>

<form action="cgi-bin/foo" method="post">
    <button type="submit">Submit!</button>
</form>

cgi-bin/foo

#!/usr/bin/env python3

response = '''HTTP/1.0 200 OK
Content-Type: text/html

<!DOCTYPE html>
<h1>hello from foo!</h1>
'''
print(response.replace('\n', '\r\n'))

However, this is both tedious and brittle. The documentation warns explicitly against production use. For proper web applications use a web application framework such as Flask.

For reference, here’s how the same thing would be written using Flask:

import flask
from flask import Flask


app = Flask(__name__)


@app.route('/')
def index():
    return f'''
    <h1>Hello</h1>
    <form action="{flask.url_for('foo')}" method="post">
        <button type="submit">Submit</button>
    </form>
    '''


@app.route('/foo', methods=['POST'])
def foo():
    return '''
    <h1>Hello from foo!</h1>
    '''
export FLASK_APP=server.py
flask run
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214