Search code examples
pythonhtmlpython-3.xserver

How could I extract the user's input from the webpage and send it back to a python script?


I'm writing a program to generate a webpage capable of accepting user input. I need to take whatever the user enters, and then print out a statement on the webpage to the effect of "Hello firstname!". Only I can't work out how to get the data entered out of the webpage and communicate it back to python.

I've thus far tried to use the post method though I think something was inconfigured incorrectly as it generated the following error on the website. "Error Code 501, Unsupported Method (POST)"

Below is the code I used on the server side, a very simply little python script. This whole ordeal is part of my efforts to learn python as such if the solution could be explained in terms of python i'd be very grateful.

However if there's some way to print the user input inside of html i'd not be opposed to that as it'll be passed back to the webpage with python regardless.

# Python 3 server example
`from  http.server import BaseHTTPRequestHandler, HTTPServer #clarify from command Hypothesis: Code doesn't require the entire http module so it's only importing the BaseHttp and HTTPServer classes, classes can be imported without the modle they're from?
import time #Why is time imported if it's not used? Hypothesis: the send response method on line 10 states among other things to send the current date. Thus time is needed to determine current date?

hostName = "localhost"
serverPort = 8080

class MyServer(BaseHTTPRequestHandler): #What is __init__ not used in this class? Still need to clarify "self" value.
    def do_GET(self): 
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
        self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
        self.wfile.write(bytes("<body>", "utf-8"))
        self.wfile.write(bytes("<p>Hello world! This is a webpage!</p>", "utf-8"))
        self.wfile.write(bytes("<p> And hello to you! Please enter your name below!</p>", "utf-8"))
        self.wfile.write(bytes("""<form action="webpage.py" method="post">
                                   <label for="name">Please enter your name:</label><br>
                                   <input type="text" id="name" name="name"><br>
                                   <input type = "submit" value = "Click me!">
                                </form>  
                              """, "utf-8" )) #if this throws an error try inserting "utf-8" at the very end as a seperate string
        self.wfile.write(bytes())
        self.wfile.write(bytes("</body></html>", "utf-8"))

if __name__ == "__main__":   #Identify use of __name__ dunder     
    webServer = HTTPServer((hostName, serverPort), MyServer)
    print("Server started http://%s:%s" % (hostName, serverPort))

    try:
        webServer.serve_forever()
    except KeyboardInterrupt: #Why does this exception exist if no code is present. Hypothesis: Given this is demonstration code it's just to keep it from crashing if you input something in the console?
        pass

    webServer.server_close()
    print("Server stopped.")

    #TODO: Insert a form that will ask for a user's name, insert a button. When the button is pushed raise a flag e.g button_clicked, use an if statement to print the entered nanme when this flag is raised.`


Solution

  • There might be couple of issues in your code that is causing the 501 error.

    Firstly check, in your HTML form, if the action attribute is set to "filename.py", which is likely causing the unsupported method error. The action attribute should point to the endpoint where you want to handle the form submission. In your case, it's the same Python script, so you can leave it empty or set it to "/".

    Secondly, you need to implement the do_POST method in your MyServer class to handle the POST request. Currently, you only have the do_GET method. Add the following method to your class:
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length).decode('utf-8')
        # Parse the post data to get the user input
        user_input = post_data.split('=')[1]
    
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
    
        self.wfile.write(bytes("html>head>title>https://pythonbasics.org</title>/head>", "utf-8"))
        self.wfile.write(bytes("<body>", "utf-8"))
        self.wfile.write(bytes(f"<p>Hello {user_input}!</p>", "utf-8"))
        self.wfile.write(bytes("</body></html>", "utf-8"))
    

    This code reads the content of the POST request, extracts the user input, and then includes it in the response.