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

Flask-restx接口使用Buffer时未触发空数据判断逻辑异常

问题:Flask-RESTX /calendar接口数据库为空时未正确返回404错误

问题详情

开发Flask-RESTX的/calendar接口时出现异常:当数据库为空时,接口本该触发if not events判断,返回{"Error": "No events found"}及404状态码,但实际仍返回ICS文件。即使注释掉if语句后的所有代码,接口依然返回ICS文件,怀疑存在缓存或代码重复定义问题。目前数据库已设为空,期望仅当events有数据时才返回ICS文件,需排查原因。

提供的代码示例

from flask import Flask, request, Response, send_file, make_response
from flask_restx import Api, Resource, fields, reqparse
from ics import Calendar, Event

@api.route('/calendar')
class ICSCalendar(Resource):

    @api.response(200, 'Successfully Retrieved Calendar')
    @api.response(404, 'No Events Found')
    @api.doc(description="Get all events in an ``ICS`` calendar format")
    def get(self):
        '''Get all events in an ICS calendar format'''
        events = execute_query("SELECT * FROM events")
        print(events)
        if not events:
            return {"Error": "No events found"}, 404
        cal = Calendar()
        for row in events:
            event = Event()
            event.name = row[1]
            event.begin = pytz.timezone('Australia/Sydney').localize(datetime.combine(datetime.strptime(row[2], '%Y-%m-%d').date(), datetime.strptime(row[3], '%H:%M:%S').time()))
            event.end = pytz.timezone('Australia/Sydney').localize(datetime.combine(datetime.strptime(row[2], '%Y-%m-%d').date(), datetime.strptime(row[4], '%H:%M:%S').time()))
            event.location = f"{row[5]}, {row[6]}, {row[7]} {row[8]}"
            event.description = row[9]
            event.last_modified = pytz.utc.localize(datetime.strptime(row[10], '%Y-%m-%d %H:%M:%S'))
            cal.events.add(event)

        # Write the ICS data to an in-memory buffer
        buffer = StringIO(cal.serialize(), newline=None)
        buffer.seek(0)
        # Create a response with the ICS data as an attachment
        response = make_response(send_file(buffer, as_attachment=True, attachment_filename='calendar.ics', mimetype='text/calendar'))
        response.headers['Content-Disposition'] = 'attachment; filename=calendar.ics'
        buffer.truncate(0)
        return response

@api.route('/calendar')
class ICSCalendar(Resource):

    @api.response(200, 'Successfully Retrieved Calendar')
    @api.response(404, 'No Events Found')
    @api.doc(description="Get all events in an ``ICS`` calendar format")
    def get(self):
        '''Get all events in an ICS calendar format'''
        events = execute_query("SELECT * FROM events")
        print(events)
        if not events:
            return {"Error": "No events found"}, 404

问题排查与解决方案

1. 核心问题:重复注册路由资源

你的代码中两次使用@api.route('/calendar')装饰了同名的ICSCalendar资源类。Python中后定义的类会覆盖前一个,但Flask-RESTX的路由注册逻辑会导致绑定混乱,服务器可能加载了旧的类定义(比如第一个包含ICS生成逻辑的类),从而导致即使数据库为空,依然执行ICS生成代码返回文件。

2. 修复步骤

  • 删除重复的路由与类定义:保留一个完整的ICSCalendar类实现,删除第二个重复的@api.route('/calendar')及对应的类代码。
  • 强制重启Flask服务:确保修改后的代码被重新加载,避免服务器缓存旧的代码逻辑(开发环境下如果开启了debug模式会自动重载,但手动重启更稳妥)。
  • 验证查询返回值:确认execute_query("SELECT * FROM events")在数据库为空时返回的是空列表[]——如果返回的是None或其他空值类型,虽然if not events仍会触发,但需确保返回值符合预期。
  • 排查缓存问题:如果是生产环境,检查是否有反向代理(如Nginx)或Flask缓存插件开启了响应缓存。测试时可以在请求头中添加Cache-Control: no-cache,强制跳过缓存获取最新响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:14:52