This note is about PEP3333- Python Web Server Gateway Interface. Refer to (Source: http://legacy.python.org/dev/peps/pep-3333/) for the complete description. 

1. From the Application/Framwork side

The application object is simply a callable object that accepts two arguments, named environ, and start_response, following the convention.

Example:

HELLO_WORLD = b"Hello world!\n"

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]

2. From the Server/Gateway side

The server or gateway invokes the application callable once for each request it receives from an HTTP client.

Exmple:

import os, sys

enc, esc = sys.getfilesystemencoding(), 'surrogateescape'

def unicode_to_wsgi(u):
# Convert an environment variable to a WSGI "bytes-as-unicode" string
return u.encode(enc, esc).decode('iso-8859-1') def wsgi_to_bytes(s):
return s.encode('iso-8859-1') def run_with_cgi(application):
environ = {k: unicode_to_wsgi(v) for k,v in os.environ.items()}
environ['wsgi.input'] = sys.stdin.buffer
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', ''):
environ['wsgi.url_scheme'] = 'https'
else:
environ['wsgi.url_scheme'] = 'http' headers_set = []
headers_sent = [] def write(data):
out = sys.stdout.buffer 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
out.write(wsgi_to_bytes('Status: %s\r\n' % status))
for header in response_headers:
out.write(wsgi_to_bytes('%s: %s\r\n' % header))
out.write(wsgi_to_bytes('\r\n')) out.write(data)
out.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[1].with_traceback(exc_info[2])
finally:
exc_info = None # avoid dangling circular ref
elif headers_set:
raise AssertionError("Headers already set!") headers_set[:] = [status, response_headers] # Note: error checking on the headers should happen here,
# *after* the headers are set. That way, if an error
# occurs, start_response can only be re-called with
# exc_info set. 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()

3. Specification Details

The application object must accept two positional arguments. For the sake of illustration, we have named them environ and start_response, but they are not required to have these names. A server or gateway must invoke the application object using positional(not keyword) arguments.

The environ parameter is a dictonary object, containing CGI-style enviroment variables. This object must be a builtin Python dictionary (not a subclass, or other dictionary simulation), and the application is allowed to modify the dictionary in any way it desires. The dictionary must also include cetain WSGI-required variables, and may also include server-specific extension variables, named according to a covention.

The start_reponse parameter is a callable accepting two required positional arguments, and one optional argument. For the sake of illustration, we have named these arguments status, response_headers, and exc_info, but they are not required to have these names, and the application must invoke the start_response callable using positional arguments.

The status parameter is a status string of form '999 Message here', and response_headers is a list of (header_name, head_value) tuples describing the HTTP response header. The optional exc_info parameter is used only when the application has trapped an error and is attempting to display an error message to the browser.

The start_response callable must return a write(body_data) callable that takes one postional parameter: a bytestring to be written as part of the HTTP response body.

When called by the server, the application object must return an iterable yielding zero or more bytestrings. This can be accomplished in a variety of ways, such as by returning a list of bytestrings, or by the application being a generator function that yields bytestrings, or by the application being a class whose instances are iterable. Regardless of how it is accomplised, the application object must always return an iterable yielding zero or more bytestrings.

The server or gateway must transmit the yielded bytestrings to the client in an unbuffered fashion, completing the transmission of each bytestring before requesting another one. (In other words, applications should perform their own buffering.)

The application must invoke the start_response() callable before the iteralbe yields its first body bytestring, so that the server can send the headers before any body content. However, this invocatio nmay be performed by the iterable's first iteration, so servers must not assume that start_reponse() has been called before they begin iterating over the iterable.

If the iterable returned by the appliation has close() method, the server or gateway must call that method upon completion of the current request, whether the request was completed normally, or terminated early due to an application error during iteration or an early disconnect of the browser. (The close() method requirement is to support resource release by the application.)

Notes on PEP333 (Python Web Server Gateway Interface)的更多相关文章

  1. Python Web Server Gateway Interface -- WSGI

    了解了HTTP协议和HTML文档,我们其实就明白了一个Web应用的本质就是: 浏览器发送一个HTTP请求: 服务器收到请求,生成一个HTML文档: 服务器把HTML文档作为HTTP响应的Body发送给 ...

  2. a simple and universal interface between web servers and web applications or frameworks: the Python Web Server Gateway Interface (WSGI).

    WSGI is the Web Server Gateway Interface. It is a specification that describes how a web server comm ...

  3. python web server gateway interface (wsgi ) notes

    前言: 注:如果需要得到支持批Python3.x以及包含了勘误表,附录,和说明的更新版规范,请查看PEP 3333 摘要: 这篇文档详细说明了一套在web服务器与Python web应用程序(web框 ...

  4. 【Python Programe】WSGI (Web Server Gateway Interface)

    Part1: What is a Web server? 一个位于物理服务器上的网络服务器(服务器里的服务器),等待客户端去发送request,当服务器接收到request,就会生成一个respons ...

  5. Python的WSGI(Web Server Gateway Interface)服务器

    Python的WSGI(Web Server Gateway Interface)服务器 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任.

  6. 小测几种python web server的性能

    http://blog.csdn.net/raptor/article/details/8038476 因为换了nginx就不再使用mod_wsgi来跑web.py应用了,现在用的是gevent-ws ...

  7. C# 启动 a Python Web Server with Flask

    概览 最近有个需求是通过c#代码来启动python 脚本.嘿~嘿!!! 突发奇想~~既然可以启动python脚本,那也能启动flask,于是开始着手操作. 先看一波gif图 通过打开控制台启动flas ...

  8. 全面解读python web 程序的9种部署方式

    转载自鲁塔弗的博客,本文地址http://lutaf.com/141.htm  python有很多web 开发框架,代码写完了,部署上线是个大事,通常来说,web应用一般是三层结构 web serve ...

  9. [原]Python Web部署方式总结

    不要让服务器裸奔 学过PHP的都了解,php的正式环境部署非常简单,改几个文件就OK,用FastCgi方式也是分分钟的事情.相比起来,Python在web应用上的部署就繁杂的多,主要是工具繁多,主流服 ...

随机推荐

  1. redis学习笔记——主从同步(复制)

    在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器进行复 ...

  2. 编程算法 - 二叉搜索树 与 双向链表 代码(C++)

    二叉搜索树 与 双向链表 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目:输入一颗二叉搜索树, 将该二叉搜索树转换成一个排序的双向链表. 要求 ...

  3. Java Web开发基础(3)-JSTL

    在DRP项目中接触到了JSTL标签库,对我这样的比較懒的人来说,第一感觉就是"惊艳". JSTL标签库的使用.能够消除大量复杂.繁复的工作.工作量降低的不是一点半点.是降低了一大半 ...

  4. 【BIRT】使用rptlibrary设置统一数据源

    在使用birt开发报表的过程中我们通常会发现,如果直接在报表中写死数据源的话,那么之后如果数据库服务器发生变更,那么所有的报表都得一一去修改数据源 这是一个相当耗时间的过程. 1.首先新建librar ...

  5. PO*创建标准采购订单

    --   l_iface_rec       po_headers_interface%ROWTYPE; 校验头相关信息 ) INTO l_po_count FROM po_headers_all p ...

  6. python之模块csv之 读取CSV文件(reader和DictReader2个方法)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #读取CSV文件(reader和DictReader2个方法) import csv #csv文件,是一种常用 ...

  7. hdoj 2199 Can you solve this equation? 【二分枚举】

    题意:给出一个数让你求出等于这个数的x 策略:如题. 由于整个式子是单调递增的.所以能够用二分. 要注意到精度. 代码: #include <stdio.h> #include <s ...

  8. Swift调用OC和C

    Swift文件:main.swift import Foundation //Swift调用C函数 desc1() //Swift调用OC //拿到OC类 var funcClass = Root() ...

  9. 【laravel54】关于用户权限认证RBAC和无限极分类

    1.权限认证方面: https://packagist.org/packages/spatie/laravel-permission 用户认证 HTTP本身是无状态,通常在系统交互的过程中,使用账号或 ...

  10. PHP原生实现,校验微信公众号||小程序服务器地址

    1.原生的.php文件:  test.php <?php header('Content-type:text'); define("TOKEN", "weixin& ...