资讯专栏INFORMATION COLUMN

Python WSGI

lingdududu / 1674人阅读

摘要:在实际创建一个运行的时,一个参数都不需要我们传,无论是还是回调函数都由服务器,也就是负责。如上所述,两个参数,回调函数传入和最后返回一个字符串,也就是服务器返回给客户端的核心数据。

Python中的WSGI

https://jasonlvhit.github.io/...

简单来看,wsgi是web组件的接口规范,在wsgi规范里,wsgi把web组件分成三个部分,wsgi server,wsgi middleware,wsgi application

application

更多的时候,我们关心的只是wsgi application, wsgi application就是一个Python中的callable对象(函数,或定义了__call__方法的类等), 接受两个参数,environ和start_response,参数只是一个名字而已,environ指的是环境变量,start_response是一个回调函数。在实际创建一个运行的app时,一个参数都不需要我们传,无论是environ还是回调函数都由服务器,也就是wsgi server负责。

environ

environ 包括 服务器环境变量,客户端环境变量,和请求中的数据method,path等等。environ是怎么生成的呢?

wsgi server主要分为两部分,server和handler。server监听端口,handler处理请求。server接受到一个request,解析客户端environ,bind一个handler,handler解析请求,将请求信息放入environ,最后服务器端环境变量也放入environ中。这就是environ的全部了。

start_response

在wsgiref中,回调函数start_response的源码是下面这样的:

def start_response(self, status, headers,exc_info=None):

    """"start_response()" callable as specified by PEP 333"""

    if exc_info:
        try:
            if self.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 self.headers is not None:
        raise AssertionError("Headers already set!")

    assert type(status) is StringType,"Status must be a string"
    assert len(status)>=4,"Status must be at least 4 characters"
    assert int(status[:3]),"Status message must begin w/3-digit code"
    assert status[3]==" ", "Status message must have a space after code"
    if __debug__:
        for name,val in headers:
            assert type(name) is StringType,"Header names must be strings"
            assert type(val) is StringType,"Header values must be strings"
            assert not is_hop_by_hop(name),"Hop-by-hop headers not allowed"
    self.status = status
    self.headers = self.headers_class(headers)
    return self.write

函数接受两个参数,status,也就是HTTP状态码,和headers,请求头。函数验证这两个信息,并将其塞入服务器。最后调用write方法,write方法的功能是“to buffer data for send to client”,也就是把信息再塞回客户端。

说到这,我们就可以看看一个在PEP3333中给出的简单的wsgi app了。

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]

如上所述,两个参数,environ, start_response, 回调函数start_response传入status和headers,最后返回一个字符串,也就是服务器返回给客户端的核心数据。

同样,我们说过,一个wsgi application是一个callable对象,只要他是callable(实现__call__方法)的就可以。在PEP3333中也给出了一个简单的类形式的app:

class AppClass:

def __call__(self, environ, start_response):
    status = "200 OK"
    response_headers = [("Content-type", "text/plain")]
    start_response(status, response_headers)
return [HELLO_WORLD]

到这,其实wsgi的结构很清晰了,最后,还差一个wsgi middleware。

middleware

按照PEP3333的说法,wsgi server是server端的东西,wsgi app是应用端的东西,并不是说middleware是中间的东西,middleware是一个两头兼顾的东西。

我们可以把app看成一个蛋糕,middleware则是这块蛋糕的包装。web服务中,例如session,route,auth等等,都是用middleware实现的。

例如一个PEP3333中的这个转换piglatin的wsgi middleware:

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 bytestring, 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())   # call must be byte-safe on Py3
    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
        del 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))   # call must be byte-safe on Py3
            return write_latin
        else:
            return write

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

middleware与函数装饰器很像。

最后,一个应用的middleware不止一层,middleware可能像下面一样工作:

def configure(app):
   return ErrorHandlerMiddleware(
           SessionMiddleware(
            IdentificationMiddleware(
             AuthenticationMiddleware(
              UrlParserMiddleware(app))))))
webframework

最后我们来看webframework,现在回想一下包括Django,Flask等框架,我们可以察觉出Python的web框架并不是特别的难以搭建。在4年前,第一个版本的Flask,只有短短600行代码,并且其中充斥着大量的注释(文档)。

一般来说,一个python的webframework需要一个wsgi工具集(werkzeug, webob(pylons)),一个模板渲染引擎(mako,jinja2)和一个ORM数据库工具集(sqlalchemy),还有其他的包括dispatcher,mail,json等支持,这样我们可以胶合一个自己的框架。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40680.html

相关文章

  • CentOS 5系统安装Django、Apache 、mod_wsgi部署Python环境教程

    摘要:系统安装部署环境教程第一安装依赖环境在准备安装框架部署之前,我们需要先安装依赖环境,因为可能默认的环境没有完善的最新部署包。检查最新版本的数据库,然后部署安装。到目前为止,我们已经成功的在环境中部署了应用程序,以及。 Django,是一款针对Python环境的WEB开发框架,能够帮助我们构架快捷、简单的WEB框架设置,Django框架非常适合开发内容应用环境,所以在本文中,麦子将整理基...

    褰辩话 评论0 收藏0
  • Linux下 apache 配置 wsgi 以使用 python-flask (2016年2月)

    摘要:先在服务器上安装配置好下载地址将下载好的文件上传至服务器解压安装下载页面有说明注意看一下满足没有有种安装方式一种是直接安装到一种是安装到这里先采用第一种直接安装到进入下载的文件目录常规安装先然后最后因为我是自己搭的服务器而且是版所以很多软件 先在linux服务器上安装, 配置好apache 下载wsgi, 地址: https://pypi.python.org/pypi/mod_ws...

    binaryTree 评论0 收藏0
  • WSGI简介

    摘要:提出这些规范的目的就是为了定义统一的标准,提升程序的可移植性。的对象处理完成后,会调用并且返回结果给,存放在中。比如可以检查是否有非法内容,检查是否有非法内容,为加上特定的等,这些都是可以的。的实现和部署要使用,需要分别实现角色和角色。 WSGI是什么 WSGI的全称是Web Server Gateway Interface,翻译过来就是Web服务器网关接口。具体的来说,WSGI是一个...

    Harpsichord1207 评论0 收藏0
  • Hello, WSGI

    摘要:最新的工作中,有一部分的任务,于是开始折腾先恶补理论吧,关于有篇需要看,和,前者是年的提案,后者在年对前者做了小幅修订,提案状态也已经是,所以已经不是提案,已经是协议规范了,是的缩写,解决的是各种比如与各种框架比如之间互联互通的兼容性问题如 最新的工作中,有一部分HTTP API的任务,于是开始折腾Python WSGI... WSGI 先恶补理论吧,关于Python WSGI有2...

    array_huang 评论0 收藏0
  • 通读Python官方文档之wsgiref(未完成)

    摘要:一般来说,这一例行程序用于处理请求的每一部分,例如把路径作为一系列字典键值进行处理。,必须是按照中所规定地键值元组列表。行为时回车换行。这个包装器也可能用模块指明那些有问题的,但不完全违反的行为。 wsgirf-WSGI功能及参考实现 源码:Lib/wsgiref Web服务器网关接口(Web Server Gateway Interface, WSGI),是用Python写的一个服务...

    mumumu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<