零基础小白必看篇:从0到1构建Python Web框架

造轮子是最好的一种学习方式,本文尝试从0开始造个Python Web框架的轮子,我称它为ToyWebF。

本文操作环境为:MacOS,文中涉及的命令,请根据自己的系统进行替换。

ToyWebF的简单特性:

  • 1.支持多种不同形式的路由注册方式

  • 2.支持静态HTML、CSS、JavaScript

  • 3.支持自定义错误

  • 4.支持中间件

下面我们来实现这些特性。

 

最简单的web服务

首先,我们需要安装gunicorn,回忆一下Flask框架,该框架有内置的Web服务器,但不稳定,所以上线时通常会替换成uWSGI或gunicorn,这里不搞这个内置Web服务,直接使用gunicorn。

这里多说一句,小编是一名python开发工程师,这里有我自己整理的一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以关注小编,并在后台私信小编即可领取。

我们创建新的目录与Python虚拟环境,在该虚拟环境中安装gunicorn

 
 

mkdir ToyWebF python3 -m venv venv # 创建虚拟环境 source venv/bin/activate #激活虚拟环境 pip install gunicorn 复制代码

在啥都没有的情况下,构建最简单的Web服务,在ToyWebF目录下,创建app.py与api.py文件,写入下面代码。

 
 

# api.py 文件 class API: def __call__(self, environ, start_response): response_body = b"Hello, World!" status = "200 OK" start_response(status, headers=[]) return iter([response_body]) # app.py 文件 from api import API app = API() 复制代码

运行gunicorn app:app访问http://127.0.0.1:8000,可以看见Hello, World!,但现在请求体中的参数在environ变量中,难以解析,我们返回的response也是bytes形式。

 

 

 

我们可以使用webob库,将environ中的数据转为Request对象,将需要返回的数据转为Response对象,处理起来更加直观方便,直接通过pip安装一下。

 
 

pip install webob 复制代码

然后修改一下API类的__call__方法,代码如下。

 
 

from webob import Request, Response class API(object): def wsgi_app(self, environ, start_response): """通过 webob 将请求的环境信息转为request对象""" request = Request(environ) response = self.handle_request(request) return response(environ, start_response) def __call__(self, environ, start_response): self.wsgi_app(environ, start_response) 复制代码

上述代码中,通过webob库的Request类将environ对象(请求的环境信息)转为容易处理的request,随后调用handle_request方法对request进行处理,处理的结果,通过response对象返回。

handle_request方法在ToyWebF中非常重要,它会匹配出某个路由对应的处理方法,然后调用该方法处理请求并将处理的结果返回,在解析handle_request前,需要先讨论路由注册实现,代码如下。

 
 

class API(object): def __init__(self): # url路由 self.routes = {} def route(self, path): # 添加路由的装饰器 def wrapper(handler): self.add_route(path, handler) return handler return wrapper def add_route(self, path, handler): # 相同路径不可重复添加 assert path not in self.routes, "Such route already exists" self.routes[path] = handler 复制代码

其实就是将路由和方法存到self.routes字典中,可以通过route装饰器的形式将路由和方法关联,也可以通过add_route方法关联,在app.py中使用一下。

 
 

app = API() # 通过装饰器关联路由和方法 @app.route("/home") def home(request, response): response.text = "This is Home" # 路由中可以有变量,对应的方法也需要有对应的参数 @app.route("/hello/{name}") def hello(requst, response, name): response.text = f"Hello, {name}" # 可以装饰类 @app.route("/book") class BooksResource(object): def get(self, req, re

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值