原标题:从零开始:写一个简单的Python框架
Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。
你为什么想搭建一个Web框架?我想有下面几个原因:
有一个新奇的想法,将会取代其他框架。
获得一些疯狂的街头信誉。
你的问题比较独特,现有的框架不适合。
你想成为一位更好的Web开发者,你对Web框架是如何运行的感到好奇。
我将集中精力在最后一点上。这篇文章旨在描述我从写一个小型的服务框架中学到了什么,我将解释框架的设计,以及如何一步一步,一个函数一个函数的实现这个框架的。关于此项目完整的代码可以点击此链接。
我希望我的行为可以鼓励大家去尝试因为真的非常有趣,我们可以从中学到很多关于web应用程序是如何工作的知识,而且比我想象的要容易的多。
范围
框架的功能有:请求-响应周期、身份验证、数据库访问、模板的生成等。Web开发者使用框架,因为大多数Web应用程序共享大量的相同功能,并且没必要为每个项目都重新实现这些功能。
像Rails或Django这些较大的框架做了高层次的抽象并且功能完备。这些框架经历了很长时间来完成所有这些特性,因此,我们重点完成一个微型框架。开始写代码前,我先列一下这个微型框架的功能及一些限制。
功能:
可以处理GET和POST的HTTP请求。从该WIKI中你可以了解获得关于HTTP简介。
异步的(我喜欢Python3 asyncio这个模块)。
包含简单的路由逻辑,以及参数捕获。
像其他酷的微框架一样,提供简单的用户级API。
可以处理身份验证,因为学会会非常的酷(在第2部分介绍)。
限制:
仅完成HTTP/1.1协议的一小部分:不实现transfer-encoding, http-auth, content-encoding (gzip), persistant connections(持久连接)这些功能。
响应信息中无MIME-guessing,用户将不得不手动设置。
无WSGI-只是简单的TCP连接处理。
不支持数据库。
我决定用一个小的用例来使上面的需求更具体,同样可以演示这个框架的API:
用户应该能够定义几个异步函数返回字符串或响应对象,然后用表示路由的字符串与这些函数配对,最后通过一个函数调用(start_server)开始处理请求。
有了这些设计后,我需要编码来实现这些抽象:
一个可以接受TCP连接和进度的异步函数。
将原始文本解析成某种抽象的容器。
某种机制,可以确定每个请求,哪个函数应该被调用。
将上面所有的集合在一起并提供一个简单的接口给开发者。
我针对每个功能点开始写一些必要的抽象描述。在几次重构后,页面布局被分成几个部分。每部分是相对独立的,这种情况下特别好,因为每一部分都可以自行研究学习。这些是我上面列出的抽象的具体体现:
一个HTTPServer对象,需要一个Router对象和一个http_parser模块,并使用他们来初始化。
HTTPConnection对象,每个表示一个单独的客户端HTTP连接并且处理请求-响应周期:使用http_parser模块解析进来的字节流到一个Request对象;使用一个Router实例找到正确的函数调用产生一个响应;最后将这个响应发送回客户端。
一对Request和Response对象提供给用户一种友好的方式来处理本质上是字节流的字符串形式。用户不必了解正确的信息格式或分隔符。
一个Router对象,包含路由功能:函数对。它提供一种增加这些函数对的方法,并且提供了一种给定URL路径,找到对应函数的方法。
最后,一个包含配置文件的App对象,并使用它来实例化一个HTTPServer实例。
让我们仔细分析每一部分,从HTTPConnection开始。
模拟异步连接
为了满足限制(约束),每个HTTP请求是一个单独的 TCP 连接。这会导致请求处理变慢,因为建立多个TCP连接(DNS查询消耗,TCP三次握手消耗,慢启动等