Bottle源码分析

server适配

Bottle的一个优势是适配很多支持WSGI的Server,主要有默认是用wsgiref,CherryPy,Gunicorn,Tornado,Eventlet和Gevent。
Bottle中定义了ServerAdapter基类,通过继承这个基类,可以适配很多的WSGI Server。通过将解析完的app对象以及相关的host,port等参数传递给ServerAdapter的子类,再通过各个Server特有的启动方式,根据指定的参数启动WSGI Server。
例如,WSGIRefefServer的实现就是这样的(直接从源码中copy过来)

class WSGIRefServer(ServerAdapter):
    def run(self, app):  # pragma: no cover
        from wsgiref.simple_server import make_server
        from wsgiref.simple_server import WSGIRequestHandler, WSGIServer
        import socket

        class FixedHandler(WSGIRequestHandler):
            def address_string(self):  # Prevent reverse DNS lookups please.
                return self.client_address[0]

            def log_request(*args, **kw):
                if not self.quiet:
                    return WSGIRequestHandler.log_request(*args, **kw)

        handler_cls = self.options.get('handler_class', FixedHandler)
        server_cls = self.options.get('server_class', WSGIServer)

        if ':' in self.host:  # Fix wsgiref for IPv6 addresses.
            if getattr(server_cls, 'address_family') == socket.AF_INET:

                class server_cls(server_cls):
                    address_family = socket.AF_INET6

        self.srv = make_server(self.host, self.port, app, server_cls,
                               handler_cls)
        self.port = self.srv.server_port  # update port actual port (0 means random)
        try:
            self.srv.serve_forever()
        except KeyboardInterrupt:
            self.srv.server_close()  # Prevent ResourceWarning: unclosed socket
            raise

Bottle中还提供了一个AutoServer,这个server会从几个默认的WSGI Server中尝试进行启动,直到第一个成功的为止。利用AutoServer的这个特性,可以很自由的在几个WSGI Server之间进行切换,而不必更改自己的代码。比如本机的环境(开发环境)可以安装WSGIRef,但是到了线上环境我们直接选择安装CherryPy,这样就能直接将WSGI Server切换到CherryPy,而且应用的代码不需要做任何改动。AutoServer的代码实现如下:

class AutoServer(ServerAdapter):
    """ Untested. """
    adapters = [WaitressServer, PasteServer, TwistedServer, CherryPyServer,
                WSGIRefServer]

    def run(self, handler):
        for sa in self.adapters:
            try:
                return sa(self.host, self.port, **self.options).run(handler)
            except ImportError:
                pass

默认app

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值