✿ code toolkit ✿ python ✿

spring 2022



Week 11 Async Work

  1. Review the class notes for this week.

  2. Create a simple, HTML mad lib generator.

    Make a new folder, call it mad-lib-exercise. Within that, create a subfolder called cgi-bin. Open Atom, drag your mad-lib-exercise folder into Atom, close all other tabs and create a new file insde your cgi-bin folder as server.py.

    Go to your terminal and cd to your mab-lib-exercise folder. (If you ended up inside cgi-bin, you can type cd .. to change to the parent directory.) Make sure that your server.py file is executable. You can check this by typing the following (remember, don't type the dollar signs):

    $ ls -l cgi-bin
    

    It probably is not executable by default, so to make sure that it is, type the following command:

    $ chmod a+x cgi-bin/server.py
    

    (This command is short for "change mode" and it allows you to change read, write, and execute permissions on files.) You can type ls -l cgi-bin again to see what this changed.

    The first line of this file should be the executable path to Python on your system. Type:

    $ which python
    /usr/local/bin/python
    

    For me, that outputs /usr/local/bin/python, but for you it may be different. Whatever it says, copy that output, and paste it in as the first line of server.py, preceded by a pound sign (#) and an exclamation point, like this:

    #!/usr/local/bin/python
    

    This strange symbolic incantation is actually very common in command line and Unix-like contexts. It is usually referred to as "hash-bang" or "sha-bang" notation. When you put this at the top of an executable file, it usually tells the operating system what program to use to interpret the rest of the contents of the file when someone tries to run it.

    The output of this program is going to be returned as an HTTP response, so the first thing you have to do is follow the rules of HTTP. In this case, that means that the first thing you have to do is print the following: Content-Type: text/html including the blank line.

    So put the following commands in server.py:

    print("Content-Type: text/html")
    print("")
    

    After that, try adding some other Python commands. For example, try adding some other print() statements, which will generate text output that will be returned to the user.

    Next, inside your mad-lib-exercise folder (not cgi-bin), create a new HTML file and add the following code to it:

    
    <html>
    <head>
    
    </head>
    
    <body>
    <form action="cgi-bin/server.py">
    <input type="text" name="first-name"><br/>
    <input type="text" name="species"><br/>
    <input type="submit" value="Submit">
    </form>
    </body>
    </html>
    
    

    Save this as mad-lib.html or you can name it anything you would like as long as it ends with .html. Add some additional <input> fields here. Because of the way HTML works, when the user types text into these fields and clicks 'Submit', their browser will send an HTTP request to the location specified by the action attribute of this form. So in this case, that is cgi-bin/server.py — the IP address is implicit, and if not specified defaults to the address of the current page.

    You can access the values of those form variables in your code by using the Python cgi library. Add the following line to server.py directly after the first line:

    import cgi
    form = cgi.FieldStorage()
    


    **** if you are using python 2.7 (instead of python3) you should paste the following into your server file

    import cgi, cgitb
    cgitb.enable()
    
    form = cgi.FieldStorage()
    


    Now, form is a dictionary that gives you access to all the values that the user submitted. You can access these values by using this dictionary in the following way:

    form["first-name"].value
    

    Remember that you can join text together in Python using +, the string concatenation operator. So if you wanted to make a fill-in-the-blank sentence, you could do so like this:

    print( "Hello, " + form["first-name"].value + ", how are you today?" )
    

    Of course, replace "first-name" with whatever <input>s you have added, specifying them based on what you have put in the name attribute for each <input> field in your HTML.

    You can test this by running a CGI webserver with the following command:

    $ python3 -m http.server --cgi 8000
    

    *** if you are using python 2.7 (instead of python3) you should run this command in your terminal instead:

    $ python -m CGIHTTPServer

    and accessing 127.0.0.1:8000/mad-lib.html in your browser. Try typing some text in the form and clicking 'Submit'.

    Now you should be able to modify server.py to create a kind of "mad lib" that takes user input and uses it to fill in text to return to the user.

    Some improvements and challenges

    Add labels to your HTML form fields simply by adding text to your HTML file, like this:

    Name: <input type="text" name="first-name"><br/>
    Species: <input type="text" name="species"><br/>
    

    Try treating some form fields as numerical values and using them with some of the control structures that we have learned this semester, like if statements and while loops. If you want to treat an HTTP request value in the form dictionary as a number, you need to wrap it in the int() command like this:

    int(form["count"].value)
    

    That is assuming that you have the following field in your HTML form:

    Enter a number: <input type="text" name="count"><br/>
    

    Now you could do something like this:

    print("I am ")
    i = 0
    while i < int(form["count"].value):
        print("very ")
        i = i + 1
    print("happy that you are learning to code.")
    

    Have fun! Next week I will show you how to upload this to a live web server so that you can share your work with others.