Werkzeug移除shutdown接口后如何实现Flask单请求接收后自动停止服务
实现临时Flask服务接收OAuth回调后自动终止的解决方案
核心思路
你需要的是本地临时运行的轻量服务,仅用于接收一次OAuth回调请求,不需要支持高并发或生产级稳定性,核心逻辑为:启动服务后阻塞等待回调,拿到token后主动终止服务即可,完全不需要依赖Werkzeug废弃的私有shutdown接口。
方案1:线程+Event事件实现(兼容性最优,全版本通用)
不依赖任何框架私有接口,Flask 1.x/2.x/3.x全版本可用:
- 用
threading.Event作为终止信号,回调接口拿到token后存储结果,再触发终止信号 - 主线程等待信号触发后直接退出,自动销毁后台运行的Flask服务
from flask import Flask, request import threading import webbrowser import sys app = Flask(__name__) # 存储回调拿到的token oauth_token = None # 服务终止信号 shutdown_event = threading.Event() @app.route("/oauth/callback") def oauth_callback(): global oauth_token oauth_token = request.args.get("token") # 触发终止信号 shutdown_event.set() return "授权成功,你可以关闭当前页面返回应用了" def run_temp_server(): # 关闭调试模式和自动重载,避免线程冲突 app.run(host="127.0.0.1", port=8765, debug=False, use_reloader=False) if __name__ == "__main__": # 后台线程启动临时服务 server_thread = threading.Thread(target=run_temp_server) server_thread.daemon = True server_thread.start() # 打开浏览器跳转到OAuth授权页 # webbrowser.open("你的OAuth服务授权地址,回调填http://127.0.0.1:8765/oauth/callback") # 阻塞等待回调触发终止信号,可加timeout避免进程永久残留,示例为300秒超时 shutdown_event.wait(timeout=300) if oauth_token: print(f"获取到token:{oauth_token}") # 此处写你拿到token后的业务逻辑 else: print("授权超时") sys.exit(0)
方案2:用生产级WSGI服务器Waitress实现(无线程依赖)
如果不想用多线程逻辑,可以用轻量生产级WSGI服务器Waitress,它原生支持处理指定数量请求后自动退出:
- 首先安装依赖:
pip install waitress - 代码示例:
from flask import Flask, request from waitress import serve import webbrowser import sys app = Flask(__name__) oauth_token = None @app.route("/oauth/callback") def oauth_callback(): global oauth_token oauth_token = request.args.get("token") return "授权成功,你可以关闭当前页面返回应用了" if __name__ == "__main__": # 打开浏览器跳转到OAuth授权页 # webbrowser.open("你的OAuth服务授权地址") # max_requests设为1,处理完1个请求后自动停止服务 serve(app, host="127.0.0.1", port=8765, max_requests=1) print(f"获取到token:{oauth_token}") sys.exit(0)
注意事项
- 上述方案仅适用于本地临时接收OAuth回调的场景,不要用于对外提供服务的生产环境
- 可提前检测端口是否被占用,避免启动失败,也可以动态分配闲置端口
- 建议加超时逻辑,避免用户长时间不操作导致后台进程残留
内容的提问来源于stack exchange,提问作者Phatmandrake
相关产品推荐
相关产品推荐

