《Python实战进阶》专栏 No2: Flask 中间件与请求钩子的应用

专栏简介

《Python实战进阶》专栏共68集,分为 模块1:Web开发与API设计(共10集);模块2:数据处理与分析(共10集);模块3:自动化与脚本开发(共8集);模块4:机器学习与深度学习(共12集);模块5:并发与性能优化(共8集);模块6:网络编程与安全(共8集);模块7:云计算与容器化(共6集);模块8:综合实战与扩展(共6集);覆盖了Python在不同领域的应用,并结合了实际开发中的热点和难点。这些内容可以帮助读者从基础到高级逐步掌握Python技术,同时为实际项目开发提供参考。

专栏特色

  1. 聚焦实战:每集都包含实际案例和代码示例,帮助读者快速上手。
  2. 覆盖全面:从基础到高级,涵盖 Python 的多个应用场景。
  3. 模块化设计:每个模块独立成体系,便于读者按需学习。
  4. 持续更新:根据技术发展趋势,定期补充新内容。

《Python实战进阶》专栏 No2: Flask 中间件与请求钩子的应用

在 Web 开发中,中间件(Middleware)请求钩子(Request Hooks) 是非常重要的概念。它们可以帮助我们处理跨请求的逻辑,例如日志记录、权限验证、性能监控等。Flask 提供了灵活的机制来实现这些功能,使得开发者可以轻松地扩展应用的功能。

本文将详细介绍 Flask 的中间件和请求钩子,并通过实战代码展示其应用场景。


在这里插入图片描述

什么是中间件?

定义

中间件是一种拦截 HTTP 请求和响应的组件,通常用于在请求到达视图函数之前或响应返回客户端之前执行特定的逻辑。它可以在不修改核心业务逻辑的情况下,为应用添加额外的功能。

在 Flask 中实现中间件

Flask 的中间件可以通过 WSGI 中间件的方式实现。WSGI(Web Server Gateway Interface)是 Python Web 应用的标准接口,Flask 本身就是一个 WSGI 应用。


什么是请求钩子?

定义

请求钩子是 Flask 提供的一种装饰器机制,用于在请求的不同阶段执行特定的逻辑。常见的请求钩子包括:

  • @before_request:在每个请求之前执行。
  • @after_request:在每个请求之后执行(如果视图函数没有抛出异常)。
  • @teardown_request:在每个请求结束时执行(无论是否发生异常)。
  • @before_first_request:在应用接收第一个请求之前执行(Flask 2.3 后已废弃)。

实战案例:使用中间件与请求钩子

我们将构建一个简单的 Flask 应用,演示如何使用中间件和请求钩子实现以下功能:

  1. 日志记录:记录每个请求的路径和方法。
  2. 性能监控:测量每个请求的处理时间。
  3. 权限验证:检查用户是否有访问权限。

完整代码

from flask import Flask, request, jsonify, g
import time
from functools import wrapsapp = Flask(__name__)# 中间件:记录请求日志
class LoggingMiddleware:def __init__(self, app):self.app = appdef __call__(self, environ, start_response):# 记录请求信息print(f"Request received: {environ['REQUEST_METHOD']} {environ['PATH_INFO']}")return self.app(environ, start_response)# 注册中间件
app.wsgi_app = LoggingMiddleware(app.wsgi_app)# 请求钩子:性能监控
@app.before_request
def start_timer():g.start_time = time.time()@app.after_request
def log_request(response):if hasattr(g, 'start_time'):duration = round(time.time() - g.start_time, 2)print(f"Request took {duration} seconds")return response# 请求钩子:权限验证
def require_auth(f):@wraps(f)def decorated_function(*args, **kwargs):auth_token = request.headers.get('Authorization')if auth_token != "Bearer my-secret-token":return jsonify({"error": "Unauthorized"}), 401return f(*args, **kwargs)return decorated_function@app.route('/protected', methods=['GET'])
@require_auth
def protected():return jsonify({"message": "You have access to this protected resource!"})@app.route('/public', methods=['GET'])
def public():return jsonify({"message": "This is a public resource."})# 启动应用
if __name__ == '__main__':app.run(debug=True)

代码解析

1. 中间件:LoggingMiddleware
  • 我们定义了一个 LoggingMiddleware 类,用于拦截所有请求并打印请求方法和路径。
  • 在构造函数中接收 Flask 应用的 wsgi_app,并在 __call__ 方法中调用原始的 WSGI 应用。
  • 将中间件注册到 Flask 应用中:app.wsgi_app = LoggingMiddleware(app.wsgi_app)

图1:中间件工作原理
(图片描述:流程图展示了请求从客户端到中间件再到 Flask 应用的传递过程,中间件记录了请求信息。)
在这里插入图片描述

2. 请求钩子:性能监控
  • 使用 @before_request 钩子记录请求开始时间。
  • 使用 @after_request 钩子计算请求处理时间,并打印日志。
  • g 是 Flask 提供的全局对象,用于存储请求上下文中的数据。
3. 请求钩子:权限验证
  • 定义了一个装饰器 require_auth,用于检查请求头中的 Authorization 字段。
  • 如果验证失败,返回 401 错误;否则继续执行视图函数。

运行结果

启动 Flask 应用后,访问以下 URL:

  1. 访问公共资源

    GET /public
    

    输出:

    {"message": "This is a public resource."
    }
    
  2. 访问受保护资源(无权限)

    GET /protected
    Authorization: Bearer wrong-token
    

    输出:

    {"error": "Unauthorized"
    }
    
  3. 访问受保护资源(有权限)

    GET /protected
    Authorization: Bearer my-secret-token
    

    输出:

    {"message": "You have access to this protected resource!"
    }
    

控制台日志:

Request received: GET /public
Request took 0.01 seconds
Request received: GET /protected
Request took 0.02 seconds

总结

本文介绍了 Flask 中间件和请求钩子的基本概念,并通过实战代码展示了它们的应用场景。通过中间件和请求钩子,我们可以轻松实现日志记录、性能监控和权限验证等功能,从而提升应用的可维护性和安全性。

希望这篇文章能帮助你更好地理解和使用 Flask 的中间件与请求钩子!如果你有任何问题或建议,请随时告诉我!


参考资料

  • Flask 官方文档: https://flask.palletsprojects.com/
  • WSGI 规范: https://www.python.org/dev/peps/pep-3333/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/20088.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习:k近邻

所有代码和文档均在golitter/Decoding-ML-Top10: 使用 Python 优雅地实现机器学习十大经典算法。 (github.com),欢迎查看。 K 邻近算法(K-Nearest Neighbors,简称 KNN)是一种经典的机器学习算法,主要用于分类和回归任务…

初识Linux(9):程序地址空间

实验&#xff1a; 1 #include <stdio.h>2 #include <sys/types.h>3 #include <unistd.h>4 #include <string.h>5 6 int g_val 100;7 8 int main()9 {10 printf("我是一个进程: pid:%d,ppid:%d\n",getpid(),getppid());11 pid_t id for…

RadASM环境,win32汇编入门教程之六

;运行效果 ;RadASM环境&#xff0c;win32汇编入门教程之六 ;在上一个教程里面&#xff0c;我们学习了如何定义数据&#xff0c;那么在这一章节里面&#xff0c;我们来学习一下&#xff0c;再说明怎么把这些数据显示出来 ;下列就是显示出这些数据的示例程序&#xff0c;可以直接…

Flutter

项目文件目录结构介绍 注&#xff1a;创建 Flutter 项目名称不要包含特殊字符&#xff0c;不要使用驼峰标识 // TODO 开发中运行一个 Flutter 三种启动方式&#xff1a; Run 冷启动从零开始启动Hot Reload 热重载执行 build 方法Hot Restart 热重启重新运行整个 APP 代码分析…

【基础架构篇十一】《DeepSeek日志体系:ELK+Prometheus监控方案》

各位被日志淹没的工程师们,是否经历过这些抓狂时刻?——凌晨三点被报警短信吵醒,打开系统却看到: 日志文件以每秒100MB的速度疯狂膨胀关键报错信息在10TB日志里玩捉迷藏监控图表像心电图一样上蹿下跳服务器硬盘在报警声中发出垂死呻吟今天我们不聊什么基础的日志收集,直接…

JavaEE -JDBC池化思想 与 IDEA导包

1.JDBC概述 1.JDBC 的概述 * Java DataBase Connectivity Java数据库的连接。 * 目的使用 Java 的代码来操作数据库 * 需要使用 JDBC &#xff08; Java 数据库的连接&#xff09;规范来操作数据。 2.JDBC 的规范 * JDBC是一套接口规范 * JDBC的实现类都是由各个数据库的…

Pycharm打开的jupyter notebook无法在pycharm中关闭怎么解决

首先你可以先看一下你的pycharm的jupyter界面的输出&#xff1a; 可以看到第一行有个启动命令 找到这个–port的端口号&#xff0c;现在我们可以走下面的步骤&#xff0c;假设你找到的是–port47187 &#xff1a; 步骤 1&#xff1a;定位占用端口的进程&#xff08;Linux/Mac…

电磁铁的磁芯材质

电磁铁的磁芯通常采用软铁材质&#xff0c;因其具有高磁导率和低矫顽力&#xff0c;使得电磁铁能够在通电时迅速产生强磁场&#xff0c;断电后磁场又能迅速消失。 一、电磁铁与磁芯材质 电磁铁是一种利用电流产生磁场的装置。其核心部件——磁芯&#xff0c;对电磁铁的性能有着…

网络安全等级保护测评(等保测评):全面指南与准备要点

等保测评&#xff0c;全称为“网络安全等级保护测评”&#xff0c;是根据《网络安全法》及《网络安全等级保护条例》等法律法规&#xff0c;对信息系统进行安全等级划分&#xff0c;并依据不同等级的安全保护要求&#xff0c;采用科学方法和技术手段&#xff0c;全面评估信息系…

24蓝桥省赛B-数字接龙

#include<bits/stdc.h> using namespace std; const int N13; int mp[N][N],flag,n,k; bool vis[N][N]; int f[N][N][N][N];//存储路径,用于判断是否斜着走,是本题剪枝的难点 vector<int>ans; vector<int>res; int dx[]{-1,-1,0,1,1,1,0,-1}; int dy[]{0,1,1…

基于豆瓣2025电影数据可视化分析系统的设计与实现

✔️本项目旨在通过对豆瓣电影数据进行综合分析与可视化展示&#xff0c;构建一个基于Python的大数据可视化系统。通过数据爬取收集、清洗、分析豆瓣电影数据&#xff0c;我们提供了一个全面的电影信息平台&#xff0c;为用户提供深入了解电影产业趋势、影片评价与演员表现的工…

React实现自动滚动表格

在 React 中实现一个自动滚动的表格&#xff0c;可以通过 CSS 动画和 JavaScript 定时器来实现。以下是一个完整的示例代码&#xff0c;包含示例数据和自动滚动功能。 实现思路&#xff1a; ** 自动滚动&#xff1a;** 使用 setInterval 实现表格的自动滚动。 手动滚动&…

2024年GESP09月认证Scratch一级试卷

2024年GESP09月认证Scratch一级试卷分数&#xff1a;100 题数&#xff1a;17 一、单选题(共10题&#xff0c;每题3分&#xff0c;共30分) 01020304050607080910AACBCABCDD 1、据有关资料&#xff0c;山东大学于1972年研制成功DJL-1计算机&#xff0c;并于1973年投入运行&…

Qt常用控件之按钮QPushButton

按钮QPushButton QPushButton 在 Qt 中用于表示一个按钮控件&#xff0c;它继承自抽象 QAbstractButton 类。 QPushButton属性 属性说明text按钮中的文本。icon按钮中的图标。iconSize按钮中图标的大小。shortCut按钮对应的快捷键。autoRepeat按钮是否会重复触发&#xff08…

【PHP】php+mysql 活动信息管理系统(源码+论文+数据库+数据库文件)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 【PHP】php 活动信息管理系统&#xff08;源码论文…

搭建一个 Spring Boot 项目,解决jdk与springboot版本不匹配

搭建一个 Spring Boot 项目 方式一&#xff1a;使用 Spring Initializr Spring Initializr 是一个基于 Web 的工具&#xff0c;用于快速生成 Spring Boot 项目的基础结构。 访问 Spring Initializr 网站&#xff1a;https://start.spring.io/配置项目信息&#xff1a; …

基于SpringBoot的小区运动中心预约管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

WPF快速创建DeepSeek本地自己的客户端-基础思路版本

开发工具&#xff1a;VS 2015 开发环境&#xff1a;.Net 4.0 使用技术&#xff1a;WPF 本篇文章内容&#xff1a; 本地部署DeepSeek以后一般使用网页工具&#xff08;如Chatbox&#xff09;或者DOS窗口与其对话。本篇文章使用WPF创建一个基础版的对话工具。 一、搭建本地DeepS…

【怎么使用Redis实现一个延时队列?】

怎么使用Redis实现一个延时队列? 详细说明Java代码示例解释注意事项使用Redis实现延时队列通常通过有序集合(Sorted Set)来实现,利用Redis的ZSET类型及其相关命令可以很方便地实现这一功能。 有序集合中的每个元素都有一个分数(score),我们可以利用这个分数来存储消息需…

Blackbox.AI:高效智能的生产力工具新选择

前言 在当今数字化时代&#xff0c;一款高效、智能且功能全面的工具对于开发者、设计师以及全栈工程师来说至关重要。Blackbox.AI凭借其独特的产品特点&#xff0c;在众多生产力工具中脱颖而出&#xff0c;成为了我近期测评的焦点。以下是我对Blackbox.AI的详细测评&#xff0…