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

python fastapi统一捕获请求和响应

服务端代码

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import time
import json
from typing import Dict, Anyapp = FastAPI()@app.middleware("http")
async def log_request_response(request: Request, call_next):# 记录请求开始时间start_time = time.time()# 准备请求日志数据request_info: Dict[str, Any] = {"method": request.method,"url": str(request.url),"headers": dict(request.headers),"query_params": dict(request.query_params),}# 尝试获取请求体(对于非GET请求)if request.method not in ["GET", "HEAD"]:try:body = await request.json()request_info["body"] = bodyexcept:body = await request.body()if body:request_info["body"] = body.decode()# 打印请求信息print("\n" + "="*50)print("Incoming Request:")print(json.dumps(request_info, indent=2, ensure_ascii=False))# 调用路由处理函数response = await call_next(request)# 计算处理时间process_time = time.time() - start_time# 捕获响应体response_body = b""async for chunk in response.body_iterator:response_body += chunk# 准备响应日志数据response_info = {"status_code": response.status_code,"process_time": f"{process_time:.3f}s","body": json.loads(response_body.decode()) if response_body else None,"headers": dict(response.headers),}# 打印响应信息print("\nOutgoing Response:")print(json.dumps(response_info, indent=2, ensure_ascii=False))print("="*50 + "\n")# 重新构造响应(因为我们已经读取了body_iterator)return JSONResponse(content=response_info["body"],status_code=response.status_code,headers=dict(response.headers),)# 测试路由
@app.post("/test")
async def test_endpoint(data: dict):"""测试端点,返回处理后的数据"""return {"message": "Data processed successfully","received_data": data,"additional_info": {"timestamp": time.time()}}@app.get("/hello")
async def hello(name: str = "World"):"""简单的问候端点"""return {"message": f"Hello, {name}!"}if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)

客户端测试代码

import requestsdef test_get():url = "http://localhost:8000/hello"params = {"key1": "这是一个get请求测试值","key2": "value2"}# 发送 GET 请求response = requests.get(url, params=params)# 检查响应状态码if response.status_code == 200:# 获取响应内容 (JSON 格式)data = response.json()print("GET 请求成功,响应数据:", data)else:print(f"GET 请求失败,状态码: {response.status_code}")def test_post():url = "http://localhost:8000/test"headers = {"Content-Type": "application/json","Authorization": "Bearer your_token_here"  # 如果需要认证}data = {"key1": "这是一个post请求测试值","key2": "value2"}# 发送 POST 请求response = requests.post(url, headers=headers, json=data)# 检查响应状态码if response.status_code == 200:# 获取响应内容 (JSON 格式)result = response.json()print("POST 请求成功,响应数据:", result)else:print(f"POST 请求失败,状态码: {response.status_code}")print("错误信息:", response.text)test_get()
test_post()
http://www.xdnf.cn/news/9139.html

相关文章:

  • 七段码--dfs+set去重/状压
  • python训练营第35天
  • Axure动态面板学习笔记
  • React整合【ECharts】教程004:饼图的构建和基本设置
  • MySQL增删改查基础教程:熟练掌握DML语句操作【MySQL系列】
  • leetcode98.验证二叉搜索树:递归法中序遍历的递增性验证之道
  • GitLab 18.0 正式发布,15.0 将不再受技术支持,须升级【一】
  • 数字孪生文旅,如何颠覆传统旅游体验?
  • 在 Unity 中,AOT和JIT的区别
  • Java集合操作常见错误及规避方法
  • 菜鸟之路Day33一一Mybatis入门
  • halcon 图像预处理
  • 线程安全问题的成因
  • [Java实战]Spring Boot整合达梦数据库连接池配置(三十四)
  • AI智能分析网关V4室内消防逃生通道占用检测算法打造住宅/商业/工业园区等场景应用方案
  • TensorFlow 的基本概念和使用场景
  • C/C++---类型转换运算符
  • WireShark网络抓包—详细教程
  • TinyVue v3.23.0 正式发布:增加 NumberAnimation 数字动画组件、支持全局配置组件的 props
  • 深入解析操作系统内核与用户空间以及内核态与用户态转换
  • Prompt Tuning与自然语言微调对比解析
  • 视频存储开源方案
  • Jupyter Notebook 完全指南:从入门到高效使用
  • OpenFOAM 字典系统与求解器配置解析机制
  • ApplicationRunner接口和@PostConstruct注解
  • 如何选择自动化编程平台
  • 基于Android的个人健康管理系统APP
  • Python 爬虫入门
  • ViT- an image is worth 16x16 words- transformers for image recognition at scale
  • YOLOv11改进 | Neck篇 | 双向特征金字塔网络BiFPN助力YOLOv11有效涨点