You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Connexion+Flask时after_request打印响应致Swagger-UI异常的咨询

问题:Connexion+Swagger-UI响应日志导致界面功能异常

环境配置

  • connexion[swagger-ui]==2.13.0
  • Flask==2.2.5

需求与实现

使用Connexion搭建应用并托管Swagger-UI,需要在请求处理前后打印所有请求和响应的payload到控制台。

构建Connexion应用后添加了以下代码:

# Add pre payload printer to app
connex_app.app.before_request(print_request(config))
connex_app.app.after_request(print_response(config))

对应的日志函数实现:

def print_request(config):
    '''
    Print out requests received, or response sent
    '''
    def request_logger():
        if request.method not in ('GET'):
            if config.myproject.logging.myproject.pretty_print.request_payloads:
                logger.debug(f"Request received, Body: {request.get_data(as_text=True)}")
            else:
                data = request.get_json() if request.is_json else {}
                flat_json = json.dumps(data, separators=(',', ':'))
                logger.debug(f"Request received, Body: {flat_json}")
        else:
            logger.debug("Request received")

    return request_logger

def print_response(config):
    '''
    Print out requests received, or response sent
    '''
    def response_logger(response):
        # Ensure you have access to the correct response object here, this might need to be passed explicitly
        if config.myproject.logging.myproject.pretty_print.response_payloads:
            logger.debug(f"Response sent, Body: {response.get_data(as_text=False)}")
        else:
            # This section might need adjustment based on how you're handling response data
            data = response.get_json() if response.is_json else {}
            flat_json = json.dumps(data, separators=(',', ':'))
            logger.debug(f"Response sent, Body: {flat_json}")
        return response

    return response_logger

问题点

执行response.get_data(as_text=False)这行代码时,会导致Swagger-UI的请求和响应被异常重定向,直接破坏Swagger-UI的正常功能。此前使用旧版Connexion 2.x时无此问题,但当前因依赖限制无法升级到3.0,且必须固定使用Flask==2.2.5。


解决方案

1. 修复get_data的调用方式

response.get_data(as_text=False)返回字节流,打印时可能干扰Flask对响应内容的后续处理(比如Swagger-UI的静态资源、HTML内容)。将参数改为as_text=True,统一以文本形式获取响应内容:

logger.debug(f"Response sent, Body: {response.get_data(as_text=True)}")

这样可以避免字节流读取导致的响应对象状态异常,同时不影响日志内容的可读性。

2. 过滤Swagger-UI相关请求

如果不需要打印Swagger-UI自身的请求(比如静态资源、界面请求),可以在日志函数中添加路径过滤,跳过这些请求的日志打印:

def response_logger(response):
    # 跳过Swagger-UI相关路径的日志
    if request.path.startswith('/swagger/') or request.path == '/swagger.json':
        return response
    
    # 原日志逻辑
    if config.myproject.logging.myproject.pretty_print.response_payloads:
        logger.debug(f"Response sent, Body: {response.get_data(as_text=True)}")
    else:
        data = response.get_json() if response.is_json else {}
        flat_json = json.dumps(data, separators=(',', ':'))
        logger.debug(f"Response sent, Body: {flat_json}")
    return response

同样在request_logger中也可以添加相同的路径过滤规则,减少无关日志。

3. 优化非JSON响应的处理逻辑

对于Swagger-UI返回的HTML、CSS等非JSON响应,response.get_json()会返回None,此时无需强行JSON序列化,直接打印原始文本即可:

else:
    if response.is_json:
        data = response.get_json()
        flat_json = json.dumps(data, separators=(',', ':'))
        logger.debug(f"Response sent, Body: {flat_json}")
    else:
        # 非JSON响应直接打印文本内容
        logger.debug(f"Response sent, Body: {response.get_data(as_text=True)}")

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 05:12:38