这是应用层第一篇文章,后面的几篇文章也都是和应用层有关的啦

前面我们讲了关于httpserver的内容,httpserver负责网络服务器部分的内容,通过application()函数将data发送到我们的Aapplication里面,这里的application也是一个类 这篇文章主要讲的app.py这个源代码里面的内容.

下面是application类关键部分的代码:
class Application(object):
    def __init__(self,handlers):
        self.add_handler(handlers)
    def __call__(self,req):
        self.Request = Request = req    
        requestrouter = RequestRouter(self.handlers,self.Request)
        return requestrouter.execute()
    def add_handler(self,host_handler):
        self.handlers =[]
        for spec in host_handler:
            if isinstance(spec, (tuple)):
                print spec
                spec  = URLSpec(*spec)
            self.handlers.append(spec)
            print self.handlers
            if spec.name:
                if spec.name in self.named_handlers:
                    print  "Multiple handlers named %s; replacing previous value"%spec.name
                self.named_handlers[spec.name]= spec
    def get_host_handlers(self):
        matches= []
        for pattern ,handlers in self.handlers:
            matches.extend(handlers)
        return matches or None

这个application类是应用层的核心部分,首先解释一下结果函数的作用:

  1. init() 调用add_handler()函数,而这个函数的作用就是用来注册 路由-处理方法

  2. call()这里重写了Python类里面的call函数,在实例化类后,可以直接调用把类当做一个函数调用,application(request)的其实本质上调用的就是这里的call(),我们可以注意到这个call()函数其实非常重要的一个函数, 它是一个请求在应用层的开始.

call()函数一开始实例了一个requestrouter的类,顾名思义,这个类就是包含了路由解析的功能的,一个请求过来,经过路由匹配,成功之后找到对应的处理类,我们定义了每一个处理的类都是继承一个基类BaseReqest()的,匹配成功后会实例对应的处理类,同时执行_excute()方法,执行这个方法的目的是因为:一个处理类用户可以定义很多种方法,而使用_execute()方法可以根据请求的method来执行对应的处理函数.整个应用层路由解析部分的内容大致就是这样的.

下面来看下前面提到的requestrouter类和baserequest的代码:

class RequestRouter(object):
    def __init__(self,handlers,request):
        self.handlers =handlers
        self.request = request
        self.handler_class = None
        self.handler_kwargs = {}
        self.path_args = []
        self.path_kwargs = {}
        print self.request.path()
        self.find_handler()

    def find_handler(self):
        handlers = self.handlers
        if not handlers:
            self.handlers_class = RedirectHandler
            #self.handler_kwargs  = {}
            return
        for spec in handlers:
            match  = spec.regex.match(self.request.path())
            print self.request.path()
            print match
            if match !=None:
                print spec
                self.handler_class = spec.handler_class
                self.handler_kwargs  = spec.kwargs
                if spec.regex.groups:
                    if spec.regex.groupindex:
                        self.path_kwargs = dict(
                            (str(k), _unquote_or_none(v))
                            for (k,v) in match.groupdict().item())
                    else:
                        self.path_kwargs = [_unquote_or_none(s)
                                                for s in match.groups()]
                return



    def execute(self):
        if self.handler_class !=None:
            self.handler = self.handler_class(self.request,**self.handler_kwargs)
            return self.handler._excute(*self.path_args,**self.path_kwargs)
        else:
            print 'app 149  '
            error  = HttpError('404 ','not foound you request page ')
            return error()
class BaseRequest(object):
    Default_Method = ["GET","POST", "DELETE","PUT"]
    def  __init__(self,request,**kwargs):
        super(BaseRequest, self).__init__()
        self.request = request
        self.status_code ='200 OK'
        self.header = []
    def _excute(self,*args,**kwargs):
        print 'steart _execute'
        try:
            print self.request.method
            if self.request.method() not in self.Default_Method:
                error= HttpError('405 Method Not Allowed','Invalid method')
                return error()

            self.path_args = [self.decode_argument(arg) for arg in args]
            self.path_kwargs = dict((k, self.decode_argument(v, name=k))
                                        for (k, v) in kwargs.items())

            method = getattr(self,self.request.method().lower())
            print 'get method ...........'
            result = method (*self.path_args,**self.path_kwargs)
            print 'this is result ------.'
            print result
            if result is not None:
                return result
        except Exception as e:
            error= HttpError('500 Internal Server Error','some error in server ')

            print 'Exception in handler excute'
            return error()

    def decode_argument(self, value, name=None):
        try:
            return to_unicode(value)
        except UnicodeDecodeError:
            error =  HttpError('400 Bad Request', "Invalid unicode in %s: %r" %
                                (name or "url", value[:40]))
            return error()
    def set_status_code(self,code):
        self.status_code = code
    def set_header(self,key,value):
        self.header.append((key,value))
    def set_cookie(self,value):
        self.header.append(('Cookie',value))
    def Response(self,result):
        results = (self.status_code,self.header,result)
        return results

看完了这个两个类的代码再来重新看一下掌心宝似的call()函数

    def __call__(self,req):
        self.Request = Request = req    
        requestrouter = RequestRouter(self.handlers,self.Request)
        return requestrouter.execute()

可以看出requestrouter类和baserequest这两个类基本都是为这个call()函数服务的.

同时也看到baserequest这个类封装了一些基本的方法,set_header,set_cookie()等,后面会根据需求进行扩展. Response()这个函数是用来返回处理结果的.也可以重新写过增加框架的灵活性.对app.py代码的介绍差不多就这样了,app.py里面里的工具类可能比较多(其实是我懒没有写多少)就不一一把代码贴出来了,那样子意义不大.

下一篇主要讲一下,我们这个平台的main.py代码,一看就知道是干嘛用的啦,这个当然使我们启动的整个平台的入口程序



Copyright © 2019 outshineamaze.
All rights reserved.

results matching ""

    No results matching ""