flask源码之flask入口(一)

Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。

“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。

默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同是 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已准备好在需求繁杂的生产环境中投入使用。

wsgi

werkzeug示例

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)

flask基本使用

from flask import Flask

app = Flask(__name__)

#将 ‘/’和函数hello_world的对应关系添加到路由中
@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    #监听用户请求
    #如果有用户请求到来,则执行app的__call__方法
    app.run()

我们点开run()看里面的源码你会发现:

    def run(self, host=None, port=None, debug=None,
            load_dotenv=True, **options):
        if os.environ.get('FLASK_RUN_FROM_CLI') == 'true':
            from .debughelpers import explain_ignored_app_run
            explain_ignored_app_run()
            return

        if get_load_dotenv(load_dotenv):
            cli.load_dotenv()
            if 'FLASK_ENV' in os.environ:
                self.env = get_env()
                self.debug = get_debug_flag()
            elif 'FLASK_DEBUG' in os.environ:
                self.debug = get_debug_flag()
        if debug is not None:
            self.debug = bool(debug)
        #对ip和端口进行的一些设置
        _host = '127.0.0.1'
        _port = 5000
        server_name = self.config.get('SERVER_NAME')
        sn_host, sn_port = None, None

        if server_name:
            sn_host, _, sn_port = server_name.partition(':')

        host = host or sn_host or _host
        port = int(port or sn_port or _port)

        options.setdefault('use_reloader', self.debug)
        options.setdefault('use_debugger', self.debug)
        options.setdefault('threaded', True)

        cli.show_server_banner(self.env, self.debug, self.name, False)

        from werkzeug.serving import run_simple

        try:
            #这儿又回到了上面的代码了,这儿self就是app对象,对象叫括号执行对象的__call__方法
            run_simple(host, port, self, **options)
        finally:
            self._got_first_request = False

我们通过app.__call__()进去源码看:

    def __call__(self, environ, start_response):

        #environ是请求相关,start_response相应相关
        return self.wsgi_app(environ, start_response)

我们在点开wsgi_app进去看源码:

    def wsgi_app(self, environ, start_response):
        #这儿就是所有请求的入口
        ctx = self.request_context(environ)
        error = None
        try:
            try:
                #ctx.session中已经有值
                ctx.push()

                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def __repr__(self):
        return '<%s %r>' % (
            self.__class__.__name__,
            self.name,
        )

猜你喜欢

转载自blog.csdn.net/huang_yong_peng/article/details/82496415