Bottle 框架源码学习 二

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bottle 框架源码学习 二相关的知识,希望对你有一定的参考价值。

上一篇简单分析了route的基本用法

本篇分析一下run函数的运行原理

def run(app=None, server=‘wsgiref‘, host=‘127.0.0.1‘, port=8080,
        interval=1, reloader=False, quiet=False, plugins=None,
        debug=None, **kargs):
    
    if NORUN: return
    if reloader and not os.environ.get(‘BOTTLE_CHILD‘):
        try:
            lockfile = None
            fd, lockfile = tempfile.mkstemp(prefix=‘bottle.‘, suffix=‘.lock‘)
            os.close(fd) # We only need this file to exist. We never write to it
            while os.path.exists(lockfile):
                args = [sys.executable] + sys.argv
                environ = os.environ.copy()
                environ[‘BOTTLE_CHILD‘] = ‘true‘
                environ[‘BOTTLE_LOCKFILE‘] = lockfile
                p = subprocess.Popen(args, env=environ)
                while p.poll() is None: # Busy wait...
                    os.utime(lockfile, None) # I am alive!
                    time.sleep(interval)
                if p.poll() != 3:
                    if os.path.exists(lockfile): os.unlink(lockfile)
                    sys.exit(p.poll())
        except KeyboardInterrupt:
            pass
        finally:
            if os.path.exists(lockfile):
                os.unlink(lockfile)
        return

    try:
        if debug is not None: _debug(debug)
        app = app or default_app()
        if isinstance(app, basestring):
            app = load_app(app)
        if not callable(app):
            raise ValueError("Application is not callable: %r" % app)

        for plugin in plugins or []:
            app.install(plugin)

        if server in server_names:
            server = server_names.get(server)
        if isinstance(server, basestring):
            server = load(server)
        if isinstance(server, type):
            server = server(host=host, port=port, **kargs)
        if not isinstance(server, ServerAdapter):
            raise ValueError("Unknown or unsupported server: %r" % server)

        server.quiet = server.quiet or quiet
        if not server.quiet:
            _stderr("Bottle v%s server starting up (using %s)...\n" % (__version__, repr(server)))
            _stderr("Listening on http://%s:%d/\n" % (server.host, server.port))
            _stderr("Hit Ctrl-C to quit.\n\n")

        if reloader:
            lockfile = os.environ.get(‘BOTTLE_LOCKFILE‘)
            bgcheck = FileCheckerThread(lockfile, interval)
            with bgcheck:
                server.run(app)
            if bgcheck.status == ‘reload‘:
                sys.exit(3)
        else:
            server.run(app)
    except KeyboardInterrupt:
        pass
    except (SystemExit, MemoryError):
        raise
    except:
        if not reloader: raise
        if not getattr(server, ‘quiet‘, quiet):
            print_exc()
        time.sleep(interval)
        sys.exit(3)

 1.

if reloader and not os.environ.get(‘BOTTLE_CHILD‘):

  这段代码作用是判断用户编辑了源码后,是否需要重新载入并运行bottle,先知道它的作用,具体细节暂时不看


 2.看这一段

app = app or default_app()
if isinstance(app, basestring):
    app = load_app(app)
if not callable(app):
    raise ValueError("Application is not callable: %r" % app)

如果不显式指定一个application对象,bottle会帮我们生成一个默认的application对象

如果提供的app是一个字符串,则会通过load_app返回一个application对象

3.

if server in server_names:
    server = server_names.get(server)
if isinstance(server, basestring):
    server = load(server)
if isinstance(server, type):
    server = server(host=host, port=port, **kargs)
if not isinstance(server, ServerAdapter):
    raise ValueError("Unknown or unsupported server: %r" % server)

server.quiet = server.quiet or quiet
if not server.quiet:
    _stderr("Bottle v%s server starting up (using %s)...\n" % (__version__, repr(server)))
    _stderr("Listening on http://%s:%d/\n" % (server.host, server.port))
    _stderr("Hit Ctrl-C to quit.\n\n")

if reloader:
    lockfile = os.environ.get(‘BOTTLE_LOCKFILE‘)
    bgcheck = FileCheckerThread(lockfile, interval)
    with bgcheck:
        server.run(app)
    if bgcheck.status == ‘reload‘:
        sys.exit(3)
else:
    server.run(app)

如果不指定server(即实现wsgi协议的服务器程序),则会应用WSGIRefServer这个服务器程序

4.

server_names = {
    ‘cgi‘: CGIServer,
    ‘flup‘: FlupFCGIServer,
    ‘wsgiref‘: WSGIRefServer,
    ‘waitress‘: WaitressServer,
    ‘cherrypy‘: CherryPyServer,
    ‘paste‘: PasteServer,
    ‘fapws3‘: FapwsServer,
    ‘tornado‘: TornadoServer,
    ‘gae‘: AppEngineServer,
    ‘twisted‘: TwistedServer,
    ‘diesel‘: DieselServer,
    ‘meinheld‘: MeinheldServer,
    ‘gunicorn‘: GunicornServer,
    ‘eventlet‘: EventletServer,
    ‘gevent‘: GeventServer,
    ‘geventSocketIO‘:GeventSocketioserver,
    ‘rocket‘: RocketServer,
    ‘bjoern‘ : BjoernServer,
    ‘auto‘: AutoServer,
}

以上是bottle支持的servers

本文出自 “nickylans” 博客,请务必保留此出处http://378359.blog.51cto.com/368359/1959384

以上是关于Bottle 框架源码学习 二的主要内容,如果未能解决你的问题,请参考以下文章

Bottle 框架源码学习 二

python bottle 简介

python微框架Bottle(http)

bottle源码笔记

bottle框架学习:变量定义等

bottle框架学习:命令行