Flask的工作原理

web应用程序处理流程

  • 用户通过客户端发送请求。
  • 请求发送到web服务器上。
  • web服务器将请求转交给web应用程序,web应用程序进行处理。
  • web应用程序将请求结果返回给web服务器,由web服务器返回响应结果给客户端。
  • 客户端收到响应结果,展示给用户。

可以看到,web服务器和web应用程序需要进行通信,但是web服务器有很多种(apache,Nginx,Lighttpd...),web应用程序开发框架也有很多种(Flask,Django...),如果没有统一标准进行通信,就会存在Web框架和Web服务器数据无法匹配的情况,那么开发就会受到限制,这显然不合理的。所以就有了WSGI规范,那么什么是WSGI呢?

WSGI

web服务器网关接口(Python Web Server Gateway Interface,简称WSGI),是为python定义的web服务器和web应用程序或框架之间的一种简单而通用的接口。它是一种规范,作用于web服务器和python应用程序之间,目的是保证不同的web服务器和不同的web应用程序或框架能够进行通信。



wsgi就像一个桥梁,连接着服务器和应用程序。

WSGI区分为两个部分:一为“服务器”或“网关”,另一为“应用程序”或“应用框架”。在处理一个WSGI请求时,服务器会为应用程序提供环境信息及一个回调函数。当应用程序完成处理请求后,透过前述的回调函数,将结果回传给服务器。

WSGI 相当于中间件同时实现了API的两方,因此可以在服务器和应用程序之间起调解作用:从Web服务器的角度来说,中间件扮演应用程序,而从应用程序的角度来说,中间件扮演服务器。

WSGI规定:

  • web应用程序必须是一个可调用对象,必须接收两个参数,返回一个可迭代对象。
  • 两个参数(由服务器提供):
    environ:字典,包含请求的所有信息
    start_response:在可调用对象中调用的函数,用来发起响应,参数包括状态码,headers等

根据这些规则,很容易写出一个遵循wsgi协议的app。

def application(environ, start_response):
    status = "200 OK"
    response_headers = [('Content-Type', 'text/html')]
    start_response(status, response_headers)
    return [b'

hello world!

' ]

了解了WSGI,让我们从源码的角度来看一下Flask的工作原理。

Flask处理请求入口

我们知道,遵循WSGI协议的应用一定是一个可调用对象, 所以它既可以是一个函数, 也可以是一个实现了__call__()方法的类。
我们可以看一下Flask的源码。

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

flask在接收请求时,会执行__call__()方法,而__call__()方法会调用wsgi_app方法,这就是核心所在。

    def wsgi_app(self, environ, start_response):
        ctx = self.request_context(environ)
        error = None
        try:
            try:
                ctx.push()
                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:  # noqa: B001
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)

这个就是Flask的真正请求入口了,该方法完成了请求和响应的处理,WSGI服务器通过调用该方法传入请求数据,获取返回数据。

我们看一下wsgi_app具体实现。

Flask处理请求的实现

  • ctx = self.request_context(environ)和ctx.push()这里的代码是创建一个request对象和生成请求上下文环境。
  • response = self.full_dispatch_request() 这部分实现了请求预处理,错误处理及请求转发到响应的过程。
  • return response(environ, start_response) 这部分将响应结果返回给WSGI。

到此为止,WSGI和flask一次请求到响应完成了。

你可能感兴趣的:(Flask的工作原理)