Dynamic Web Pages ================= Instead of placing the form in an HTML file and the script in a ``.py`` file, we can have the Python scripts printing the forms, recursively as needed. Forms in Python Scripts ----------------------- To run a simple CGI server, a simple Python script suffices. The documentation string of ``myserver.py`` is :: """ Launch this code in the directory where the CGI script is that you want to run. Point the browser to localhost:8000 (or whatever the value of PORTNUMBER is), followed by / and the name of the script. """ To run the CGI scripts in this lecture, one does not really need Apache. The portnumber defined in the script must be open. Tthe script ``myserver.py`` is below. :: PORTNUMBER = 8000 import http.server import cgitb; cgitb.enable() # CGI error report server = http.server.HTTPServer handler = http.server.CGIHTTPRequestHandler server_address = ("", PORTNUMBER) handler.cgi_directories = ["/"] httpd = server(server_address, handler) try: print('welcome to our cgi server') print('press ctrl c to shut down the server') httpd.serve_forever() except: print('ctrl c pressed, shutting down server') httpd.socket.close() Serving Python scripts suffices, as we can have scripts print HTML code. What we did before: 1. The form element in an HTML page triggers an action, for example: submit user name and password. 2. The action triggered by the submit button is defined by a Python script. The advantage is that the separate HTML separates the layout from the actions. The main disadvantage is the possibility of error by a mismatch between the names of the values in the form and the names used the retrieve the values in the script. Consider for example a form which prompts the user for a word, illustrated in :numref:`figuseforms1`. .. _figuseforms1: .. figure:: ./figuseforms1.png :align: center Asking for a word. The confirmation of the submitted word is shown in :numref:`figuseforms2`. .. _figuseforms2: .. figure:: ./figuseforms2.png :align: center Confirming the word. The script ``use_forms.py`` starts with the printing of the header for the HTML page. :: #!/usr/bin/python import cgi def print_header(title): """ writes title and header of page """ print("""Content-type: text/html
Your word is %s
""" % FORM["word"].value) print("\n") For our next example, we introduce default values for input elements of type text. When the form is then printed, a default value appears in the text element, as shown in :numref:`figdefaults`. The default value in this example is ``2``. .. _figdefaults: .. figure:: ./figdefaults.png :align: center A form with a default value in a text element. The code snippet which prints the form with the default value follows below. :: print """""" A Web Interface for a Determinant --------------------------------- In our next example we make our interactive forms dynamic, in the sense that the content of the form is determined when the application is running. In :numref:`figwebdet` we see the form to ask for a matrix. .. _figwebdet: .. figure:: ./figwebdet.png :align: center Asking for a matrix. The computation of the determinant of the matrix entered in the form is illustrated in :numref:`figcomputedet`. .. _figcomputedet: .. figure:: ./figcomputedet.png :align: center Computing the determinant. The script is a sequence of two forms: 1. We ask for the dimension of the matrix. The dimension is then used to generate a table of input elements to give the entries of the matrix. 2. We ask for the entries of the matrix. The second form is processed by the same script. The action of this form brings up a new page with the matrix and the determinant. The dimension is passed from one form to the other *through an input element*. The main function of ``web_det.py`` is below. :: def main(): """ web interface to compute a determinant """ print_header("compute determinant") ask_dimension() form = cgi.FieldStorage() if "dim" in form: dim = int(form["dim"].value) ask_matrix(dim) print("