欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python WSGI开发WEB应用的理解

程序员文章站 2022-07-15 11:34:26
...

什么是WEB应用?

Web应用的本质:

  • 1)、浏览器发送HTTP请求
  • 2)、服务器接收到请求,生成HTML文档
  • 3)、服务器把HTML文档作为HTTP响应的Body发送给浏览器
  • 4)、浏览器收到HTTP响应,从HTTP
    Body取出HTML文档进行显示

整个浏览器动态请求服务器的全过程如下图:
Python WSGI开发WEB应用的理解

什么是WSGI?

WSGI(Web Server Gateway Interface,Web 服务器网关接口)则是Python语言中所定义的Web服务器和Web应用程序之间或框架之间的通用接口标准。
WSGI就是一座桥梁,桥梁的一端称为服务端或网关端,另一端称为应用端或者框架端,WSGI的作用就是在协议之间进行转化。WSGI将Web组件分成了三类:Web 服务器(WSGI Server)、Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。
Web Server接收HTTP请求,封装一系列环境变量,按照WSGI接口标准调用注册的WSGI Application,最后将响应返回给客户端。

WSGI Server?

WSGI Server可以理解为一个符合WSGI规范的web server,接收request请求,封装一系列环境变量,按照WSGI规范调用注册的WSGI App,最后将reponse返回给客户端。
WSGI Server的基本工作流程:

  • 1)服务器创建socket,监听端口,等待客户端连接。
  • 2)当有请求来时,服务器解析客户端信息放到环境变量environ中,并调用绑定的handler来处理请求。
  • 3)handler解析这个http请求,将请求信息例如method,path等放到environ中。
  • 4)wsgi handler再将一些服务器端信息也放到environ中,最后服务器信息,客户端信息,本次请求信息全部都保存到了环境变量environ中。
  • 5)wsgi handler 调用注册的wsgi app,并将environ和回调函数传给wsgi app。
  • 6)wsgi app将reponse header/status/body 回传给wsgi handler ,最终handler还是通过socket将response信息塞回给客户端。
    写法如下:
#最简单的WSGI server为Python自带的wsgiref.simple_server
from wsgiref.simple_server import make_server
srv = make_server('localhost', 8080, fuc)
srv.serve_forever()

WSGI Application?

WSGI协议要求:
the application object接受两个参数且可以被多次调用
这两个参数分别为:

  • 1)environ:是一个CGI式的字典;
  • 2)start_response:是一个回调函数:application用来向server传递http状态码/消息/http头

写法如下:

# the application object. 可以使用其他名字,
# 但是在使用mod_wsgi 时必须为 "application"
def application( environ, start_response):
 
# 构造响应体,以可迭代字符串形式封装
  response_body = 'The request method was %s' % environ['REQUEST_METHOD']
 
# HTTP 响应码及消息
  status = '200 OK'
 
# 提供给客户端的响应头.
# 封装成list of tuple pairs 的形式:
# 格式要求:[(Header name, Header value)].
  response_headers = [('Content-Type', 'text/plain'),
            ('Content-Length', str(len(response_body)))]
 
# 将响应码/消息及响应头通过传入的start_reponse回调函数返回给server
  start_response(status, response_headers)
 
# 响应体作为返回值返回
# 注意这里被封装到了list中.
  return [response_body]

WSGI Middleware?

所谓的 WSGI中间件同时实现了API的两方,因此可以在WSGI服务和WSGI应用之间起调解作用:从WSGI服务器的角度来说,中间件扮演应用程序,而从应用程序的角度来说,中间件扮演服务器。
“中间件”组件可以执行以下功能:

  • 1)重写环境变量后,根据目标URL,将请求消息路由到不同的应用对象。
  • 2)允许在一个进程中同时运行多个应用程序或应用框架。
  • 3)负载均衡和远程处理,通过在网络上转发请求和响应消息。
  • 4)进行内容后处理,例如应用XSLT样式表。

写法如下 :

class Router(object):
    def __init__(self):
        self.mapper = Mapper()
        self.mapper.connect('/test', controller=Controller(), action='test', conditions={'method': ['GET']})
        self.mapper.connect('/login', controller=Controller().login, action='login', conditions={'method': ['POST']})
        self.mapper.connect('/projects', controller=Controller().get_projects, action='get_projects',
                            conditions={'method': ['GET']})
        self.mapper.connect('/services', controller=Controller().get_services, action='get_services',
                            conditions={'method': ['GET']})
        self.router = middleware.RoutesMiddleware(self.dispatch, self.mapper)  # 创建实例,调用的时候进行路由匹配,修改环境变量

    @webob.dec.wsgify
    def __call__(self, req):
        urll = ['%s : %s' % (k, v) for k, v in sorted(req.environ.items())]
        print('\n'.join(urll))  # 原始的环境变量
        return self.router

    @staticmethod
    @webob.dec.wsgify
    def dispatch(req):
        urll = ['%s : %s' % (k, v) for k, v in sorted(req.environ.items())]
        print('\n'.join(urll))  # 从这里可以看出来环境变量已经改变了
        match = req.environ['wsgiorg.routing_args'][1]

        if not match:
            return webob.exc.HTTPNotFound()

        app = match['controller']
        return app

上一篇: python WSGI接口

下一篇: Python中的WSGI