同时使用@statsd.timed与@swag_from装饰器引发FileNotFoundError
解决Flasgger与Datadog statsd.timed装饰器冲突导致的Swagger文件路径错误
问题描述
原本正常运行的Flask接口,添加Datadog的statsd.timed装饰器后,Swagger页面渲染失败,抛出FileNotFoundError,提示在/usr/local/lib/python3.7/site-packages/datadog/dogstatsd/swagger/目录下找不到YML文件,而实际文件是放在项目自身的swagger/目录中。修改Flask的static_folder配置也无法解决。
原因分析
Python装饰器的执行顺序是从下到上(越靠近函数的装饰器越先执行)。原本@swag_from直接装饰原函数时,会以原函数所在模块的目录为基准查找YML文件;但把@statsd.timed放在@swag_from上方后,@swag_from实际装饰的是statsd生成的包装函数,此时Flasgger会以datadog模块的安装目录作为基准路径去查找YML文件,自然找不到项目里的文件。
解决方案
调整两个装饰器的顺序,将@swag_from放在@statsd.timed的下方(更靠近被装饰的函数),让swag_from优先基于原函数的目录路径查找YML文件,再由statsd.timed包装处理好Swagger配置的函数。
修正后的代码:
from flasgger import swag_from from datadog import statsd @app.route("/jobs", methods=["GET"]) @statsd.timed("api_call.duration") @swag_from('swagger/get_jobs.yml') def get_jobs(request_id): # 业务逻辑代码 ...
这样调整后,Flasgger就能正确找到项目目录下的swagger/get_jobs.yml文件,同时Datadog的耗时统计也能正常工作。
内容的提问来源于stack exchange,提问作者Tzach Zohar
相关产品推荐
相关产品推荐

