最近学习了有关WSGI规则,遵循这一规则来编写一个Python框架----使用wsgiref模块。
1.wsgiref模块创建服务
? ?响应动态请求。
from wsgiref import simple_server
def hello_app(environ,start_reponse):
# 在 start_response 中传入响应状态行 - 响应头
start_reponse('200 OK',[('Content-type','text/html')])
content = "Hello world"
print(environ)
return [content.encode('utf-8')]
# 创建服务
server = simple_server.make_server('',8008,hello_app)
print("服务器在端口号8008下进行监听......")
# 启动服务
server.serve_forever()
2.处理web请求和响应
? ?environ打印的数据太乱,可通过webob模块按行进行处理。
from wsgiref import simple_server
from webob import Request,Response
def hello_app(environ,start_reponse):
# 将请求信息按行进行处理
req = Request(environ)
print(req)
# 在start_response中传入响应状态行 - 响应头
# start_response("200 OK",[("Content-type","text/html")])
# content = "Hello world"
# return [content.encode("utf-8")]
response = Response(body='hello world!')
return response(environ,start_reponse)
# 创建服务
server = simple_server.make_server('',8008,hello_app)
print("服务器在端口号8008下进行监听......")
# 启动服务
server.serve_forever()
3.路由分发
? ?方便多个地址进行。
from wsgiref import simple_server
from webob import Request,Response
from selector import Selector
def hello_app(environ,start_reponse):
# 将请求信息按行进行处理
req = Request(environ)
# ------------------------------------
# 不适用 webob 模块自己封装响应头和响应体
# 在 start_response 中传入响应状态行 - 响应头
# start_reponse('200 OK',[('Content-type','text/html')])
# content = "hello world"
# 输出,根据 wsgi 协议,返回的需要是一个迭代器,返回一个 list 就可以
# return [content.encode('utf-8')]
# ------------------------------------
response = Response(body='hello world!')
return response(environ,start_reponse)
# '/cart'
def cart_app(environ,start_reponse):
response = Response(body='next page')
return response(environ, start_reponse)
# '/handle_favicon'
def handle_favicon(environ,start_reponse):
response = Response(body='')
return response(environ, start_reponse)
# 自定义 404 页面
def page404(environ,start_reponse):
response = Response(body='404 not found')
return response(environ, start_reponse)
# 路由分发 - selector
app = Selector()
app.add('/favicon.ico',GET=handle_favicon)
app.add('/next',GET=cart_app)
app.add('/',GET=hello_app)
# 如果他请求了一个非法的路径-404
app.status404 = page404
# 创建服务
server = simple_server.make_server('',8008,app)
print("服务器在端口号8008下进行监听......")
# 启动服务
server.serve_forever()
4.装饰器将请求响应与业务处理分离开
? ?这里使用装饰器可简化代码。
from wsgiref import simple_server
from webob import Request,Response
from selector import Selector
# 装饰器 - 不改变函数的名字,对函数的功能进行扩展
def wsgi_decorator(func):
def new_func(environ,start_reponse):
# 使用 Request 统一处理一下 environ
request = Request(environ)
# 调用一下传入的 func
response = func(request)
return response(environ,start_reponse)
new_func.__name__ = func.__name__
new_func.__doc__ = func.__doc__
return new_func
@wsgi_decorator
def hello_app(request):
# # 将请求信息按行进行处理
# req = Request(environ)
# ------------------------------------
# 不适用 webob 模块自己封装响应头和响应体
# 在 start_response 中传入响应状态行 - 响应头
# start_reponse('200 OK',[('Content-type','text/html')])
# content = "hello world"
# 输出,根据 wsgi 协议,返回的需要是一个迭代器,返回一个 list 就可以
# return [content.encode('utf-8')]
# ------------------------------------
# response = Response(body='hello world!')
# return response(environ,start_reponse)
return Response(body='hello world!')
@wsgi_decorator
def cart_app(request):
return Response(body='next page')
@wsgi_decorator
def handle_favicon(request):
return Response(body='')
@wsgi_decorator
def page404(request):
return Response(body='404 not found')
# 路由分发 - selector
app = Selector()
app.add('/favicon.ico',GET=handle_favicon)
app.add('/next',GET=cart_app)
app.add('/',GET=hello_app)
# 如果他请求了一个非法的路径-404
app.status404 = page404
# 创建服务
server = simple_server.make_server('',8008,app)
print("服务器在端口号8008下进行监听......")
# 启动服务
server.serve_forever()
逻辑分析:先找到路由--->函数(函数由装饰器扩展)---->传入函数到装饰器中func=函数--->用Request统一处理---->将所有的environ和start_response存放在一个新的函数中方便调用。
以上是我对于该框架建立的一个逻辑总结,方便自己理解。
|