在Jupyter中直接调用带JSON参数的Flask路由函数的方法
问题:在Jupyter中直接调用带JSON参数的Flask路由函数
我在学习Flask和Jupyter配合使用时搭建了一个简单服务器,目前能在Jupyter单元格里直接调用无参数的Flask路由函数,但调用需要传入JSON参数的serverAPI_ejemplo函数时遇到阻碍。虽然已经能用test_client通过HTTP请求完成测试,但希望能在Python执行环境中直接调用该函数,不走TCP/IP栈,以此适配学习与教学场景。
服务器代码
#%% ALL server logic from flask import Flask,jsonify,request,make_response app = Flask(__name__) @app.route('/') def nakedRoute(): print('inside the teapot') return "I'm a teapot", 418 @app.route('/echo/', methods=['POST']) def serverAPI_ejemplo(): try: if not request.is_json: return make_response(jsonify({"error": "I was expecting a JSON"}), 400) data = request.json['key'] + 1 return jsonify({"key":data}), 200 # Código de estado 200 (OK) except Exception as e: return make_response(jsonify({"error": 33}), 500) #%% Mount the server if __name__ == "__main__": app.run(port=5000, debug=True)
未完成的直接调用测试代码
# %% TEST /echo/ for a JSON with app.app_context(): my_JSON = {"key":33} #...??? result= serverAPI_ejemplo() print(result)
已实现的HTTP测试代码
# %% IT WORKS !!!! if my_JSON == None: my_JSON = {"key":33} with app.test_client() as c: headers = {"Content-Type": "application/json; charset=utf-8"} response = c.post('/echo/', headers=headers, json=my_JSON) print(response.get_json()) my_JSON = response.json
解决方案
Flask的request对象依赖请求上下文,直接调用路由函数时需要手动模拟请求环境,以下提供两种可行方案:
方案1:模拟请求上下文(不修改原有路由)
利用app.test_request_context()创建符合要求的请求上下文,让request对象能正常读取JSON参数:
# %% 直接调用路由函数的测试代码 with app.app_context(): # 构造POST请求上下文,传入JSON数据与对应请求头 with app.test_request_context('/echo/', method='POST', json={"key":33}): result = serverAPI_ejemplo() # 解析返回的Response对象 print(result.get_json())
方案2:修改路由函数,支持直接传参
给路由函数增加参数分支,既保留HTTP请求处理逻辑,也支持直接传入Python数据:
# 修改后的路由函数 @app.route('/echo/', methods=['POST']) def serverAPI_ejemplo(data=None): try: # 直接调用时使用传入的data参数 if data is not None: processed_data = data['key'] + 1 return jsonify({"key": processed_data}), 200 # 处理HTTP请求的原有逻辑 if not request.is_json: return make_response(jsonify({"error": "I was expecting a JSON"}), 400) data = request.json['key'] + 1 return jsonify({"key":data}), 200 except Exception as e: return make_response(jsonify({"error": 33}), 500) # 直接调用的测试代码 with app.app_context(): my_JSON = {"key":33} result = serverAPI_ejemplo(data=my_JSON) print(result.get_json())
两种方案说明:
- 方案1完全保留原有代码逻辑,适合需要维持路由函数原生形态的场景;
- 方案2更直观,能清晰展示函数的两种调用方式,适合教学演示。
内容的提问来源于stack exchange,提问作者AsperusMe
相关产品推荐
相关产品推荐

