功能类型 | 代表名称 |
---|---|
程序接受、响应信息以及运行 | app.run() |
路由以及视图函数处理 | app.way(‘/‘,methods=[‘GET‘]) |
请求处理 | request |
全局变量 | g |
会话 | session |
模板以及渲染模板 | template |
静态文件以及返回静态文件 | static |
全局current_app | current_app |
原理库 | 函数 |
---|---|
werkzeug.serving | run_simple |
werkzeug.wrappers | Request,Response |
werkzeug.routing | Map,Rule |
werkzeug.utils | redirect |
werkzeug.wsgi | SharedDataMiddleware |
jinja2 | Environment,FileSystemLoader |
itsdangerous | TimedJSONWebSignatureSerializer |
werkzeug.local | LocalProxy,LocalStack |
os | / |
在Freedom类中定义程序运行函数fly(),fly()使用run_simple函数进行接口设置,之后每次与服务器的交互都会调用wsgi_app函数,然后会调用下列两个主要函数最后返回响应
wsgi_app->dispatch_request->make_response->Response
wsgi_app函数将服务器传输的environ信息封装到Request、Response中,进行和request相关的工作后调用dispatch_request
dispatch_request函数主要进行查找请求中对应的路由信息并调用路由函数,将返回值再输入make_response函数中进行简单处理以及建立session到响应中,再返回处理后的响应
在Freedom类__init__中调用Map实例化url_map用于储存路由Rule中的相关信息,再建立初始化一个字典view_functions用于存储函数名与函数的对应关系。
Freedom类中注册路由的函数是register_url需要路由、该路由下函数名、该路由下函数、访问方法参数,register_url中实例化了Rule并将实例加入到url_map中,将函数名与函数对应传入到view_functions,调用register_url就可以创建路由。
我模仿flask也在register_url函数上加上了一个装饰器,装饰器名为way接受路由以及方法作为参数,在way中默认方法为GET,之后会传入函数作为参数调用decorator函数,decorator函数再调用register_url注册路由后返回被输入的函数。
最后提供给用户的视图函数等的形式就是下面这个样子
当与服务器交互时,调用dispatch_request函数从request中提取出请求的路由信息,再从view_functions中得到视图函数、执行视图函数,其中make_response函数是把视图函数的返回值按照分类封装到Response中返回响应,使得用户不用每次都要调用Response,再把响应返回给服务器,这就是我做的简单路由过程。
对这四个的处理在ctx模块和globals模块中,ctx模块中主要分为AppContext类和RequestContext类两个部分,globals模块中调用了LocalProxy,LocalStack支持多线程以及队列操作。在ctx中RequestContext设置了request以及session的内容,AppContext设置了current_app以及g的内容
(1)globals模块
在globals模块中设置了两个栈request_stack、app_stack,然后分别从app_stack和request_stack类中提取出current_app、g以及request、session,在RequestContext的push中已经将对应的RequestContext和AppContext推入栈中,在golobals中提取提取信息函数如下方request方法:
分别将信息提取,将会给每个信息加上LocalProxy进行代理(看的意思似乎是为了不同线程保持独立),这样就可以从gobals中调用四个信息,进行相关的操作了。
(2)ctx模块
RequestContext
RequestContext中包括了request、session的内容,有push和pop方法,在RequestContext的__init__中初始化request将服务器传入的environ信息封装,引入Freedom的实例,再初始化url_adapter和session
在push中将request_stack、app_stack栈顶的信息更换进行信息的更新,并在此时创建session
在push中的session创建我采用了itsdangerous中的TimedJSONWebSignatureSerializer将__init__中初始化的session字典转换成token,push中的create_session函数从引入的app中调用search_session函数从栈顶的request的cookies中得到session编码后的token,编码session的函数是RequestContext的set_token函数,这个函数在Freedom类的dispatch_request函数中被调用并通过response的set_cookies将token建立在cookies中,这样就实现了session。
AppContext
AppContext用RequestContext差不多,先在__init__中初始化g以及引入app,然后AppContext中同样也有push以及pop方法,但AppContext还没有完善只有很少的功能
最初的模板在Freedom的__init__中初始化为文件夹tamplates,模板的设置我从jinja2中调用Environment,FileSystemLoader并jinja_env设置为文件夹tamplates的地址,这样就实现了默认的模板查询地址和存储地址,在Freedom中我设置了一个由用户自定义模板地址的函数set_templates,这个函数需要输入文件夹名作为参数
在Freedom中我也设置了一个渲染模板的函数drawing_template,这个函数从jinja_env中获取模板文件并渲染返回
关于静态文件的地址我再Freedom中建立了一个set_static函数,这个函数在__init__中会被调用并且初始化app_path文件保存地址,默认是static文件夹,用户可以通过这个函数设置提取和设置保存文件的文件夹。在这个函数中我设置了有一个提取文件的路由,之后通过SharedDataMiddleware设置返回静态文件。
在ctx的全局变量g,初始化时我将g初始化为一个空类的实例,但是仍然能实现全局变量的功能
原文:https://www.cnblogs.com/trainking-star/p/12986597.html