Python 编写简易 Web 应用框架实战指南
写应用框架需要写底层服务器吗?
开发 Web 应用框架时,是否需要自己实现底层服务器取决于是否遵循标准。如果应用框架不参考 WSGI (Web Server Gateway Interface) 标准,那么确实需要定义一套属于自己的服务器协议。但这种方式通常不必要,专业的事情应该交给专业的工具来做。
我们将编写符合 WSGI 标准的框架,因此只需要引入符合该标准的服务器即可。
常见的 WSGI 服务器
- uWSGI:使用 C 语言编写的应用程序容器,具有广泛的应用场景。除了支持
WSGI外,还支持 HTTP、WebSocket 等协议。它提供了多进程、多线程、协程、异步 IO 等多种运行模式,并支持内存共享、定时任务、快速热部署等高级功能。 - Waitress:纯 Python 编写的轻量级、可靠且支持多线程的
WSGI服务器,适合运行 Python Web 应用。
本文将以 uWSGI 为例进行讲解。
uWSGI 基本使用
安装 uWSGI
在 Python 环境中,直接使用 pip 安装即可:
pip3 install uwsgi
配置 uWSGI
uWSGI 支持多种配置方式,可以直接在命令行指定参数,也可以写入配置文件。
命令行启动示例
uwsgi --http :8080 --wsgi-file myapp.py --callable app
配置文件启动
可以将上述命令写入 myapp.ini 文件中:
[uwsgi]
http = :8080
wsgi-file = myapp.py
callable = app
然后通过以下命令加载配置启动:
uwsgi --ini myapp.ini
此外,uWSGI 还支持 XML、YAML、JSON 等格式,甚至可以通过 URL 读取配置文件。
uWSGI 常用配置项
-
指定启动用户和用户组
uid=root gid=root生产环境建议不要使用 root 运行,应创建专用用户。
-
指定项目名称
project=myproject -
设置进程数 需要先开启 master 进程,再设置 worker 数量。一般建议进程数不超过 CPU 核数。
master=True process=4 -
设置对外 HTTP 地址 若需监听所有网卡,可设置为 0.0.0.0。
http=0.0.0.0:8000
启服和停服
启动服务器
直接运行命令或加载配置文件:
uwsgi --http :8080
# 或
uwsgi -ini app.ini
关闭服务器
通过向进程发送信号来关闭,对应的信号为 SIGINT (即 kill -2)。
kill -2 <uwsgi_pid>
启动一个 Demo
首先编写一个符合 WSGI 标准的应用程序。WSGI 接口要求应用接收两个参数:environ (字典,包含请求信息) 和 start_response (函数,用于设置响应状态和头)。
def application(environ, start_response):
status = "200 OK"
headers = [("Content-type", "text/html")]
start_response(status, headers)
return [b'Hello, World.']
将上述代码保存为 main.py,使用 uWSGI 启动:
uwsgi --http :8080 --wsgi-file main.py
启动后,可以使用 curl 测试:
curl -v 127.0.0.1:8080/
写一个简单的 Web 应用框架
基于 WSGI 标准,我们可以封装一个更简单的路由框架,将业务逻辑与服务器解耦。
框架核心代码
创建一个 myWeb.py 文件作为框架核心:
webRoute = {}
def application(environ, start_response):
path = environ.get('PATH_INFO', '/')
if path in webRoute:
func = webRoute[path]
# 调用业务函数,传入 environ
code, body = func(environ)
status = "%d OK" % (code)
headers = [("Content-type", "text/html")]
start_response(status, headers)
return [body.encode()]
else:
# 处理 404 错误
status = "404 Not Found"
headers = [("Content-type", "text/plain")]
start_response(status, headers)
return [b"Page not found"]
def Routes(path, func):
print("add routes: %s %s" % (path, func))
webRoute[path] = func
代码解析:
- 使用字典
webRoute存储路由映射关系,Key 为 URL 路径,Value 为处理函数。 application函数是 WSGI 入口,获取请求路径并在字典中匹配。- 若匹配成功,执行对应函数并根据返回值组合响应;若未匹配,返回 404。
Routes装饰器或辅助函数用于注册路由。
业务逻辑代码
创建 main.py 文件,引用框架并定义具体业务:
import myWeb
# 定义应用入口
app = myWeb.application
def index(environ):
return (200, "hello world")
def api_data(environ):
return (200, "api response data")
# 注册路由
myWeb.Routes("/index", index)
myWeb.Routes("/api", api_data)
运行框架
使用 uWSGI 启动我们编写的框架应用:
uwsgi --http :8080 --wsgi-file main.py --callable app
注意新增的配置项 --callable app,因为我们的入口函数名定义为 app 而不是默认的 application,所以需要显式指定。
启动后观察日志,可以看到路由注册信息:
add routes: /index <function index at ...>
add routes: /api <function api_data at ...>
验证请求:
curl http://127.0.0.1:8080/index
# 输出:hello world
curl http://127.0.0.1:8080/api
# 输出:api response data
curl http://127.0.0.1:8080/notfound
# 输出:Page not found
总结
本文介绍了基于 WSGI 标准使用 Python 编写简易 Web 应用框架的方法。通过理解 WSGI 接口规范(environ 和 start_response),我们可以将 Web 应用与底层服务器解耦。利用 uWSGI 作为服务器,配合自定义的路由框架,能够快速构建轻量级的 Web 服务。这种模式不仅适用于学习,也是理解 Flask、Django 等成熟框架底层原理的基础。
在实际生产中,建议结合 Gunicorn、Nginx 反向代理以及数据库连接池等组件,以构建高可用、高性能的 Web 系统。

