Size: 6161
Comment:
|
Size: 1049
Comment: 加两篇翻译文章的链接
|
Deletions are marked like this. | Additions are marked like this. |
Line 7: | Line 7: |
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() }}} |
[[Include(/AbtWSGI)]] |
Line 28: | Line 14: |
* [http://www-128.ibm.com/developerworks/library/wa-wsgi/ Mix and match Web components with Python WSGI] * 中译版本 [:/MixMatchWebComponentsWithPyWSGI:使用PyWSGI混合WEB组件] * [http://xlp223.yculblog.com/post.2566634226.html Why so many Python web frameworks?(中译版本)] * [http://xlp223.yculblog.com/post.2566639120.html WSGI-Gateway or Glue?(中译版本)] == 规范 == === WSGI应用程序 === [[Include(/AppWSGI)]] |
|
Line 29: | Line 22: |
== 例子 == === 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'] |
=== WSGI服务器 === [[Include(/SrvWSGI)]] === WSGI中间件 === [[Include(/MidWSGI)]] |
Line 40: | Line 28: |
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)) }}} |
== 规范细节 == [[Include(/DetailsWSGI)]] |
简介
相关页面
[http://www.python.org/peps/pep-0333.html Python Web Server Gateway Interface v1.0 PEP333]
[http://pythonpaste.org/ Paste] ["PasteQuickIn"] 为编写基于WSGI的应用程序或框架提供一个良好的基础, 比如:提供wsgi web服务器,常用wsgi中间件 等.
[http://www-128.ibm.com/developerworks/library/wa-wsgi/ Mix and match Web components with Python WSGI]
中译版本 [:/MixMatchWebComponentsWithPyWSGI:使用PyWSGI混合WEB组件]
[http://xlp223.yculblog.com/post.2566634226.html Why so many Python web frameworks?(中译版本)]
[http://xlp223.yculblog.com/post.2566639120.html WSGI-Gateway or Glue?(中译版本)]
规范
WSGI应用程序
WSGI服务器
WSGI中间件
规范细节