<强>瓶强>
瓶是一个使用Python编写的轻量级网络应用框架,让我们可以使用Python语言快速搭建Web服务,瓶也被称为“microframework”,因为它使用简单的核心,用扩展增加其他功能
我们先来看看python现在比较流行的网框架
-
<李>瓶李>
<李> Django李>
<李>龙卷风李>
<李> Sanic李>
瓶:轻,组件间松耦合,自由,灵活,可扩展性强,第三方库的选择面广的同时也增加了组件间兼容问题
Django: Django相当于一个全家桶,几乎包括了所有web开发用到的模块(会话管理,CSRF防伪造请求,形式表单处理,ORM数据库对象化,模板语言),但是相对应的会造成一个紧耦合的情况,对第三方插件不太友好
龙卷风:底层通过eventloop来实现异步处理请求,处理效率高,学习难度大,处理稍有不慎很容易阻塞主进程导致不能正常提供服务,新版本也支持asyncio
Sanic:一个类瓶框架,但是底层使用uvloop进行异步处理,可以使用同步的方式编写异步代码,而且运行效率十分高效。
先来看看维基百科对WSGI的定义
Web服务器网关接口(Python Web服务器网关接口,缩写为WSGI)是为Python语言定义的Web服务器和网络应用程序或框架之间的一种简单而通用的接口。
何为网关,即从客户端发出的每个请求(数据包)第一个到达的地方,然后再根据路由进行转发处理。而对于服务端发送过来的消息,总是先通过网关层,然后再转发至客户端
那么可想而知,WSGI其实是作为一个网关接口,来接受服务器传递过来的信息,然后通过这个接口调用后台应用程序里的视图函数进行响应。
先看一段有趣的对话:
Nginx:嘿,WSGI,我刚收到了一个请求,我需要你作些准备,然后由瓶来处理这个请求。
引用>
WSGI:好的,Nginx。我会设置好环境变量,然后将这个请求传递给瓶处理。
瓶:谢谢。WSGI给我一些时间,我将会把请求的响应返回给你。
WSGI:好吧,那我等你。
瓶:好的,我完成了,这里是请求的响应结果,请求把结果传递给Nginx。
WSGI:好!Nginx,这里是响应结果,已经按照要求给你传递回来了。
Nginx:酷,我收到了,我把响应结果返回给客户端。大家合作愉快~对话里面可以清晰了解到WSGI, nginx,瓶三者的关系
下面来看看瓶中的wsgi接口(注意:每个进入瓶的请求都会调用Flask.__call__)
#摘自瓶源码app.py 类瓶(_PackageBoundObject): #中间省略 def __call__(自我、环境start_response): 回归自我。start_response wsgi_app(环境) def wsgi_app(自我、环境start_response): 环境:一个包含全部HTTP请求信息的字典,由WSGI服务器解包HTTP请求生成 # start_response: WSGI服务器提供的函数,调用可以发送响应的状态码和HTTP报文头, #函数在返回前必须调用一次。 :param环境:WSGI环境。 :param start_response:一个可调用的接受状态码, 标题的列表,和一个可选的异常上下文 开始响应。 #创建上下文 ctx=self.request_context(环境) 错误=没有 试一试: 试一试: #把上下文压栈 ctx.push () #分发请求 响应=self.full_dispatch_request () 除了例外e: 错误=e 响应=self.handle_exception (e) 除了: 错误=sys.exc_info () [1] 提高 #返回结果 start_response返回响应(环境) 最后: 如果self.should_ignore_error(错误): 错误=没有 #上下文出栈 ctx.auto_pop(错误) >之前wsgi_app中定义的就是瓶处理一个请求的基本流程,
1.创建上下文
2.把上下文入栈
3.分发请求
4.上下文出栈
5 .返回结果其中反应=self.full_dispatch_request()请求分发的过程我们需要关注一下
#摘自瓶源码app.py 类瓶(_PackageBoundObject): #中间省略 def full_dispatch_request(自我): self.try_trigger_before_first_request_functions () 试一试: request_started.send(自我) 房车=self.preprocess_request () 如果没有:房车 房车=self.dispatch_request () 除了例外e: 房车=self.handle_user_exception (e) 返回self.finalize_request (rv) def dispatch_request(自我): 要求=_request_ctx_stack.top.request 如果要求。routing_exception不是没有: self.raise_routing_exception(要求) 规则=req.url_rule 如果getattr(规则,provide_automatic_options, False) \ 和要求。方法==把∠睢? 返回self.make_default_options_response () 返回self.view_functions [rule.endpoint] (* * req.view_args) def finalize_request(自我,房车,from_error_handler=False): 响应=self.make_response (rv) 试一试: 响应=self.process_response(响应) request_finished。发送(自我,响应=响应) 除了例外: 如果不是from_error_handler: 提高 self.logger。异常(“请求最终失败了,” 当处理一个错误时发生错误) 返回响应浅谈瓶源码之请求过程