python bottle 简介

来源:互联网 发布:淘宝店招制作视频 编辑:程序博客网 时间:2024/05/17 06:10
  bottle 是一个轻量级的python web框架, 可以适配各种web服务器,包括python自带的wsgiref(默认),gevent, cherrypy,gunicorn等等。bottle是单文件形式发布,源码在这里可以下载,代码量不多,可以用来学习web框架。这里也有官方文档的中文翻译。
  首先我们来运行一下bottle的hello world
复制代码
from bottle import run if __name__ == '__main__':    def application(environ, start_response):        start_response('200 OK', [('Content-Type', 'text/html')])        return ['<h1>Hello world!</h1>']     run(host='localhost', port=8080, app=application)
复制代码
  上面的代码看起来也非常符合wsgi的接口规范。启动改代码,可以看到输出
        Bottle v0.13-dev server starting up (using WSGIRefServer())...
        Listening on http://localhost:8080/
        Hit Ctrl-C to quit.
  输出中加粗部分表明使用的web服务器是python自带的wsgiref。也可以使用其他web server,比如gevent,前提是需要安装gevent,修改后的代码如下:
复制代码
from bottle import runimport gevent.monkeygevent.monkey.patch_all() if __name__ == '__main__':    def application(environ, start_response):        start_response('200 OK', [('Content-Type', 'text/html')])        return ['<h1>Hello world!</h1>']     run(host='localhost', port=8080, app=application, server = 'gevent')
复制代码

通过server关键字指定web服务器为‘gevent’,输出的第一行变成了:

    Bottle v0.13-dev server starting up (using GeventServer())...
不管bottle用什么web服务器启动,在浏览器输入127.0.0.1:8080,都可以看到
    
下面介绍bottle中部分类和接口
bottle.Bottle
    代表一个独立的wsgi应用,由一下部分组成:routes, callbacks, plugins, resources and configuration。
    __call__: Bottle定义了__call__函数, 使得Bottle的实例能成为一个callable。在前文提到,web框架(或Application)需要提供一个callbale对象给web服务器,bottle提供的就是Bottle实例
    def __call__(self, environ, start_response):      """ Each instance of :class:'Bottle' is a WSGI application. """       return self.wsgi(environ, start_response)        
    下面是Bottle.wsgi函数的核心代码,主要调用两个比较重要的函数:_handle, _cast
复制代码
    def wsgi(self, environ, start_response):        """ The bottle WSGI-interface. """        try:            out = self._cast(self._handle(environ))            # rfc2616 section 4.3            if response._status_code in (100, 101, 204, 304)\            or environ['REQUEST_METHOD'] == 'HEAD':                if hasattr(out, 'close'): out.close()                out = []            start_response(response._status_line, response.headerlist)            return out
复制代码

  _handle:处理请求,最终调用到application ,简化后的代码如下:

1   def _handle(self, environ):2         self.trigger_hook('before_request')3         route, args = self.router.match(environ)4         out = route.call(**args)5         self.trigger_hook('after_request')6         return out
  _cast: 
       标准的wsgi接口对Application的返回值要求严格,必须迭代返回字符串。bottle做了一些扩展,可以允许App返回更加丰富的类型,比如dict,File等。 _cast函数对_handle函数返回值进行处理,使之符合wsgi规范
 
bottle.Route
    封装了路由规则与对应的回调
bottle.Router
    A Router is an ordered collection of route->target pairs. It is used to  efficiently match WSGI requests against a number of routes and return the first target that satisfies the request.
ServerAdapter
    所有bottle适配的web服务器的基类,子类只要实现run方法就可以了,bottle里面有大量的Web服务器的适配。下表来自官网,介绍了bottle支持的各种web服务器,以及各自的特性。
    NameHomepageDescriptioncgi Run as CGI scriptflupflupRun as FastCGI processgaegaeHelper for Google App Engine deploymentswsgirefwsgirefSingle-threaded default servercherrypycherrypyMulti-threaded and very stablepastepasteMulti-threaded, stable, tried and testedrocketrocketMulti-threadedwaitresswaitressMulti-threaded, poweres PyramidgunicorngunicornPre-forked, partly written in CeventleteventletAsynchronous framework with WSGI support.geventgeventAsynchronous (greenlets)dieseldieselAsynchronous (greenlets)fapws3fapws3Asynchronous (network side only), written in CtornadotornadoAsynchronous, powers some parts of FacebooktwistedtwistedAsynchronous, well tested but... twistedmeinheldmeinheldAsynchronous, partly written in CbjoernbjoernAsynchronous, very fast and written in Cauto Automatically selects an available server adapter
    可以看到,bottle适配的web服务器很丰富。工作模式也很全面,有多线程的(如paste)、有多进程模式的(如gunicorn)、也有基于协程的(如gevent)。具体选择哪种web服务器取决于应用的特性,比如是CPU bound还是IO bound
bottle.run
    启动wsgi服务器。几个比较重要的参数
    app: wsgi application,即可以是bottle.Bottle 也开始是任何满足wsgi 接口的函数
    server: wsgi http server,字符串
    host:port: 监听端口
    核心逻辑:
    ServerAdapter.run(app)。
最后,bottle源码中有一些使用descriptor的例子,实现很巧妙,值得一读,前文也有介绍。
references;
http://www.bottlepy.org/docs/dev/
https://raw.githubusercontent.com/bottlepy/bottle/master/bottle.py
http://blog.csdn.net/huithe/article/details/8087645
http://simple-is-better.com/news/59
http://www.bottlepy.org/docs/dev/deployment.html#server-options
http://blog.rutwick.com/use-bottle-python-framework-with-google-app-engine

0 0