Differences between revisions 3 and 19 (spanning 16 versions)
Revision 3 as of 2006-08-22 06:03:52
Size: 6161
Editor: HuangYi
Comment:
Revision 19 as of 2006-11-16 11:48:56
Size: 2550
Editor: ohyha
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
## page was renamed from zhSoftDespTemplate
##language:zh

[[TableOfContents]]

== 简介 ==

wsgi 是一个 web 组件的接口规范.
wsgi将 web 组件分为三类: web服务器,web中间件,web应用程序.
其目标是提高web组件的可重用性.
wsgi 的设计目标是适合尽可能广泛的web应用, 较原始.

典型场景:

{{{#!python
  app = A_WSGI_Application(...)
  app = Middleware1(app, ...)
  app = Middleware2(app, ...)
  ...
  server(app).serve_forever()
}}}

== 相关页面 ==

 * [http://www.python.org/peps/pep-0333.html Python Web Server Gateway Interface v1.0 PEP333]
 * http://wsgi.org/
 * [http://pythonpaste.org/ Paste] ["PasteQuickIn"] 为编写基于WSGI的应用程序或框架提供一个良好的基础, 比如:提供wsgi web服务器,常用wsgi中间件 等.

== 例子 ==
=== WSGI应用程序 ===
{{{#!python
def simple_app(environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['Hello world!\n']


class AppClass:
    """Produce the same output, but using a class

    (Note: 'AppClass' is the "application" here, so calling it
    returns an instance of 'AppClass', which is then the iterable
    return value of the "application callable" as required by
    the spec.

    If we wanted to use *instances* of 'AppClass' as application
    objects instead, we would have to implement a '__call__'
    method, which would be invoked to execute the application,
    and we would need to create an instance for use by the
    server or gateway.
    """

    def __init__(self, environ, start_response):
        self.environ = environ
        self.start = start_response

    def __iter__(self):
        status = '200 OK'
        response_headers = [('Content-type','text/plain')]
        self.start(status, response_headers)
        yield "Hello world!\n"
}}}
=== WSGI服务器 ===
{{{#!python
import os, sys

def run_with_cgi(application):

    environ = dict(os.environ.items())
    environ['wsgi.input'] = sys.stdin
    environ['wsgi.errors'] = sys.stderr
    environ['wsgi.version'] = (1,0)
    environ['wsgi.multithread'] = False
    environ['wsgi.multiprocess'] = True
    environ['wsgi.run_once'] = True

    if environ.get('HTTPS','off') in ('on','1'):
        environ['wsgi.url_scheme'] = 'https'
    else:
        environ['wsgi.url_scheme'] = 'http'

    headers_set = []
    headers_sent = []

    def write(data):
        if not headers_set:
             raise AssertionError("write() before start_response()")

        elif not headers_sent:
             # Before the first output, send the stored headers
             status, response_headers = headers_sent[:] = headers_set
             sys.stdout.write('Status: %s\r\n' % status)
             for header in response_headers:
                 sys.stdout.write('%s: %s\r\n' % header)
             sys.stdout.write('\r\n')

        sys.stdout.write(data)
        sys.stdout.flush()

    def start_response(status,response_headers,exc_info=None):
        if exc_info:
            try:
                if headers_sent:
                    # Re-raise original exception if headers sent
                    raise exc_info[0], exc_info[1], exc_info[2]
            finally:
                exc_info = None # avoid dangling circular ref
        elif headers_set:
            raise AssertionError("Headers already set!")

        headers_set[:] = [status,response_headers]
        return write

    result = application(environ, start_response)
    try:
        for data in result:
            if data: # don't send headers until body appears
                write(data)
        if not headers_sent:
            write('') # send headers now if body was empty
    finally:
        if hasattr(result,'close'):
            result.close()
}}}
=== WSGI中间件 ===
{{{#!python
from piglatin import piglatin

class LatinIter:

    """Transform iterated output to piglatin, if it's okay to do so

    Note that the "okayness" can change until the application yields
    its first non-empty string, so 'transform_ok' has to be a mutable
    truth value."""

    def __init__(self,result,transform_ok):
        if hasattr(result,'close'):
            self.close = result.close
        self._next = iter(result).next
        self.transform_ok = transform_ok

    def __iter__(self):
        return self

    def next(self):
        if self.transform_ok:
            return piglatin(self._next())
        else:
            return self._next()

class Latinator:

    # by default, don't transform output
    transform = False

    def __init__(self, application):
        self.application = application

    def __call__(self, environ, start_response):

        transform_ok = []

        def start_latin(status,response_headers,exc_info=None):

            # Reset ok flag, in case this is a repeat call
            transform_ok[:]=[]

            for name,value in response_headers:
                if name.lower()=='content-type' and value=='text/plain':
                    transform_ok.append(True)
                    # Strip content-length if present, else it'll be wrong
                    response_headers = [(name,value)
                        for name,value in response_headers
                            if name.lower()<>'content-length'
                    ]
                    break

            write = start_response(status,response_headers,exc_info)

            if transform_ok:
                def write_latin(data):
                    write(piglatin(data))
                return write_latin
            else:
                return write

        return LatinIter(self.application(environ,start_latin),transform_ok)


# Run foo_app under a Latinator's control, using the example CGI gateway
from foo_app import foo_app
run_with_cgi(Latinator(foo_app))
}}}

== 讨论 ==
大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!

大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!大哥小弟,附件不能删除了,还叫什么wiki啊,要人怎么更新阿?! 哈哈!

WSGI (last edited 2009-12-25 07:17:11 by localhost)