Download presentation
Presentation is loading. Please wait.
Published byTodd Hudson Modified over 9 years ago
1
“I drink my WSGI clear” A barebones introduction to Python Web Programming. 3/14/2011
2
Who are we? Doug Morgan (@dougzor) Alex Conrad (@alexconrad) Whit Morriss (@whitmo)
3
What is WSGI?
4
WSGI Web Server Gateway Interface, pronounced ‘whizky’ (duh) PEP 333 A standardized specification to define communication between a web server and your Python application.
5
What do you need? An HTTP server with WSGI support aka a Host (we’ll get into these later). A Python file (your app).
6
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!
7
Example def application(environ, start_response): # Let’s setup some data to send back to the client body = “WSGI is awesome and tastes delicious!” headers = [(“Content-Type”, “text/plain”), (“Content-Length, str(len(body)))] # Send response headers back to the client start_response(“200 OK”, headers) # Send the body back to the client to complete the Response return body
8
Example def application(environ, start_response): # Let’s setup some data to send back to the client body = “WSGI is awesome and tastes delicious!” headers = [(“Content-Type”, “text/plain”), (“Content-Length, str(len(body)))] # Send response headers back to the client start_response(“200 OK”, headers) # Send the body back to the client to complete the Response return body
9
Example def application(environ, start_response): # Let’s setup some data to send back to the client body = “WSGI is awesome and tastes delicious!” headers = [(“Content-Type”, “text/plain”), (“Content-Length, str(len(body)))] # Send response headers back to the client start_response(“200 OK”, headers) # Send the body back to the client to complete the Response return body
10
Example def application(environ, start_response): # Let’s setup some data to send back to the client body = “WSGI is awesome and tastes delicious!” headers = [(“Content-Type”, “text/plain”), (“Content-Length, str(len(body)))] # Send response headers back to the client start_response(“200 OK”, headers) # Send the body back to the client to complete the Response return body
11
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 " WSGI rules "
12
WSGI Hosts Python comes with a built-in one that you can use, wsgiref, batteries included. Other WSGI Hosts: Apache mod_wsgi Google App Engine Paste (Python) uWsgi (Nginx, Cherokee, Apache)
13
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 8000 httpd = make_server(‘’, 8000, application) httpd.serve_forever() # run into process is killed
14
That’s it!
15
WSGI on the rocks
16
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
17
WebOb Example from webob import Response from webob.dec import wsgify @wsgify def hello_world_app(request): response = Response(“Hello World”) return response
18
WebOb Example from webob import Response from webob.dec import wsgify @wsgify def hello_world_app(request): response = Response(“Hello World”) return response
19
And now for something more useful
20
WebOb URL Routing @wsgify def 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, …}
21
WebOb URL Routing @wsgify def 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, …}
22
WebOb URL Routing @wsgify def 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, …}
23
WebOb URL Routing @wsgify def 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, …}
24
WebOb URL Routing @wsgify def 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, …}
25
WebOb URL Routing @wsgify def 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, …}
26
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.
27
Uppercase Middleware Example def app(req): response = Response("The quick brown fox jumped over buzz.") return response @wsgify.middleware def 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)
28
Uppercase Middleware Example def app(req): response = Response("The quick brown fox jumped over buzz.") return response @wsgify.middleware def 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)
29
Uppercase Middleware Example def app(req): response = Response("The quick brown fox jumped over buzz.") return response @wsgify.middleware def 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)
30
Gzip Middleware Example def gzip_middleware(request, app): # Don’t want to do any pre-processing so just call the app response = app(request) # Compress the body and set header response.body = gzip(request.body) response.headers[‘Content-Encoding’] = ‘gzip’ return response
31
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.
32
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
33
Questions?
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.