一文掌握异步web框架FastAPI(五)-- 中间件(测试环境、访问速率限制、请求体解析、自定义认证、重试机制、请求频率统计、路径重写)

news2024/10/27 22:18:28

接上篇:一文掌握异步web框架FastAPI(四)-CSDN博客

目录

七、中间件

 15、测试环境中间件

16、访问速率限制中间件,即限制每个IP特定时间内的请求数(基于内存,生产上要使用数据库)

        1)限制单ip访问速率

        2)增加限制单ip并发(跟上面的一样,也是限制每个IP特定时间内的请求数,另一种写法)

        3)增加封禁IP

17. 请求体解析中间件

18. 自定义认证中间件

19. 重试机制中间件

20. 请求频率统计中间件(各个接口的访问次数)

21. 路径重写中间件


七、中间件

 15、测试环境中间件

这个中间件用于识别请求是否来自于测试环境,并采取相应的措施,如禁用缓存或跳过某些安全检查。

from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
import os
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI()


@app.middleware("http")
async def test_environment_middleware(request: Request, call_next):
    try:
        # 检查环境变量
        test_environment_enabled = os.getenv("TEST_ENVIRONMENT_ENABLED", "false").lower() == "true"
        if "X-Test-Environment" in request.headers and request.headers["X-Test-Environment"].lower() == "true":
            if test_environment_enabled:
                logger.info("Test environment header detected. Enabling test environment specific logic.")
                # 测试环境特有的处理
                # 例如:设置数据库连接为测试数据库、开启调试模式等
                pass
            else:
                logger.warning("Test environment header detected, but TEST_ENVIRONMENT_ENABLED is not set to true.")
                return JSONResponse({"message": "Test environment not enabled"}, status_code=403)
        response = await call_next(request)
        return response
    except Exception as e:
        logger.error(f"Error in test_environment_middleware: {str(e)}")
        return JSONResponse({"message": "Internal server error"}, status_code=500)


@app.get("/")
async def root():
    return {"message": "Hello World"}


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8000)

请求:

import requests

# FastAPI应用的URL
url = "http://127.0.0.1:8000/"
# 发送GET请求到根路径,并包含测试环境头部
response = requests.get(url, headers={"X-Test-Environment": "true"})
# 打印响应状态码和内容
print(f"Status Code: {response.status_code}")
print(f"Response Content: {response.json()}")

本地未启用测试环境:

16、访问速率限制中间件,即限制每个IP特定时间内的请求数(基于内存,生产上要使用数据库)

        1)限制单ip访问速率
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import time
from collections import defaultdict
import logging

app = FastAPI()
# 初始化rate_limits字典
rate_limits = defaultdict(list)
# 配置日志
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)


# 定义中间件
@app.middleware("http")
async def rate_limit_middleware(request: Request, call_next):
    ip = request.headers.get("X-Forwarded-For", request.client.host).split(",")[0].strip()
    now = time.time()
    # 移除旧的请求时间戳
    rate_limits[ip] = [t for t in rate_limits[ip] if t > now - 60]
    # 检查速率限制
    if len(rate_limits[ip]) >= 10:  # 限制为每分钟10个请求
        logger.debug(f"Rate limit exceeded for IP: {ip}")
        return JSONResponse(
            status_code=429,
            content={"detail": "Too Many Requests"}
        )
    # 添加当前请求的时间戳
    rate_limits[ip].append(now)
    # 继续处理请求
    response = await call_next(request)
    return response


# 定义路由
@app.get("/")
async def root():
    return {"message": "Hello World"}


# 启动应用
if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8000, log_level="debug")

请求:

import requests
import time

# FastAPI应用的URL
url = "http://127.0.0.1:8000/"
# 用于测试的IP地址
ip = "127.0.0.1"
# 设置请求头,模拟X-Forwarded-For
headers = {
    "X-Forwarded-For": ip
}


# 发送多个请求以测试速率限制
def test_rate_limit():
    for i in range(15):
        try:
            response = requests.get(url, headers=headers)
            print(f"Request {i + 1}: Status Code: {response.status_code}")
            if response.status_code == 429:
                print(f"Request {i + 1}: {response.json()}")
        except Exception as e:
            print(f"Request {i + 1}: Error: {e}")
        time.sleep(1)  # 等待1秒

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2结合echarts实现数据排名列表——前端柱状进度条排行榜

写在前面,博主是个在北京打拼的码农,工作多年做过各类项目,最近心血来潮在这儿写点东西,欢迎大家多多指教。 数据排名列表——图表开发,动态柱状图表,排名图 UI 直接搜到类似在线代码(数据列表…

事务的原理、MVCC的原理

事务特性 数据库事务具有以下四个基本特性,通常被称为 ACID 特性: 原子性(Atomicity):事务被视为不可分割的最小工作单元,要么全部执行成功,要么全部失败回滚。这意味着如果事务执行过程中发生…

交换机:端口安全与访问控制指南

为了实现端口安全和访问控制,交换机通常通过以下几种机制和配置来保护网络,防止未经授权的访问和恶意攻击。 01-端口安全 定义及功能 端口安全功能允许管理员限制每个交换机端口可以学习的MAC地址数量。 通过绑定特定的MAC地址到交换机的某一端口上&a…

二十二、Python基础语法(模块)

模块(module):在python中,每个代码文件就是一个模块,在模块中定义的变量、函数、类别人都可以直接使用,如果想要使用别人写好的模块,就必须先导入别人的模块,模块名须满足标识符规则(由字母、数…

MFC七段码显示实例

在MFC中添加iSenvenSegmentAnalogX控件,添加编辑框和按钮实现在编辑框中输入数字点击按钮后数字用七段码显示 1、在对话框中点击右键如下图添加控件和变量 2、在sevenDlg.h中添加代码 public: void ShowInd(int,double);3、在sevenDlg.cpp中添加代码 void CSe…

将 el-date-picker获取的时间数据转换成时间戳

在Vue.js中使用Element UI的el-date-picker组件时,你可以获取用户选择的日期并将其转换为时间戳。el-date-picker通常返回的是一个Date对象或一个格式化后的字符串(取决于你如何配置它)。下面是一个示例,展示了如何将el-date-pick…

攻防世界的新手web题解

攻防世界引导模式 1、disabled_button 好&#xff0c;给了一个按钮&#xff0c;第一道题目就不会做 看的wp<input disabled class"btn btn-default" style"height:50px;width:200px;" type"submit" value"flag" name"auth&q…

来源爬虫程序调研报告

来源爬虫程序调研报告 一、什么是爬虫 爬虫&#xff1a;就是抓取网页数据的程序。从网站某一个页面&#xff08;通常是首页&#xff09;开始&#xff0c;读取网页的内容&#xff0c;找到在网页中的其它链接地址&#xff0c;然后通过这些链接地址寻找下一个网页&#xff0c;这…

植物健康,Spring Boot来保障

5系统详细实现 5.1 系统首页 植物健康系统需要登录才可以看到首页。具体界面的展示如图5.1所示。 图5.1 系统首页界面 5.2 咨询专家 可以在咨询专家栏目发布消息。具体界面如图5.2所示。 图5.2 咨询专家界面 5.3 普通植物检查登记 普通员工可以对普通植物检查登记信息进行添…

07 设计模式-结构型模式-桥接模式

桥接&#xff08;Bridge&#xff09;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;它通过提供抽象化和实现化之间的桥接结构&#xff0c;来实现二者的解耦。 这种模式涉及到一个作为桥接的接口&#xff0c;使得…

入门 | Prometheus+Grafana 普罗米修斯

#1024程序员节&#xff5c;征文# 一、prometheus介绍 1、监控系统组成 一个完整的监控系统需要包括如下功能&#xff1a;数据产生、数据采集、数据存储、数据处理、数据展示、分析、告警等。 &#xff08;1&#xff09;、数据来源 数据来源&#xff0c;也就是需要监控的数据…

VS Code 自动生成代码

1. 在vs code中的左下角&#xff0c;点击设置中的snippets。 2. 输入你需要生成的代码种类&#xff0c;这边以JS为例 打开后可以看到下面这样 从Example看起&#xff0c; 1.Print to console 这个是提升信息&#xff0c;就是当你输入代码的时候的提升。 2.prefix是缩写。 3.b…

python爬虫——Selenium的基本使用

目录 一、Selenium的介绍 二、环境准备 1.安装Selenium 2.安装WebDriver 三、元素定位 1.常用定位元素的方法 2. 通过指定方式定位元素 四、窗口操作 1.最大化浏览器窗口 2.设置浏览器窗口大小 3.切换窗口或标签页 切换回主窗口 4. 关闭窗口 关闭当前窗口 关闭所…

由于找不到mfc140u.dll,无法继续执行代码怎么办,总有6个解决方法

在软件开发和程序运行过程中&#xff0c;许多用户可能会遇到“找不到mfc140u.dll&#xff0c;无法继续执行代码”的问题。本文将对该问题进行详细解读&#xff0c;分析其产生原因&#xff0c;并提供相应的解决方案。 一、mfc140u.dll是什么 mfc140u.dll是Microsoft Visual C 2…

apache poi导出excel

简介 常见的使用场景 入门 导入maven依赖 <!-- poi --> <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId> </dependency> <dependency><groupId>org.apache.poi</groupId><arti…

Java Web项目实战:从零基础到项目开发全流程

Java Web开发环境搭建 Java Web开发需要Java运行环境、IDE&#xff08;如IntelliJ IDEA或Eclipse&#xff09;以及Maven集成开发工具等。首先&#xff0c;确保电脑上安装有Java 8或更高版本&#xff0c;可以通过访问Java官网获取最新版本。其次&#xff0c;安装IDE&#xff0c…

jupyter notebook改变默认启动路径

安装好Anaconda 3以后&#xff0c;就可以使用Jupyter notebook了&#xff0c;但是我们打开Jupyter notebook后&#xff0c;发现界面是一个默认的目录&#xff0c;这个目录在哪里&#xff1f;如果想把自己写的程序文件保存在自己新建的一个文件夹里&#xff0c;修改默认目录到自…

vue elementui el-table实现增加行,行内编辑修改

需求&#xff1a; 前端进行新增表单时&#xff0c;同时增加表单的明细数据。明细数据部分&#xff0c;可进行行编辑。 效果图&#xff1a; <el-card><div slot"header"><span style"font-weight: bold">外来人员名单2</span><…

MySQL8.0.40编译安装

近期MySQL发布了8.0.40版本&#xff0c;与之前的版本相比&#xff0c;部分依赖包发生了变化&#xff0c;因此重新编译一版&#xff0c;也便于大家参考。 1. 下载源码 选择对应的版本、选择源码、操作系统 如果没有登录或者没有MySQL官网账号&#xff0c;可以选择只下载 2. 进…

Flutter仿京东商城APP实战 用户中心基础布局

用户中心界面 pages/tabs/user/user.dart import package:flutter/material.dart; import package:jdshop/utils/zdp_screen.dart; import package:provider/provider.dart;import ../../../store/counter_store.dart;class UserPage extends StatefulWidget {const UserPage…