内容简介:Bottle源码阅读笔记(一):WSGI
前言
Bottle是一个Python Web框架。整个框架只有一个文件,不到4k行的代码,没有 Python 标准库以外的依赖,却包含了路由、模板和插件等Web框架常用功能。通过阅读Bottle源码来了解什么是Web框架和Web框架是怎么工作是再合适不过了。由于Bottle是一个支持WSGI的框架,在阅读源码之前,我们先来了解什么是WSGI。
注意:文中使用的Bottle版本为0.12.13。
WSGI
一般的Web服务器只能处理静态页面。如果涉及到动态内容,服务器就需要与Java/Python/Ruby等服务器语言进行交互,将内容交给它们处理。由于大多数的Web服务器都是用C写,它们不能直接执行服务器语言,所以两者之间需要一座桥(在实际应用中,通常会在Web服务器和WSGI应用中间添加一个应用服务器来支持WSGI)。而在Python中,WSGI就是这么一座桥。WSGI的实现分两个部分,一是服务器,二是应用程序。下面来看一看它们各自是什么样子的,以及两者之间是如何协作的。
1 class Server: 2 3 def __init__(self, server_address): 4 self.server_address = server_address 5 6 def set_app(self, application): 7 self.app = application 8 9 def serve_forever(self): 10 while True: 11 # socket.accept() 12 if request_comein(): 13 self.handle_request() 14 15 def handle_request(self): 16 request_data = self.get_request() 17 self.parse_request(request_data) 18 environ = self.get_environ() 19 result = self.application(environ, self.start_response) 20 self.send_response(result) 21 22 def start_response(self, status, headers, exc_info): 23 pass 24 25 def get_environ(self): 26 pass 27 28 def get_request(self): 29 pass 30 31 def parse_request(self, text): 32 pass 33 34 def send_response(self, message): 35 pass 36 37 38 def make_server(host, port, app, server=Server): 39 server = server((host, port)) 40 server.set_app(app) 41 return server 42 43 def simple_app(environ, start_response): 44 status = '200 OK' 45 response_headers = [('Content-type', 'text/plain')] 46 start_response(status, response_headers) 47 return 'Hello World!' 48 49 if __name__ == '__main__': 50 server = make_server('localhost', 8080, simple_app) 51 server.serve_forever()
限于篇幅,这个服务器模型省略了很多细节,如果你想要一个简单又能运行的WSGI服务器,可以参考这里 Let's Build A Web Server.Part 2. 。
服务器在接收到请求后,对请求报文的信息进行解析,结果保存在一个名为environ的字典中。随后以environ与处理头信息的start_response函数作为参数,调用应用程序 application(environ, start_response) 。最后将应用的结果组成新的响应,发送回客户端。
在应用程序方面,WSGI应用是一个可调用的对象。它可以是一个函数,方法,类,或者是一个带有 __call__
方法的实例。上面的应用就是一个函数。
当各种服务器和应用程序/框架都按照WSGI的标准进行开发时,我们可以根据需求自由地组合不同的服务器和框架。
Bottle最简应用
在简单了解完WSGI后,我们回到Bottle,来观察一个Bottle应用是什么样子的,如何运行,跟我们的模型有什么区别。
1 from bottle import Bottle, run 2 3 app = Bottle() 4 5 @app.route('/hello') 6 def hello(): 7 return 'Hello World!' 8 9 run(app, host='localhost', port=8080, server='wsgiref')
现在运行这个程序,用浏览器访问地址'localhost:8080/hello'就会看到'Hello World!'。
1. 与上面的应用不同,Bottle应用是一个实例。按照WSGI规定,Bottle对象要实现__call__方法:
1 def __call__(self, environ, start_response): 2 ''' Each instance of :class:'Bottle' is a WSGI application. ''' 3 return self.wsgi(environ, start_response)
所以这个Bottle.wsgi方法就是服务器调用Bottle应用的入口,同时也是我们阅读源码的入口。
2. @app.route()这个装饰器将一个函数绑定到一个URL上。当我们访问'localhost:8080/hello'时,hello函数就会被调用。
3. Bottle默认的服务器是wsgiref(Python标准库里的一个WSGI简单实现)。当然Bottle还为许多服务器编写了适配器(Adapter),只需要改变server的值,run()函数会根据服务器的名字寻找相应的适配器。无需编写额外的代码。
run函数和适配器部分代码:
1 def run(app=None, server='wsgiref', host='127.0.0.1', port=8080, 2 interval=1, reloader=False, quiet=False, plugins=None, 3 debug=None, **kargs): 4 if server in server_names: 5 server = server_names.get(server) 6 if isinstance(server, basestring): 7 server = load(server) 8 if isinstance(server, type): 9 server = server(host=host, port=port, **kargs) 10 if not isinstance(server, ServerAdapter): 11 raise ValueError("Unknown or unsupported server: %r" % server) 12 ... 13 server.run(app) 14 15 class MeinheldServer(ServerAdapter): 16 def run(self, handler): 17 from meinheld import server 18 server.listen((self.host, self.port)) 19 server.run(handler)
最后
在本文中,我们简单介绍了在WSGI标准下服务器和应用如何进行交互。下一篇,我们继续围绕这个最简应用,讲讲与@app.route()有关的路由功能。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
An Introduction to Genetic Algorithms
Melanie Mitchell / MIT Press / 1998-2-6 / USD 45.00
Genetic algorithms have been used in science and engineering as adaptive algorithms for solving practical problems and as computational models of natural evolutionary systems. This brief, accessible i......一起来看看 《An Introduction to Genetic Algorithms》 这本书的介绍吧!