Hello, WSGI
admin
2023-07-31 01:51:09
0

最新的工作中,有一部分HTTP API的任务,于是开始折腾Python WSGI…

WSGI

先恶补理论吧,关于Python WSGI有2篇PEP需要看,PEP 0333和PEP 3333,前者是2003年的提案,后者在2010年对前者做了小幅修订,提案状态也已经是“Final”,所以已经不是“提案”,已经是协议规范了;

WSGI,是“Python Web Server Gateway Interface”的缩写,解决的是各种Web Server(比如Apache、Nginx)与各种Python Web框架(比如Flask、Tornado)之间互联互通的兼容性问题;

如PEP中描述,在没有一个统一协议规范以前,某个Python应用(Web框架、或者应用程序),可能仅支持运行在某一个Web Server下,应用开发者选择某个Web框架的同时,也就绑死了某个Web Server;另外,在某个Web框架写的应用代码,迁移到另外一个Web框架,不一定能跑起来;所以,为了能让用户自由选择、组合使用任意的Web框架和Web Server,该PEP规范了必要的交互方式和数据结构;

注意,WSGI不是一个软件工具,它是一种协议规范的描述,它规范了“交互方式和数据结构”,任何Web Server、Gateway和Framework、Application,只要遵从这个规范去实现,就一定能互联互通;既然是“交互”,就一定至少包含两方吧,PEP指出:

  • the \”server\” or \”gateway\” side(下文称为“server端”)
  • the \”application\” or \”framework\” side(下文称为“application端”,framework本质上也是一种应用)

“application端”,必须提供一个“可调用的对象”供“server端”调用,“可调用的对象”一般是个入口函数,应用对HTTP请求的处理,要在这个入口函数内完成,函数最终返回HTTP Respone,比如生成的HTML;

下面的示例摘自PEP 3333:

pythonHELLO_WORLD = b\"Hello world!\\n\"

def simple_app(environ, start_response):
    \"\"\"Simplest possible application object\"\"\"
    status = \'200 OK\'
    response_headers = [(\'Content-type\', \'text/plain\')]
    start_response(status, response_headers)
    return [HELLO_WORLD]

“server端”,一般就是Web Server啦,最主要的任务就是接受到HTTP请求后,调用“application端提供的入口函数(比如上面的“simple_app”),另外应用程序里可能需要很多HTTP请求的信息(比如HTTP Method,GET/POST),这些信息,如何获取呢?需要“server端”在调用应用入口函数的时候作为函数参数传递,就是上面的“environ”,关于“environ”这个数据结构的规范,PEP中也是有详细描述的;

关于“server端”实现的实例代码,稍稍复杂一点,搬运到这里,也不见得帮助理解,自行到PEP 3333查阅吧;

关于Python WSGI的理论介绍,最核心的都在这儿了,更细节的协议介绍,自行查阅吧;

Quick Start

好了,终于可以动手实践了,早已按耐不住啦!我们先把上面的“simple_app”跑起来吧;

bash$ touch simple_app.py
$ vim simple_app.py

HELLO_WORLD = b\"Hello world!\\n\"

def application(environ, start_response):
    \"\"\"Simplest possible application object\"\"\"
    status = \'200 OK\'
    response_headers = [(\'Content-type\', \'text/plain\')]
    start_response(status, response_headers)
    return [HELLO_WORLD]

好了,“application端”已经好了,那“server端”呢?我们需要搞来一个实现了Python WSGI的Web Server,这里,我选择了,uWSGI,不要被它的名字迷惑,它其实是一个功能非常全、实现了各种协议、支持各种的语言的“a full stack for building hosting services”,因为最早支持Python,所以取了这样一个名字,官方都说,名字已经支撑不起它的野心,哈哈;

本实践中,我们要基于Python安装uWSGI:

bash$ pip install uwsgi

根据你的Python安装路径,uWSGI的二进制程序安装路径也会不同,比我电脑上:

bash$ ls /usr/local/python2.7/bin/uwsgi

现在,“application端”和“server端”,都已经准备就绪了,我们可以启动的这个简单的WSGI应用了:

bashuwsgi --http :9090 --wsgi-file simple_app.py

uWSGI会到simple_app.py文件中,找一个固定名字“application”的入口函数,当uWSGI收到HTTP请求时,就会调用该入口函数;

你在浏览器请求http://127.0.0.1:9090,应该会看到uWSGI的输出:

bash$ uwsgi --http :9090 --wsgi-file simple_app.py

[pid: 1492|app: 0|req: 1/1] 127.0.0.1 () {34 vars in 626 bytes} [Sat Jun 20 15:32:14 2015] GET / => generated 11 bytes in 0 msecs (HTTP/1.1 200) 1 headers in 44 bytes (1 switches on core 0)
[pid: 1492|app: 0|req: 2/2] 127.0.0.1 () {36 vars in 615 bytes} [Sat Jun 20 15:32:14 2015] GET /favicon.ico => generated 11 bytes in 0 msecs (HTTP/1.1 200) 1 headers in 44 bytes (1 switches on core 0)

此时,你的浏览器应该也已经有“Hello World”页面输出,大功告成!

Learn More

本文的“Hello World”示例,仅仅是展示Python WSGI的框架结构,“server端”提供的HTTP请求信息“environ”完全没有使用,无脑返回一个不变的字符串;

真正的应用,是需要根据功能要求,定制、填充那个application的入口函数的,应用开发者,可以自己代码实现,也可以依托于一些流行的WSGI框架和Python模块,比如:Flask框架、werkzeug

“server端”就没有什么发挥的空间了,选择一个支持WSGI协议的就好了,就像本文尝试的uWSGI,除非你想自己实现个Web Server;Nginx虽然不直接支持WSGI,但它支持uWSGI,这样把Nginx挡在uWSGI前面,uWSGI就可以专门处理动态的WSGI请求了,形成的架构,非常类似于PHP场景下的Nginx+PHP-FPM;

这些方面的知识,也许会有后续的文章做介绍;

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...