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

flask入门(五)WSGI及其Python实现

文章目录

  • WSGI(Web Server Gateway Interface)
    • 基于WSGI实现的Flask框架
    • 生产环境中的WSGI
  • 参考文献

WSGI(Web Server Gateway Interface)

WSGI:Python Web 应用(Flask、Django、FastAPI 等)与 Web 服务器(Gunicorn、uWSGI、mod_wsgi 等)之间的标准协议

在这里插入图片描述

为什么需要 WSGI?

  • Nginx / Apache → 负责接收浏览器的 HTTP 请求
  • Flask / Django → 负责写业务逻辑,返回 HTML/JSON

❌ 问题:Nginx 并不能直接“调用” Python 代码,它只会转发 HTTP 请求
✅ 解决:定义一个“桥梁”—— WSGI 协议

浏览器←\leftarrowHTT→\toNginx/Apache←\leftarrowWSGI→\toGunicorn/uWSGI←\leftarrowPython→\toFlask/Django

WSGI应用本质上是一个Python可调用对象(通常是函数或类的实例),它必须接受两个参数

  • environ:一个包含请求数据的Python字典
  • start_response:一个用于发送HTTP状态和头信息的回调函数

这个接口设计得非常简单,只要求Web开发者实现一个函数,就可以响应HTTP请求
WSGI是一个低级接口,许多Python开发者在使用Django、Flask等流行框架时,实际上是在WSGI之上构建应用
最基础的WSGI应用实现

def application(environ, start_response):"""一个简单的WSGI应用"""# 设置HTTP响应状态和头信息status = '200 OK'headers = [('Content-Type', 'text/plain; charset=utf-8')]# 调用start_response发送响应头start_response(status, headers)# 获取请求路径path = environ.get('PATH_INFO', '').lstrip('/')# 根据路径返回不同内容if path == '':return [b'Welcome to WSGI application!']elif path == 'hello':return [b'Hello, WSGI World!']else:start_response('404 Not Found', [('Content-Type', 'text/plain')])return [b'404 Not Found']# 运行WSGI服务器
if __name__ == '__main__':from wsgiref.simple_server import make_serverhttpd = make_server('', 8000, application)print("Serving on port 8000...")httpd.serve_forever()
  • WSGI应用函数:application函数是核心,它接收environstart_response两个必需参数
  • environ字典:包含所有请求信息,如HTTP方法、路径、头信息等。可以通过environ.get('PATH_INFO')获取请求路径
  • start_response函数:用于设置HTTP响应状态和头信息。它需要两个参数:状态字符串(如'200 OK')和头信息列表(如[('Content-Type', 'text/plain')]
  • 响应体:必须是一个字节字符串的可迭代对象(通常是列表),如[b'Hello, WSGI!']
  • WSGI服务器:使用Python标准库中的wsgiref模块创建一个简单的WSGI服务器来运行我们的应用

实际工作流程

  1. 当用户访问服务器时,WSGI服务器接收HTTP请求
  2. 服务器将请求信息转换为environ字典
  3. 服务器调用WSGI应用函数,传入environstart_response
  4. WSGI应用处理请求,调用start_response设置响应头
  5. WSGI应用返回响应体(字节字符串列表)
  6. 服务器将响应发送回客户端

基于WSGI实现的Flask框架

前置知识

  • Flask入门(一)
  • Flask入门(二)模板
  • flask入门(三)静态文件

Flask框架本身就是构建在WSGI规范之上的,每个Flask应用实例本质上就是一个符合WSGI规范的可调用对象
在Flask内部,Flask类实现了WSGI接口

  • Flask应用实例是一个可调用对象(实现了__call__方法)
  • 当WSGI服务器调用该实例时,会传入environstart_response参数→\toapp(environ, start_response)可以被服务器调用
  • Flask内部处理请求,生成响应,并返回符合WSGI规范的响应体

基本Flask应用(标准用法):

from flask import Flask, requestapp = Flask(__name__)@app.route('/')
def home():return 'Hello from Flask!'@app.route('/user/<username>')
def show_user_profile(username):return f'User: {username}'@app.route('/query')
def query_example():name = request.args.get('name', 'Guest')return f'Hello, {name}!'if __name__ == '__main__':app.run(debug=True, host='0.0.0.0', port=5000)
  • 用 Flask 内置服务器(调试)
python app.py

Flask 内部还是调用 WSGI 接口,只是用内置开发服务器封装了一层
但在生产环境下如果用 nohup python app.py&之类运行,Ctrl+C后台挂起/终端断开/内存不足时进程会挂掉。

  • 方式 B:用原生 WSGI 服务器启动
# wsgi_server.py
from wsgiref.simple_server import make_server
from app import app   # app就是Flask实例,也是WSGI应用httpd = make_server('', 5000, app)   # 这里app直接当WSGI应用传入
print("Serving Flask on port 5000...")
httpd.serve_forever()
  • 方式 C:用 Gunicorn 启动
gunicorn -w 4 -b 0.0.0.0:5000 app:app

生产环境中的WSGI

在实际生产环境中,我们通常不会使用wsgiref这样的简单服务器,而是使用更强大的WSGI服务器如GunicornuWSGI,它们能处理更多并发请求并提供更好的性能

# 使用Gunicorn运行Flask应用
gunicorn -w 4 -b 0.0.0.0:5000 app:app
  • gunicorn:启动 Gunicorn 服务器的命令
  • -w 4:表示 worker 数量,每个 worker 是一个独立的 Python 进程(不是线程),可以并发处理多个请求,多 worker 能更好利用多核 CPU
  • -b 0.0.0.0:5000:表示绑定地址和端口→\to服务地址是 http://服务器IP:5000/
  • app:app:模块名:应用对象
    • 第一个 app → Python 文件名(不带 .py),即 app.py
    • 第二个 app → 文件里的 Flask 应用对象

参考文献

  1. Web服务器网关接口
  2. What is WSGI (Web Server Gateway Interface)
  3. The Definitive Guide to WSGI

文章转载自:

http://Sjp6HZYU.jrLgz.cn
http://ZY9LJw1a.jrLgz.cn
http://2b0nbC0B.jrLgz.cn
http://qqtMGVCf.jrLgz.cn
http://tIPboFhW.jrLgz.cn
http://vleHACvh.jrLgz.cn
http://3S2X6PGk.jrLgz.cn
http://Vg3dtXgr.jrLgz.cn
http://Aa0oXhJf.jrLgz.cn
http://ve01ReBg.jrLgz.cn
http://YSHtc5Ex.jrLgz.cn
http://U6ipeFFg.jrLgz.cn
http://cJPFfnn0.jrLgz.cn
http://1Q5ROvTT.jrLgz.cn
http://GPXPnOOq.jrLgz.cn
http://M9TP9Aeq.jrLgz.cn
http://wCwQx1Pn.jrLgz.cn
http://mH6DkAdG.jrLgz.cn
http://4tpiZsZV.jrLgz.cn
http://N0QKit5v.jrLgz.cn
http://1LlwNJl3.jrLgz.cn
http://fbdgEMOL.jrLgz.cn
http://ag20WYuE.jrLgz.cn
http://mrlBFtmo.jrLgz.cn
http://sJdQ0NbH.jrLgz.cn
http://5KGgq0Fq.jrLgz.cn
http://rBPPir9Y.jrLgz.cn
http://nMX9wJu1.jrLgz.cn
http://c69sBhNN.jrLgz.cn
http://TOTND6ji.jrLgz.cn
http://www.dtcms.com/a/382900.html

相关文章:

  • 第17课:自适应学习与优化
  • 详解安卓开发andorid中重要的agp和gradle的关系以及版本不匹配不兼容问题的处理方法-优雅草卓伊凡
  • Linux应用开发(君正T23):三网智能切换及配网功能
  • 华为HarmonyOS开发文档
  • Java 文件io
  • 在Android Studio中配置Gradle涉及到几个关键的文件
  • 基于OpenCV的答题卡自动识别与评分系统
  • 贪心算法应用:出租车调度问题详解
  • 【RK3576】【Android14】如何在Android14下单独编译kernel-6.1?
  • FlashAttention(V2)深度解析:从原理到工程实现
  • ​Prometheus+Grafana监控系统配置与部署全解
  • 电路调试过程中辨认LED正负极并焊接
  • ubuntu24.04 缺少libwebkit2gtk-4.0和libssl.so.1.1
  • eslint-config-encode 使用指南
  • MySQL高阶查询语句与视图实战指南
  • 金融数学与应用数学(金融方向)课程重合度高吗?
  • 知识沉淀过于碎片化如何形成体系化框架
  • 第二十篇|SAMU教育学院的教育数据剖析:制度阈值、能力矩阵与升学网络
  • 深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第十章知识点问答(10题)
  • dockercompose和k8s区别
  • HENGSHI SENSE 6.0技术解密:边缘计算+Serverless架构如何重构企业级BI实时性
  • Delphi - IndyHttpServer接收上传文件
  • 1.linux环境配置+ssh远程连接vscode调试(问题:无法联网,无法共享粘贴板,不满足运行vscode服务器的先决条件)
  • unity导入blender动画
  • 【杂谈】-备份革命:解锁AI时代的“死数据“金矿
  • npm 发布流程——从创建组件到发布到 npm 仓库
  • 单变量单步时序预测 | TCN-GRU时间卷积神经网络结合门控循环单元
  • 分布式协议与算法实战-理论篇
  • 《sklearn机器学习——数据预处理》生成多项式特征
  • XLua教程之入门篇