Size: 6161
Comment:
|
Size: 1902
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 7: | Line 7: |
[[Include(/AbtWSGI)]] | |
Line 8: | Line 9: |
wsgi 是一个 web 组件的接口规范. wsgi将 web 组件分为三类: web服务器,web中间件,web应用程序. 其目标是提高web组件的可重用性. wsgi 的设计目标是适合尽可能广泛的web应用, 较原始. |
== 相关资料 == '''http://wsgi.org/''' |
Line 13: | Line 12: |
典型场景: | 理解WSGI:: * PEP 333 -- Python Web Server Gateway Interface v1.0 * http://www.python.org/dev/peps/pep-0333/ * WSGI-Gateway or Glue? - 动态感觉 静观其变 - 歪酷博客 Ycool Blog * http://xlp223.ycool.com/post.1639120.html * [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?(中译版本)] |
Line 15: | Line 23: |
{{{#!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'] |
实用WSGI:: * 用 Python WSGI 混和并匹配 Web 组件 * http://www-128.ibm.com/developerworks/cn/web/wa-wsgi/index.html * PyLons 对 WEB服务网关接口(WSGI)的支持 * http://wiki.woodpecker.org.cn/moin/PyLons/wsgi WSGI框架:: * Frameworks - WSGI Wiki * http://www.wsgi.org/wsgi/Frameworks * A Pylons controller with MoinMoin as a WSGI callable - PylonsCookbook - PythonWeb * http://wiki.pylonshq.com/display/pylonscookbookA+Pylons+controller+with+MoinMoin+as+a+WSGI+callable * WsgiRequestPatch - MoinMoin * http://moinmoin.wikiwikiweb.de/WsgiRequestPatch |
Line 40: | Line 37: |
class AppClass: """Produce the same output, but using a class |
|
Line 43: | Line 38: |
(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. |
== 规范 == === WSGI应用程序 === [[Include(/AppWSGI)]] |
Line 48: | Line 42: |
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. """ |
=== WSGI服务器 === [[Include(/SrvWSGI)]] === WSGI中间件 === [[Include(/MidWSGI)]] |
Line 55: | Line 47: |
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)]] |
Line 199: | Line 51: |
=== 深思WSGI === [[Include(/AskWSGI,,from="^##startInc$",to="^##endInc$")]] |
简介
相关资料
- 理解WSGI
- PEP 333 -- Python Web Server Gateway Interface v1.0
- WSGI-Gateway or Glue? - 动态感觉 静观其变 - 歪酷博客 Ycool Blog
[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
- 用 Python WSGI 混和并匹配 Web 组件
PyLons 对 WEB服务网关接口(WSGI)的支持
- WSGI框架
- Frameworks - WSGI Wiki
A Pylons controller with MoinMoin as a WSGI callable - PylonsCookbook - PythonWeb
规范
WSGI应用程序
WSGI服务器
WSGI中间件
规范细节
讨论