“I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.
-
Upload
todd-hudson -
Category
Documents
-
view
220 -
download
0
Transcript of “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.
![Page 1: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/1.jpg)
“I drink my WSGI clear”A barebones introduction to Python Web Programming.
3/14/2011
![Page 2: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/2.jpg)
Who are we?
• Doug Morgan (@dougzor)
• Alex Conrad (@alexconrad)
• Whit Morriss (@whitmo)
![Page 3: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/3.jpg)
What is WSGI?
![Page 4: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/4.jpg)
WSGI
• Web Server Gateway Interface, pronounced ‘whizky’ (duh)
• PEP 333
• A standardized specification to define communication between a web server and your Python application.
![Page 5: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/5.jpg)
What do you need?
• An HTTP server with WSGI support aka a Host (we’ll get into these later).
• A Python file (your app).
![Page 6: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/6.jpg)
How does it work?
• 1) An HTTP request comes in to your server.• 2) The HTTP server calls your Python app with two
arguments: The environment and the “start response” function.
• 3) Your application returns a Response body which is sent back to the client.
• 4) …• 5) Profit!
![Page 7: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/7.jpg)
Example
def application(environ, start_response):# Let’s setup some data to send back to the clientbody = “WSGI is awesome and tastes delicious!”headers = [(“Content-Type”, “text/plain”),
(“Content-Length, str(len(body)))]
# Send response headers back to the clientstart_response(“200 OK”, headers)
# Send the body back to the client to complete the Response
return body
![Page 8: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/8.jpg)
Example
def application(environ, start_response):# Let’s setup some data to send back to the clientbody = “WSGI is awesome and tastes delicious!”headers = [(“Content-Type”, “text/plain”),
(“Content-Length, str(len(body)))]
# Send response headers back to the clientstart_response(“200 OK”, headers)
# Send the body back to the client to complete the Response
return body
![Page 9: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/9.jpg)
Example
def application(environ, start_response):# Let’s setup some data to send back to the clientbody = “WSGI is awesome and tastes delicious!”headers = [(“Content-Type”, “text/plain”),
(“Content-Length, str(len(body)))]
# Send response headers back to the clientstart_response(“200 OK”, headers)
# Send the body back to the client to complete the Response
return body
![Page 10: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/10.jpg)
Example
def application(environ, start_response):# Let’s setup some data to send back to the clientbody = “WSGI is awesome and tastes delicious!”headers = [(“Content-Type”, “text/plain”),
(“Content-Length, str(len(body)))]
# Send response headers back to the clientstart_response(“200 OK”, headers)
# Send the body back to the client to complete the Response
return body
![Page 11: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/11.jpg)
Arguments & Return Value
• environ: A dictionary (or Map if you’re from the Java land) of data about the incoming request, i.e. HTTP Headers, HTTP Host, etc.
{"HTTP_HOST": "surveymonkey.com", “HTTP_PATH”: “/surveys” "REQUEST_METHOD": "GET", …}
• start_response: A Python function supplied by the server that your app calls to send headers back to the client.
start_response("200 OK", headers)
• What your app returns will be the response body.return "<b>WSGI rules</b>"
![Page 12: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/12.jpg)
WSGI Hosts
• Python comes with a built-in one that you can use, wsgiref, batteries included.
• Other WSGI Hosts:Apache mod_wsgiGoogle App EnginePaste (Python)uWsgi (Nginx, Cherokee, Apache)
![Page 13: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/13.jpg)
WSGIRef Example
docs.python.org/library/wsgiref.html
run the following as “python server.py”
from wsgiref.simple_server import make_server
def application(environ, start_response):…. (from previous example)
# Server application on port 8000httpd = make_server(‘’, 8000, application)httpd.serve_forever() # run into process is killed
![Page 14: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/14.jpg)
That’s it!
![Page 15: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/15.jpg)
WSGI on the rocks
![Page 16: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/16.jpg)
WSGI on the Rocks
Libraries providing basic abstraction over raw WSGI providing request and response classes:
• Webob (apt-get install python-webob or easy_install webob)
• Werkzeug
![Page 17: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/17.jpg)
WebOb Example
from webob import Responsefrom webob.dec import wsgify
@wsgifydef hello_world_app(request):
response = Response(“Hello World”)return response
![Page 18: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/18.jpg)
WebOb Example
from webob import Responsefrom webob.dec import wsgify
@wsgifydef hello_world_app(request):
response = Response(“Hello World”)return response
![Page 19: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/19.jpg)
And now for somethingmore useful
![Page 20: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/20.jpg)
WebOb URL Routing
@wsgifydef main_app(request):
path = request.environ[‘PATH_INFO’]if path in app_paths:
return app_paths[path](request)return response.status = 404
def foo_app(request):return Response(“Got into /foo”)
app_paths = {‘/foo’: foo_app, ‘/bar’: bar_app, …}
![Page 21: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/21.jpg)
WebOb URL Routing
@wsgifydef main_app(request):
path = request.environ[‘PATH_INFO’]if path in app_paths:
return app_paths[path](request)return response.status = 404
def foo_app(request):return Response(“Got into /foo”)
app_paths = {‘/foo’: foo_app, ‘/bar’: bar_app, …}
![Page 22: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/22.jpg)
WebOb URL Routing
@wsgifydef main_app(request):
path = request.environ[‘PATH_INFO’]if path in app_paths:
return app_paths[path](request)return response.status = 404
def foo_app(request):return Response(“Got into /foo”)
app_paths = {‘/foo’: foo_app, ‘/bar’: bar_app, …}
![Page 23: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/23.jpg)
WebOb URL Routing
@wsgifydef main_app(request):
path = request.environ[‘PATH_INFO’] # ‘/foo’if path in app_paths:
return app_paths[path](request)return response.status = 404
def foo_app(request):return Response(“Got into /foo”)
app_paths = {‘/foo’: foo_app, ‘/bar’: bar_app, …}
![Page 24: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/24.jpg)
WebOb URL Routing
@wsgifydef main_app(request):
path = request.environ[‘PATH_INFO’]if path in app_paths:
return app_paths[path](request)return response.status = 404
def foo_app(request):return Response(“Got into /foo”)
app_paths = {‘/foo’: foo_app, ‘/bar’: bar_app, …}
![Page 25: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/25.jpg)
WebOb URL Routing
@wsgifydef main_app(request):
path = request.environ[‘PATH_INFO’]if path in app_paths:
return app_paths[path](request)return response.status = 404
def foo_app(request):return Response(“Got into /foo”)
app_paths = {‘/foo’: foo_app, ‘/bar’: bar_app, …}
![Page 26: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/26.jpg)
Middleware
• What we just built, a routing interface, is a ‘middleware’.
• A middleware is a WSGI application that sits between the web server the your main application which can do pre and post processing on the request and response.
• Takes as input, the request object, and the next application to call.
![Page 27: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/27.jpg)
Uppercase Middleware Example
def app(req): response = Response("The quick brown fox jumped over buzz.") return response
@wsgify.middlewaredef upper_middleware(request, app):
response = app(request)response.body = response.body.upper()
return response
wrapper_app = upper_middleware(app)httpd = make_server("", 8000, wrapper_app)
![Page 28: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/28.jpg)
Uppercase Middleware Example
def app(req): response = Response("The quick brown fox jumped over buzz.") return response
@wsgify.middlewaredef upper_middleware(request, app):
response = app(request)response.body = response.body.upper()
return response
wrapper_app = upper_middleware(app)httpd = make_server("", 8000, wrapper_app)
![Page 29: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/29.jpg)
Uppercase Middleware Example
def app(req): response = Response("The quick brown fox jumped over buzz.") return response
@wsgify.middlewaredef upper_middleware(request, app):
response = app(request)response.body = response.body.upper()
return response
wrapper_app = upper_middleware(app)httpd = make_server("", 8000, wrapper_app)
![Page 30: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/30.jpg)
Gzip Middleware Example
def gzip_middleware(request, app):# Don’t want to do any pre-processing so just call the
appresponse = app(request)
# Compress the body and set headerresponse.body = gzip(request.body)response.headers[‘Content-Encoding’] = ‘gzip’
return response
![Page 31: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/31.jpg)
Middleware Considerations
• Two things:• Middlewares are not aware of anything before or after them in
the ‘pipeline.’• Middlewares should be reusable.
• The middleware you write should act more like a filter as opposed to having a lot of business logic. Rule of thumb: if the code is specific to your application (not reusable), it should probably be a library and not a middleware.
![Page 32: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/32.jpg)
That was so easy...
• A cavema... Err anyone can do it!
• There are dozens of web frameworks that are available (most are open-source) for your use which do a lot of the leg work for you.Examples:• Pylons/Pyramid (What we use at SurveyMonkey)• Django• TurboGears• Repoze.bfg• Bottle• Flask
![Page 33: “I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011.](https://reader035.fdocuments.us/reader035/viewer/2022062516/56649dc55503460f94ab894b/html5/thumbnails/33.jpg)
Questions?