web框架总结

前提

一个web框架需要包含的组件或者功能有:

  1. router
  2. orm
  3. request and response
  4. cookies and session
  5. template engine
  6. wsgi app and wsgi server

wsgi

首先要了解WSGI的相关知识,如下:

  • web server:指的是软件程序,它从客户端接受请求,然后返回一个Response,需要注意的是它不创建Response,web app才是创建Response的主体。
  • web app:根据url来创建响应并将响应传回给web server。
  • WSGI:是一个规范,描述了web server如何与web app交互、web app如何处理请求,它规定每个app必须是一个可调用的对象(方法或者类),接受两个参数environ和start_response。

实现

web server

environ和start_response都是服务器提供的,所以服务端这边需要提供如下:

  1. 准备environ参数;
  2. 定义start_response函数;
  3. 调用程序端的可调用对象;

代码具体如下(取自PEP 333):

import os, sys
enc, esc = sys.getfilesystemencoding(), 'surrogateescape'
def unicode_to_wsgi(u):
# Convert an environment variable to a WSGI "bytes-as-unicode" string
return u.encode(enc, esc).decode('iso-8859-1')
def wsgi_to_bytes(s):
return s.encode('iso-8859-1')
def run_with_cgi(application):
# environ参数,里面是HTTP请求的环境变量
environ = {k: unicode_to_wsgi(v) for k,v in os.environ.items()}
environ['wsgi.input'] = sys.stdin.buffer
environ['wsgi.errors'] = sys.stderr
environ['wsgi.version'] = (1, 0)
environ['wsgi.multithread'] = False
environ['wsgi.multiprocess'] = True
environ['wsgi.run_once'] = True
if environ.get('HTTPS', 'off') in ('on', '1'):
environ['wsgi.url_scheme'] = 'https'
else:
environ['wsgi.url_scheme'] = 'http'
headers_set = []
headers_sent = []
# 将应答的数据输出到终端
def write(data):
out = sys.stdout.buffer
if not headers_set:
raise AssertionError("write() before start_response()")
elif not headers_sent:
# Before the first output, send the stored headers
status, response_headers = headers_sent[:] = headers_set
out.write(wsgi_to_bytes('Status: %s\r\n' % status))
for header in response_headers:
out.write(wsgi_to_bytes('%s: %s\r\n' % header))
out.write(wsgi_to_bytes('\r\n'))
out.write(data)
out.flush()
# 根据程序传过来的状态和头部参数设置响应的状态和头部
def start_response(status, response_headers, exc_info=None):
if exc_info:
try:
if headers_sent:
# Re-raise original exception if headers sent
raise exc_info[1].with_traceback(exc_info[2])
finally:
exc_info = None # avoid dangling circular ref
elif headers_set:
raise AssertionError("Headers already set!")
headers_set[:] = [status, response_headers]
return write
# 调用客户端的对象,并且输出返回的结果
result = application(environ, start_response)
try:
for data in result:
if data: # don't send headers until body appears
write(data)
if not headers_sent:
write('') # send headers now if body was empty
finally:
if hasattr(result, 'close'):
result.close()

web app

因为服务端和客户端需要共同遵守WSGI协议内容,所以客户端这边需要使用到服务端提供的environ和start_response,web app需要返回的类型需要是可迭代的。这里分为三种类型的实现,分别是函数,类,实例;

函数

HELLO_WORLD = b"Hello world!\n"
# 1. 可调用对象是一个函数
def application(environ, start_response):
# HTTP response code and message
status = '200 OK'
# 应答的头部是一个列表,每对键值都必须是一个 tuple。
response_headers = [('Content-Type', 'text/plain'),
('Content-Length', str(len(HELLO_WORLD)))]
# 调用服务器程序提供的 start_response,填入两个参数
start_response(status, response_headers)
# 返回必须是 iterable
return [HELLO_WORLD]

# 2. 可调用对象是一个类
class AppClass:
"""这里的可调用对象就是 AppClass 这个类,调用它就能生成可以迭代的结果。 使用方法类似于:
for result in AppClass(env, start_response):
do_somthing(result)
"""
def __init__(self, environ, start_response):
self.environ = environ
self.start = start_response
def __iter__(self):
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
self.start(status, response_headers)
yield HELLO_WORLD

实例

# 3. 可调用对象是一个实例
class AppClass:
"""这里的可调用对象就是 AppClass 的实例,使用方法类似于:
app = AppClass()
for result in app(environ, start_response):
do_somthing(result)
"""
def __init__(self):
pass
def __call__(self, environ, start_response):
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
self.start(status, response_headers)
yield HELLO_WORLD

Python web框架总结的更多相关文章

  1. python web框架——扩展Django&tornado

    一 Django自定义分页 目的:自定义分页功能,并把它写成模块(注意其中涉及到的python基础知识) models.py文件 # Create your models here. class Us ...

  2. 异步非阻塞IO的Python Web框架--Tornado

    Tornado的全称是Torado Web Server,从名字上就可知它可用作Web服务器,但同时它也是一个Python Web的开发框架.最初是在FriendFeed公司的网站上使用,FaceBo ...

  3. 微型 Python Web 框架 Bottle - Heroin blog

    微型 Python Web 框架 Bottle - Heroin blog 微型 Python Web 框架 Bottle

  4. Python Web框架

    本节对Python Web框架学习 一.MTVModel: 存放所有数据库相关文件Template:模板文件,存放html文件View: 业务处理,即函数文件 二.MVCmodel: 存放数据库相关文 ...

  5. 一步一步理解 python web 框架,才不会从入门到放弃

    要想清楚地理解 python web 框架,首先要清楚浏览器访问服务器的过程. 用户通过浏览器浏览网站的过程: 用户浏览器(socket客户端) 3. 客户端往服务端发消息 6. 客户端接收消息 7. ...

  6. 浅谈Python web框架

    一.Python web框架 Web Framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全 ...

  7. python web框架介绍对比

    Django Python框架虽然说是百花齐放,但仍然有那么一家是最大的,它就是Django.要说Django是Python框架里最好的,有人同意也有人 坚决反对,但说Django的文档最完善.市场占 ...

  8. “脚踢各大Python Web框架”,Sanic真有这能耐么?

    在Github上,Sanic第一句介绍语就是: "Sanic is a Flask-like Python 3.5+ web server that's written to go fast ...

  9. Python Web框架 tornado 异步原理

    Python Web框架 tornado 异步原理 参考:http://www.jb51.net/article/64747.htm 待整理

  10. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

随机推荐

  1. 【Android Developers Training】 21. 创建一个可变动的UI

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  2. java怎么处理json数据

    json = new JSONObject(data); int which = json.optInt("which", -1); String label = json.opt ...

  3. java的三大特性,封装,继承,多态

    封装 /** * 所谓封装,就是将对象具有的成员变量和成员函数包装和隐藏起来,让外界无法直接使用, * 被封装的成员只能通过某些特定的方式才能访问. * 实现封装有两个步骤: *   1.将不能暴露的 ...

  4. C++函数重载实现的原理以及为什么在C++中使用用C语言编译的函数时,要在函数名称前面加上extern "C"声明

    C++相对于C语言而言支持函数重载是其极大的一个特点,相信在使用C语言的时候大家如果要写一个实现两个整型数据相加的函数还要写一个浮点型数据相加的函数,那么这两个函数的名字绝对不可以一样,这样无疑在我们 ...

  5. window.getSelection和document.selection

    window.getSelection和document.selection   IE9以下支持:document.selection IE9.Firefox.Safari.Chrome和Opera支 ...

  6. H3CNE实验:配置VLAN和VLAN端口

    配置准备数据: | 设备名称 | IP地址 | VLAN网关 | 接口 | VLAN | |---------------|--------------|----------------|------ ...

  7. ionicangular 成长日记

    //首先配置文件ionic.bundle.min.jsionic.min.css" //创建一个angular控制器,控制器给body/html都可以angular.module('myap ...

  8. 数据结构(C语言版)顺序栈相关算法的代码实现

    这两天完成了栈的顺序存储结构的相关算法,包括初始化.压栈.出栈.取栈顶元素.判断栈是否为空.返回栈长度.栈的遍历.清栈.销毁栈.这次的实现过程有两点收获,总结如下: 一.清楚遍历栈的概念 栈的遍历指的 ...

  9. 集成 ssh第一阶段

    1.添加spring支持,包含spring-hibernate和spring-struts2.添加struts支持,包含struts-spring3.添加hibernate支持,在spring配置文件 ...

  10. 自定义事件解决重复请求BUG

    现在,组件化开发还是比较流行的,毕竟其优点相当突出.最近在开发一个组件的时候,遇到了一个很有意思的BUG... BUG的背景 最近在开发一个组件,好不容易开发好了转测试.然后,测试给我提了一个这样的b ...