why WSGI

What's WSGI?

Here's an explanation, from wsgi.org:

WSGI is the Web Server Gateway Interface. It is a specification for web servers and application servers to communicate with web applications[...]

Note the following:

  • It's a specification,
  • It specifies how a web server should tell a web application that it has a visitor, and
  • It specifies how a web application should respond to the visitor.

Why WSGI?

  • It's an official Python standard,
  • Many Python components for web application development are standardizing on it,
  • It allows you to easily mix and match multiple HTTP-related components, and
  • It's simple.

Hello World

Let's start with Hello World, WSGI-style, in Python's interactive interpreter:

>>> def hello_world(environ, start_response):
...     """A WSGI application that greets the world"""
...     start_response('200 OK', [('Content-Type', 'text/plain')])
...     return ['Hello World!']
...
>>> from wsgiref.simple_server import make_server
>>> make_server('localhost', 8000, hello_world).serve_forever()

Now open up http://localhost:8000/foo/bar/ in your browser, and there's your WSGI application.

In Detail

Let's break it down:

>>> def hello_world(environ, start_response):
...     """A WSGI application that greets the world"""

An application callable is declared to handle HTTP requests.

...     start_response('200 OK', [('Content-Type', 'text/plain')])

When it gets a request, it's going to respond with the HTTP status code 200 OKand an HTTP response header that explains the content's type.

...     return ['Hello World!']
...

After queuing the HTTP headers, it's going to return an iterable object that yields one or more strings, which will compose the message body.

>>> from wsgiref.simple_server import make_server

Now that there's an application callable, a simple application server for it to run on is imported.

>>> make_server('localhost', 8000, hello_world).serve_forever()

Finally, the WSGI/HTTP server is run on port 8000 on localhost with thehello_world callable handling all requests. It'll do this forever, or until you hitCTRL+C to stop the infinite loop.

When someone browses to any page on your server, they'll see Hello World!

WSGI in Practice

Utilizing WSGI in practice is simple. Because WSGI components all adhere to the same interface, we can easily create a stack of components to provide the application's functionality. Components can easily be added and removed from the stack.

In this example you'll do the following:

These are all WSGI components.

Prerequisites

First, get Easy Install, which will allow you to easily install Python applications and libraries. It handles finding dependencies, downloading files, and installing them into your environment.

If you're developing on Linux or BSD, and not Microsoft Windows or Mac OS X, add the following to /usr/lib/python2.5/distutils/distutils.cfg to make distutils and Easy Install install things into /usr/local:

[install]
prefix = /usr/local

[easy_install]
site_dirs = /usr/local/lib/python$py_version_short/site-packages

Download and run the Easy Install installer:

$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ sudo python2.5 ez_setup.py

And get Yaro, Selector, Memento, and Static, which will be used in the example:

$ sudo easy_install yaro selector memento static

The Package

Now you'll need to make a folder for developing the application in and a Python package to hold the code:

$ mkdir wsgitest
$ cd wsgitest
$ mkdir wsgitest

Add a doc string in wsgitest/__init__.py that explains what the application is:

"""A WSGI application demonstration"""

The Controller

To respond to requests, you'll need some controllers.

To cut out some of the boilerplate, use Yaro with a controller inwsgitest/controllers.py:

"""CRUD controllers"""

from yaro import Yaro

__all__ = ['index']

@Yaro
def index(req):
    """The application index"""

    return 'Welcome to the index!'

With Yaro wrapping index, it will handle calling start_response and returning an iterable. index only needs to return a string.

The URIs

To map controllers to URIs, use Selector to create the mappings, inwsgitest/uris.py:

"""URI-to-controller mappings"""

from selector import Selector

from wsgitest.controllers import *

__all__ = ['uris']

uris = Selector()
uris.add('/', GET=index)

Now uris is the application callable. It dispatches HTTP requests to the controllers.

The Server

Finally, make a script to run the application.

In run.py, add a function to start the HTTP server and wrap the application function with Memento so you can edit the application while it runs:

#!/usr/bin/env python2.5
"""A console script for running wsgitest"""

def run(host, port):
    """Runs the application on a built-in web server"""

    from wsgiref.simple_server import make_server
    from memento import Assassin
    app = Assassin(
        'wsgitest.uris:uris',
        ['wsgitest'],
    )
    make_server(host, port, app).serve_forever()

if __name__ == '__main__':
    run('0.0.0.0', 8000)

Now set the script executable and start it up:

$ python2.5 run.py

You should see the index at http://localhost:8000/. While it's running, try changing the string returned by controllers.index and refresh the page. Your change is reflected automatically and you didn't need to restart the application.

Memento accomplishes this by forcing Python to re-import all modules on each HTTP request. This is obviously a bad idea in a production setting but it's great for development.

In Summary

WSGI greatly simplifies writing web applications at the low level—with the application callable interface—and simplifies modularizing functionality to abstract away common requirements and boilerplate code—by allowing middleware callables. This article shows you how to start from the bottom up, without a web framework, to build a basic application. Where you go from here is a matter of what tools you choose to use in your application!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值