当前位置: 首页 > news >正文

Python 的 WSGI 简单了解

从 flask 的 hello world 说起

直接讨论 WSGI,很多人可能没有概念,我们还是先从一个简单的 hello world 程序开始吧。

from flask import Flaskapp  = Flask(__name__)@app.route("/", methods=['GET'])
def index():return "Hello world!"if __name__ == '__main__':app.run(port=8000)

在这里插入图片描述

相信只要使用过 flask 框架或者其它 Python 框架的人,应该都会见过这个警告。这个警告的意思是:这是一个开发服务器。不要在生产环境使用它。使用一个生产的 WSGI 服务器来代替。

那么什么是 WSGI 呢?

WSGI is the Web Server Gateway Interface. It is a specification that describes how a web server communicates with web applications, and how web applications can be chained together to process one request.
WSGI 是 Web 服务器网关接口。它是一个规范,描述了web服务器如何与web应用程序通信,以及如何将web应用程序链接在一起以处理一个请求。

这里来看一个简略的时序图:
它描述了用户通过浏览器上网的过程,浏览器发送请求到 Server,Server 再把请求交给 Application 来处理,最后返回响应数据给用户的过程。(通常来说,请求在到达 Server 之前,还会先经过一个反向代理服务器,例如 nginx 或者 apache 等)
在这里插入图片描述
上面这个时序图其实可以看做是大部分网络应用程序的模式了。从请求到达应用和响应返回给用户,这个过程其实是固定的。所以,一个web应用的区别就在于它对请求的处理方式上,例如:用户使用百度、搜狗亦或是谷歌浏览器,对于用户的感知其实是相同的(尽管它们内部的实现并不相同,这里也不考虑用户的体验问题,哈哈)。

什么是 WSGI?

我们都知道通用的部分可以抽取出来,做成一个组件供其它应用使用。所以 WebServer 就是这样一个组件,它负责接收用户的请求,然后交给用户的Web应用,等到它处理完成之后,再把响应数据返回给调用者。所以,WebServer 要和 WebApplication 进行交互,那就需要定义一个协议或者更专业一点叫做接口,因此这就是 WSGI。而实现 WSGI 接口的,我们则成为 WebServer 或者 WSGI Server。

注:如果你有 java web 的背景,相信你应该使用过 tomcat,也听过 servlet API。其实,它们之间的关系和WSGI服务器与 WSGI接口的关系是类似的。

它的接口其实很简单,只要 Web 框架实现了它,就可以使用各种实现了 WSGI 接口的服务器了。
在这里插入图片描述
我们常用的 Web 框架有:falsk、django 等;WSGI 服务器有:gunicorn、uWSGI等。

对于我们入门学习来说,它其实也是很简单的,我们也不需要了解那么多。对于Web 框架的作者来说,他们需要提供一个带两个参数的可调用对象即可:

callable(environ, start_response)

下面是 Python 的 PEP3333 中提供的两个简单例子,一个是函数实现,一个是类实现,它们都是一个 Web Application。

HELLO_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]class AppClass:"""Produce the same output, but using a class(Note: 'AppClass' is the "application" here, so calling itreturns an instance of 'AppClass', which is then the iterablereturn value of the "application callable" as required bythe spec.If we wanted to use *instances* of 'AppClass' as applicationobjects instead, we would have to implement a '__call__'method, which would be invoked to execute the application,and we would need to create an instance for use by theserver or gateway."""def __init__(self, environ, start_response):self.environ = environself.start = start_responsedef __iter__(self):status = '200 OK'response_headers = [('Content-type', 'text/plain')]self.start(status, response_headers)yield HELLO_WORLD

Python 官方提供了一个简单的 WSGI 实现,我们就以上面这两个例子为例来演示一下:

from wsgiref.simple_server import make_serverif __name__ == '__main__':with make_server("127.0.0.1", 8000, simple_app) as httpd:print("Server started on port 8000...")httpd.serve_forever()

在这里插入图片描述
在这里插入图片描述

使用基于类的实现,效果也是一样的,通常更推荐使用类的方式,因为可以利用面向对象的思想来编程。

from wsgiref.simple_server import make_serverif __name__ == '__main__':with make_server("127.0.0.1", 8000, AppClass) as httpd:print("Server started on port 8000...")httpd.serve_forever()

甚至,我们还可以再进行一步,使用这个 Python 自带的 WSGI 服务来运行最开始的 flask 的 hello world:

from wsgiref.simple_server import make_serverfrom flask import Flaskapp  = Flask(__name__)@app.route("/", methods=['GET'])
def index():return "Hello world!"if __name__ == '__main__':with make_server("127.0.0.1", 8000, app) as httpd:print("Server started on port 8000...")httpd.serve_forever()

这样再次运行它,连警告也没有了。不过,自带的这个只是一个简单的实现,官方也并不推荐在生产环境使用它。但是 flask 其实并不知道,我们使用了什么 WSGI 服务器,因为它也不关心这个。

在这里插入图片描述

在这里插入图片描述

flask 背后的秘密

甚至不需要深入 flask 的源码,只需要浅浅的一探,我们就能明白为什么上面那样做的可以的了。这是 Flask 类的源码的一小部分,其它的无需解释了,我相信这是不言自明的。

class Flask(App):"""The flask object implements a WSGI application and acts as the centralobject.  """def wsgi_app(self, environ: WSGIEnvironment, start_response: StartResponse) -> cabc.Iterable[bytes]:...def __call__(self, environ: WSGIEnvironment, start_response: StartResponse) -> cabc.Iterable[bytes]:"""The WSGI server calls the Flask application object as theWSGI application. This calls :meth:`wsgi_app`, which can bewrapped to apply middleware."""return self.wsgi_app(environ, start_response)

总结

关于 WSGI,它的文档就直接说明了,对于 Web 开发者来说,其实并不用去了解它。因为我们的工作重点其实是请求的处理,对于我上面序列图中的大部分操作都不需要关系了,它隐藏了很多的细节,使得我们可以更加专注于自己的工作内容。不过,我觉得简单的了解一下也是蛮好的,也不需要深入的了解,浅尝辄止即可。对于我们工作的整个领域都有一个概览,然后还是专注于自己工作的重点内容上。

相关文章:

Python 的 WSGI 简单了解

从 flask 的 hello world 说起 直接讨论 WSGI,很多人可能没有概念,我们还是先从一个简单的 hello world 程序开始吧。 from flask import Flaskapp Flask(__name__)app.route("/", methods[GET]) def index():return "Hello world!&q…...

基于stm32使用ucgui+GUIBuilder开发ui实例

1 项目需求 1.1 基于Tft 触摸屏实现一个自锁按键 1.2 按键在按下后背景色需要进行变化,以凸显当前按键状态(选中or 未选中) 1.3 按键选中时对某一gpio输出低电平,非选中时输出高电平 2 移植 ucgui UCGUI的文件数量很大&#x…...

Spring扩展点系列-ApplicationContextAwareProcessor

文章目录 简介源码分析示例代码示例一:扩展点的执行顺序运行示例一 示例二:获取配置文件值配置文件application.properties内容定义工具类ConfigUtilcontroller测试调用运行示例二 示例三:实现ResourceLoaderAware读取文件ExtendResourceLoad…...

基于Keil软件实现实时时钟(江协科技HAL库)

实时时钟实验是基于江协科技STM32的HAL库工程模板创建的(可以在作品“基于江科大STM32创建的HAL库工程模板”中的结尾处获取工程模板的百度网盘链接) 复制“OLED显示”的工程文件——“4-1 OLED显示屏”,并命名为“12-2 实时时钟 ”。打开工程,把下面的程序复制到相应的文…...

dedecms靶场(四种webshell姿势)

进入靶场 姿势一:过文件管理器上传WebShell 步骤一:登录后台 /dede 步骤二:核心-》文件式管理-》文件上传-》上传一句话木马 点击 步骤三:进行蚁剑连接 姿势二:修改模板文件拿WebShell 步骤一:模板-》默认…...

PHP:强大的Web开发语言

PHP:强大的Web开发语言 一、PHP 简介及优势 PHP 的基本概念 PHP(PHP: Hypertext Preprocessor)即 “超文本预处理器”,是一种通用开源脚本语言,最初由 Rasmus Lerdorf 于 1994 年创建。它可以在服务器上执行&#xf…...

06_Python数据类型_元组

Python的基础数据类型 数值类型:整数、浮点数、复数、布尔字符串容器类型:列表、元祖、字典、集合 元组 元组(Tuple)是一种不可变的序列类型,与列表类似,但有一些关键的区别。本质:只读的列表…...

【Vue】- ref获取DOM元素和购物车案例分析

文章目录 知识回顾前言源码分析1. ref2. 购物车案例分析3. 购物车计算、全选 拓展知识数据持久化localStorage 总结 知识回顾 前言 元素上使用 ref属性关联响应式数据&#xff0c;获取DOM元素 步骤 ● 创建 ref > const hRef ref(null) ● 模板中建立关联 > <h1 re…...

【AI大模型】ChatGPT模型原理介绍(下)

目录 &#x1f354; GPT-3介绍 1.1 GPT-3模型架构 1.2 GPT-3训练核心思想 1.3 GPT-3数据集 1.4 GPT-3模型的特点 1.5 GPT-3模型总结 &#x1f354; ChatGPT介绍 2.1 ChatGPT原理 2.2 什么是强化学习 2.3 ChatGPT强化学习步骤 2.4 监督调优模型 2.5 训练奖励模型 2.…...

Python数据分析与可视化实战指南

在数据驱动的时代&#xff0c;Python因其简洁的语法、强大的库生态系统以及活跃的社区&#xff0c;成为了数据分析与可视化的首选语言。本文将通过一个详细的案例&#xff0c;带领大家学习如何使用Python进行数据分析&#xff0c;并通过可视化来直观呈现分析结果。 一、环境准…...

react18基础教程系列-- 框架基础理论知识mvc/jsx/createRoot

react的设计模式 React 是 mvc 体系&#xff0c;vue 是 mvvm 体系 mvc: model(数据)-view(视图)-controller(控制器) 我们需要按照专业的语法去构建 app 页面&#xff0c;react 使用的是 jsx 语法构建数据层&#xff0c;需要动态处理的的数据都要数据层支持控制层: 当我们需要…...

牛客周赛 Round 60 折返跑(组合数学)

题目链接&#xff1a;题目 大意&#xff1a; 在 1 1 1到 n n n之间往返跑m趟&#xff0c;推 m − 1 m-1 m−1次杆子&#xff0c;每次都向中间推&#xff0c;不能推零次&#xff0c;问有多少种推法&#xff08;mod 1e97&#xff09;。 思路&#xff1a; 一个高中学过的组合数…...

深入浅出Java匿名内部类:用法详解与实例演示

匿名内部类&#xff08;Anonymous Inner Class&#xff09;在Java中是一种非常有用的特性&#xff0c;它允许你在一个类的定义中直接创建并实例化一个内部类&#xff0c;而不需要为这个内部类指定一个名字。匿名内部类通常用于以下几种情况&#xff1a; 实现接口&#xff1a;当…...

数据库MySQL、Mariadb、PostgreSQL、MangoDB、Memcached和Redis详细介绍

以下是一些常见的后端开发数据库选型&#xff1a; 关系型数据库&#xff08;RDBMS&#xff09;&#xff1a;关系型数据库是最常见的数据库类型&#xff0c;使用表格和关系模型来存储和管理数据。常见的关系型数据库包括MySQL、PostgreSQL和Oracle等。这些数据库适合处理结构化数…...

【ArcGIS Pro实操第七期】栅格数据合并、裁剪及统计:以全球不透水面积为例

【ArcGIS Pro实操第七期】批量裁剪&#xff1a;以全球不透水面积为例 准备&#xff1a;数据下载ArcGIS Pro批量裁剪数据集1 数据拼接2 数据裁剪3 数据统计&#xff1a;各栅格取值3.1 栅格计算器-精确提取-栅格数据特定值3.2 数据统计 4 不透水面积变化分析 参考 准备&#xff1…...

【Linux】Image、zImage与uImage的区别

1、Image 1.1 什么是 Image Image 是一种未压缩的 Linux 内核镜像文件&#xff0c;包含了内核的所有代码、数据和必要的元信息。它是 Linux 内核在编译过程中生成的一个原始的二进制文件&#xff0c;未经过任何压缩或额外的封装处理。由于未压缩&#xff0c;Image 文件相对较…...

算子加速(3):自定义cuda扩展

需要自定义某个层,或有时候用c++实现你的操作(c++扩展)可能会更好: 例如:需要实现一个新型的激活函数例如: bevfusion用cuda实现bevpool加速自定义扩展的步骤 (1) 首先用纯pytorch和python 实现我们所需的功能,看看效果再决定要不要进一步优化(2) 明确优化方向,用C++ (或CU…...

信息安全数学基础(14)欧拉函数

前言 在信息安全数学基础中&#xff0c;欧拉函数&#xff08;Eulers Totient Function&#xff09;是一个非常重要的概念&#xff0c;它与模运算、剩余类、简化剩余系以及密码学中的许多应用紧密相关。欧拉函数用符号 φ(n) 表示&#xff0c;其中 n 是一个正整数。 一、定义 欧…...

7-17 汉诺塔的非递归实现

输入样例: 3输出样例: a -> c a -> b c -> b a -> c b -> a b -> c a -> c 分析&#xff1a; 不会汉罗塔的uu们&#xff0c;先看看图解&#xff1a; 非递归代码&#xff1a; #include<iostream> #include<stack> using namespace std; s…...

word文档无损原样转pdf在windows平台使用python调用win32com使用pip安装pywin32

前提&#xff1a; windows环境下&#xff0c;并且安装了office套装&#xff0c;比如word,如果需要调用excel.也需要安装。在另外的文章会介绍。这种是直接调用word的。所以还原度会比较高。 需求&#xff1a; word文档转pdf,要求使用命令行形式&#xff0c;最终发布为api接口…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...