Building Web Applications -WSGI (Web Server Gateway Interface)
WSGI ("wheez-gee") is a Python specification that describes how web server communicates with web applications, and how web applications can be chained together to process one request.
Hello World WSGI Application, access it via http://localhost:8000/
Hello World WSGI Application, access it via http://localhost:8000/
from wsgiref.simple_server import make_server def hello_world_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain; charset=utf-8')] start_response(status, headers) return[b"Hello World"] httpd = make_server('', 8000, hello_world_app) print("Serving on port 8000...") httpd.serve_forever()
environ parameter to your handler function is the dictionary of variables from the server, start_response variable is the interface for sending HTTP status and response headers.
Let's modify the server to serve HTML content:
Let's modify the server to serve HTML content:
from wsgiref.simple_server import make_server def hello_world_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'html; charset=utf-8')] start_response(status, headers) message = "<h1>Welcome to the Zoo</h1>" return[bytes(message,'utf-8')] httpd = make_server('', 8000, hello_world_app) print("Serving on port 8000...") httpd.serve_forever()
Building the form to accept user input:
from wsgiref.simple_server import make_server def hello_world_app(environ, start_response): message="" status = '200 OK' headers = [('Content-type', 'html; charset=utf-8')] start_response(status, headers) message += "<h1>Welcome to the Zoo</h1>" message += "<form><br>Animal:<input type=text name='animal'>" message += "<br><br>Count:<input type=text name='count'>" message += "<br><br><input type='submit' name='Submit' ></form>" return[bytes(message,'utf-8')] httpd = make_server('', 8000, hello_world_app) print("Serving on port 8000...") httpd.serve_forever()
Welcome to the Zoo
Please view the code on github https://github.com/gnurmatova/Python/blob/master/lecture9/webapp/zoo2.py
As of right now, the form doesn't do anything.
Submitting the form directs the URL to itself and passes the values entered in the form as GET parameters in the URL:
http://localhost:8000/?animal=Hedgehog&count=4&Submit=Submit
Let's take a look at the environ variable that gets passed to our hello_world_app, I added the print("ENVIRON:", environ) statement to see what we get as part of it (all not related data is removed)
127.0.0.1 - - [02/Nov/2014 09:15:00] "GET / HTTP/1.1" 200 170
ENVIRON: {'HTTP_REFERER': 'http://localhost:8000/', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'HTTP_HOST': 'localhost:8000', 'QUERY_STRING': 'animal=Hedgehog&count=4&Submit=Submit', 'REQUEST_METHOD': 'GET', ...}
add method='POST' in your form tag, and view the environ variable again:
Now we have:
'REQUEST_METHOD': 'POST'
and the QUERY_STRING is gone, which is ok, it's applicable to GET method only, our data now resides in the
'wsgi.input' object
Let's modify our application such that it displays the data it has received back with the confirmation of submission,
code is here: https://github.com/gnurmatova/Python/blob/master/lecture9/webapp/zoo3.py
As of right now, the form doesn't do anything.
Submitting the form directs the URL to itself and passes the values entered in the form as GET parameters in the URL:
http://localhost:8000/?animal=Hedgehog&count=4&Submit=Submit
Let's take a look at the environ variable that gets passed to our hello_world_app, I added the print("ENVIRON:", environ) statement to see what we get as part of it (all not related data is removed)
127.0.0.1 - - [02/Nov/2014 09:15:00] "GET / HTTP/1.1" 200 170
ENVIRON: {'HTTP_REFERER': 'http://localhost:8000/', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'HTTP_HOST': 'localhost:8000', 'QUERY_STRING': 'animal=Hedgehog&count=4&Submit=Submit', 'REQUEST_METHOD': 'GET', ...}
add method='POST' in your form tag, and view the environ variable again:
Now we have:
'REQUEST_METHOD': 'POST'
and the QUERY_STRING is gone, which is ok, it's applicable to GET method only, our data now resides in the
'wsgi.input' object
Let's modify our application such that it displays the data it has received back with the confirmation of submission,
code is here: https://github.com/gnurmatova/Python/blob/master/lecture9/webapp/zoo3.py
from wsgiref.simple_server import make_server def get_form_vals(post_str): form_vals = {item.split("=")[0]: item.split("=")[1] for item in post_str.decode().split("&")} return form_vals def hello_world_app(environ, start_response): #print("ENVIRON:", environ) message="" status = '200 OK' headers = [('Content-type', 'html; charset=utf-8')] start_response(status, headers) if(environ['REQUEST_METHOD'] == 'POST'): message += "<br>Your data has been recorded:" request_body_size = int(environ['CONTENT_LENGTH']) request_body = environ['wsgi.input'].read(request_body_size) form_vals = get_form_vals(request_body) for item in form_vals.keys(): message += "<br/>"+item + " = " + form_vals[item] message += "<h1>Welcome to the Zoo</h1>" message += "<form method='POST'><br>Animal:<input type=text name='animal'>" message += "<br><br>Count:<input type=text name='count'>" message += "<br><br><input type='submit' name='Submit' ></form>" return[bytes(message,'utf-8')] httpd = make_server('', 8000, hello_world_app) print("Serving on port 8000...") httpd.serve_forever()
Your data has been recorded:
animal = Hedgehog
count = 4
Submit = Submit
Welcome to the Zoo
Processing the GET parameters is simpler: https://github.com/gnurmatova/Python/blob/master/lecture9/webapp/zoo2a.py
from wsgiref.simple_server import make_server import re def hello_world_app(environ, start_response): #print("ENVIRON:", environ) message="" status = '200 OK' headers = [('Content-type', 'html; charset=utf-8')] start_response(status, headers) if(len(environ['QUERY_STRING'])>1): message += "<br> Your data has been recieved:" for param in environ['QUERY_STRING'].split("&"): message += "<br>"+param message += "<h1>Welcome to the Zoo</h1>" message += "<form><br>Animal:<input type=text name='animal'>" message += "<br><br>Count:<input type=text name='count'>" message += "<br><br><input type='submit' name='Submit' ></form>" return[bytes(message,'utf-8')] httpd = make_server('', 8000, hello_world_app) print("Serving on port 8000...") httpd.serve_forever()