MoR03r MoR03r's Blog
打造python web 框架(三): Python WSGI架构升级
发表于 2017-2-7 | 综合

本文主要讲web框架架构会有两种形式,一种装饰器和另外一种正则表达式实现路由。

装饰器

创建WSGI服务类

class WSGIapp(object):  
# 初始化路由routes  
def __init__(self):  
    self.routes = {}  
# routes 装饰器  
def route(self,path=None):  
    def decorator(func):  
        self.routes[path] = func  
        return func  
    return decorator  
# 执行wsgi方法,进行路由验证  
def __call__(self,environ,start_response):  
    print 'call'  
    return self.wsgi(environ,start_response)

def wsgi(self,environ,start_response):  
    path = environ['PATH_INFO'] # 获取路由地址  
    print path  
    if path in self.routes:  
        status = '200 OK' # 返回状态200  
        response_headers = [('Content-Type','text/plain')]  
        start_response(status,response_headers)  
        print self.routes[path]()  
        return self.routes[path]() # 进行路由跳转  
    else:  
        status = '404 Not Found' # 访问当前地址不在路由数组里返回404  
        response_headers = [('Content-Type','text/plain')]  
        start_response(status,response_headers)  
        return '404 Not Found!'

进行路由跳转

app = WSGIapp() # 创建对象  
app.route('/') # 创建路由  
def index(): # 方法名不能重复  
    return ['This is index'] # 返回信息

@app.route('/hello') # 创建路由  
def hello():  
    return ['hello'] # 返回信息

启动服务

from wsgiref.simple_server import make_server  
httpd = make_server('',8000,app)  
print 'start....'  
httpd.serve_forever()

完整代码

class WSGIapp(object):

def __init__(self):  
    self.routes = {}

def route(self,path=None):  
        def decorator(func):  
                self.routes[path] = func  
                return func  
        return decorator

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

def wsgi(self,environ,start_response):  
        path = environ['PATH_INFO']  
        print path  
        if path in self.routes:  
                status = '200 OK'  
                response_headers = [('Content-Type','text/plain')]  
                start_response(status,response_headers)  
                print self.routes[path]()  
                return self.routes[path]()  
        else:  
                status = '404 Not Found'  
                response_headers = [('Content-Type','text/plain')]  
                start_response(status,response_headers)  
                return '404 Not Found!'

app = WSGIapp()  
@app.route('/')  
def index():  
        return ['This is index']

@app.route('/hello')  
def hello():  
        return ['hello']

from wsgiref.simple_server import make_server  
httpd = make_server('',8000,app)  
print 'start....'  
httpd.serve_forever()

运行

正则

创建WSGI服务类

import re #导入模块

class WSGIapp:  
    headers = []

    def __init__(self,urls=()):  
        self.urls = urls  
        self.status = '200 OK'

    def __call__(self,environ,start_response):
        x = self.mapping_urls(environ)  
        start_response(self.status,self.headers)

        if isinstance(x,str):  
            return iter([x])  
        else:  
            return iter(x)

    def mapping_urls(self,environ): # 进行正则路由查找  
        path = environ['PATH_INFO'] # 获取路由地址

        for pattern,name in self.urls:  
            m = re.match('^'+pattern+'$',path)  
        if m:  
            args = m.groups()  
            func = globals()[name]  
            return func(*args)  
        return self.notfound()

    def notfound(self): # 找不到返回404  
        self.status = '404 Not Found'  
        self.headers = [('Content-Type','text/plain')]  
        return '404 Not Found\n'

    @classmethod # 定义类方法  
    def header(cls,name,value):  
        cls.headers.append((name,value))

    进行路由跳转,定义方法,通过正则匹配

    def GET_index(*args):  
        WSGIapp.header('Content-Type','text/plain')  
        return 'Welcome!\n'

    def GET_hello(*args):  
        WSGIapp.header('Content-Type','text/plain')  
        return 'Hello %s!\n' % args

    urls = [  
    ('/','GET_index'),  
    ('/hello/(.*)','GET_hello')  
    ]

    wsgiapp = WSGIapp(urls)

启动服务

if __name__ == '__main__':  
    from wsgiref.simple_server import make_server  
    httpd = make_server('',8000,wsgiapp)  
    print 'server starting...'  
    httpd.serve_forever()

完整代码

import re

class WSGIapp:  
    headers = []

    def __init__(self,urls=()):  
        self.urls = urls  
        self.status = '200 OK'

    def __call__(self,environ,start_response):
        x = self.mapping_urls(environ)  
        print x  
        start_response(self.status,self.headers)

        if isinstance(x,str):  
            return iter([x])  
        else:  
            return iter(x)

    def mapping_urls(self,environ):  
        path = environ['PATH_INFO']

        for pattern,name in self.urls:  
            m = re.match('^'+pattern+'$',path)  
        if m:  
            args = m.groups()  
            func = globals()[name]  
            return func(*args)  
        return self.notfound()

    def notfound(self):  
            self.status = '404 Not Found'  
            self.headers = [('Content-Type','text/plain')]  
            return '404 Not Found\n'

    @classmethod  
    def header(cls,name,value):  
            cls.headers.append((name,value))

    def GET_index(*args):  
            WSGIapp.header('Content-Type','text/plain')  
            return 'Welcome!\n'

    def GET_hello(*args):  
            WSGIapp.header('Content-Type','text/plain')  
            return 'Hello %s!\n' % args

    urls = [  
    ('/','GET_index'),  
    ('/hello/(.*)','GET_hello')  
    ]

    wsgiapp = WSGIapp(urls)

if __name__ == '__main__':  
    from wsgiref.simple_server import make_server  
    httpd = make_server('',8000,wsgiapp)  
    print 'server starting...'  
    httpd.serve_forever()

运行

*文章转自微信公众号inn0team

TOP