Bottle框架before_request钩子在多模块合并场景下未触发问题
问题原因分析
这个问题的核心在于Bottle的merge()方法默认仅合并路由规则,不会自动合并钩子(hook)、错误处理器这类附加回调。这就是为什么你的@_local_bottle.get路由能正常工作,但before_request钩子被忽略的原因——路由是merge()的默认处理对象,而钩子不在其处理范围内。
解决方案:手动合并子应用的钩子
你需要在合并子Bottle实例到主应用时,手动遍历子实例的钩子列表,将它们注册到主应用中。Bottle的每个应用实例都有一个hooks属性,这是一个字典,键是钩子名称(比如before_request),值是该钩子对应的回调函数列表。
修改你的start.py中的合并逻辑,添加钩子合并的代码:
def start_server(debug=False): app, logger = setup_app(debug) logger.debug("Importing applications.") import ps_web_apps.load_modules for module, ps_bottle in ps_web_apps.load_modules.get_bottle_list(): logger.debug("Importing application '%s'.", module) # 先合并路由 app.merge(ps_bottle) # 手动合并所有钩子到主应用 for hook_name, callbacks in ps_bottle.hooks.items(): for callback in callbacks: app.add_hook(hook_name, callback) app = SessionMiddleware(app, session_opts) logger.debug("Starting server.") sys.argv[1:] = ["--workers", num_of_workers, "--timeout", gunicorn_timeout] if enable_gevent: logger.debug("Started as asyc gevent server.") bottle.run(app=app, port=8081, server='gunicorn', worker_class='gevent', debug=debug, quiet=not debug) else: bottle.run(app=app, port=8081, server='gunicorn', debug=debug, quiet=not debug)
额外说明
- 这个方法不仅适用于
before_request,对after_request、app_error等其他Bottle钩子同样有效,会自动合并所有子应用的钩子。 - 如果你的子应用有重复的钩子逻辑,合并后会按注册顺序依次执行(主应用原有钩子先执行,然后是子应用的钩子)。
- 如果你不想合并所有钩子,也可以针对性地只合并
before_request:# 仅合并before_request钩子 if 'before_request' in ps_bottle.hooks: for callback in ps_bottle.hooks['before_request']: app.add_hook('before_request', callback)
内容的提问来源于stack exchange,提问作者user2219195
相关产品推荐
相关产品推荐

