Python中如何在Flask的一个接口内调用另一个接口?

redirect 的话,我没看懂怎么传参,好像无法传 json 的参数。
现在就是用 requests 的方式来调用的。
想问问有没有什么好的方式?
Python中如何在Flask的一个接口内调用另一个接口?

23 回复

django 的话有个 urlconfig, 用 requests 好像会丢失请求信息。


在Flask里,一个接口直接调用另一个接口,这事儿听起来有点绕,但其实挺常见的,比如内部重定向或者复用逻辑。最直接、最干净的办法不是用requests库去发HTTP请求(那是外部调用),而是直接调用目标视图函数,或者用Flask的测试客户端。下面我给你两个最实用的方法。

方法一:直接调用视图函数 这是最高效的方式,因为你跳过了HTTP层,直接执行函数。假设你有两个接口:

from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/api/process', methods=['POST'])
def process_data():
    # 这里是主处理逻辑
    data = request.get_json()
    result = {'processed': data.get('input', '') * 2}
    return jsonify(result), 200

@app.route('/api/main', methods=['POST'])
def main_endpoint():
    # 在这个接口里,我们需要调用 /api/process 的逻辑
    # 1. 模拟一个请求上下文,因为原函数可能需要访问 `request`
    with app.test_request_context(json={'input': 5}):
        # 2. 直接调用视图函数,并获取其返回值
        # 注意:这里返回的是 (response_object, status_code, headers_tuple)
        resp_tuple = process_data()
        # resp_tuple[0] 是Response对象,用 .get_json() 获取数据
        internal_result = resp_tuple[0].get_json()

    # 现在 internal_result 就是 {'processed': 10}
    # 你可以继续处理,然后返回
    final_response = {'main_result': internal_result, 'extra': 'done'}
    return jsonify(final_response), 200

if __name__ == '__main__':
    app.run(debug=True)

关键点:用app.test_request_context()来模拟一个请求环境,这样被调用的函数里的request.get_json()才能正常工作。调用后得到的是一个元组,你需要从中提取出响应数据。

方法二:使用Flask测试客户端 这个方法更接近“模拟一次内部请求”,代码更清晰,尤其适合复杂的请求(比如带headers、不同方法)。

from flask import Flask, jsonify, request
from flask.testing import FlaskClient

app = Flask(__name__)
# 创建一个测试客户端,但注意,它只在应用上下文中工作
client = app.test_client()

@app.route('/api/process', methods=['POST'])
def process_data():
    data = request.get_json()
    result = {'processed': data.get('input', '') * 2}
    return jsonify(result), 200

@app.route('/api/main', methods=['POST'])
def main_endpoint():
    # 使用测试客户端向另一个端点发起“内部”POST请求
    # 注意:这里发起的请求,会经过所有Flask中间件和装饰器
    internal_resp = client.post(
        '/api/process',
        json={'input': 5}, # 直接传json参数
        headers={'Content-Type': 'application/json'} # 通常test_client会自动设置
    )
    # internal_resp 是一个Response对象
    internal_result = internal_resp.get_json()

    final_response = {'main_result': internal_result, 'extra': 'done'}
    return jsonify(final_response), 200

if __name__ == '__main__':
    app.run(debug=True)

app.test_client()发起请求,代码意图非常清晰,就像在写测试一样。它也会走完整的Flask请求生命周期。

总结一下:

  • 要性能、轻量,选方法一:直接调函数,但要注意手动管理请求上下文。
  • 要清晰、省心,选方法二:用测试客户端,代码更像在发起一个“内部请求”,不容易出错。

核心建议:优先使用方法二,代码更干净。

你那个是用 class based view 的方式写的,还是 method 的方式;
如果是 methodd 的方式,它的参数不就是 reqeust, 你直接调那个方法就行;
如果是 class based view 的话,好像是 class.view 方法调用,记不得了

requests 请求的话,用起来倒是还没遇到问题,只是觉得不顺心。

直接调用方法,request 参数怎么传呢

路由里面的逻辑就不能抽成一个 util 方法 公共调用么?
为什么一定要在路由层互相调用呢?又不是跳转

mvc 要分层


大概这样
假如你的定义是:
(xxx):
def func1():
# 干点啥

(xx):
def func2():
return func1(request)

直接 redirect 过去里面应该是可以访问 request 上下文的吧

这样子能的话就太牛逼了!

楼主说说实际的应用场景?针对具体情况,应该有解决方案的

("/patha")
("/pathb")
def view_func():
pass

我就是想知道有没有这种方式。能抽象出来的事情我也知道的。

我就是想知道有没有这种直接调用另外一个接口的方法。实际场景还没有遇到过这种问题。

这个方法很明显不行。func1 都没有设定参数。

上下文我看了一下,没看懂。我再仔细看看。

传参的问题不好搞定。



redirect 怎么可能有 request 上下文…
redirect 使用的 http 的 301,302…相当于新的请求…只会带单次请求的数据…

实在不行…就存在 session 里面, 用 session_id 去取数据就行了


你这种使用方法有违这个框架的设计理念…
为什么一定要走这条路呢?

上面也有人说…要分层…每一层有自己的理念和作用…
非要违背去做…

这种深究有点奇怪…

额,我都说了,是大概,我没有写全而已,你 def 函数的时候肯定是有 request 的参数的嘛,我只是给了大概的伪代码

不要这样搞,分层是正确的道路。

路由 1 产生一个 json,然后发给路由 2 返回结果
那就应该把这个处理 json 的东西抽出来作一个函数,输入参数为 json,然后路由 1 和路由 2 都去调这个函数

,楼主你用 requests 调用遇到过 starting new HTTP connection ( 1 ):localhost:5000,卡着不动的情况吗,我这也是遇到了访问接口一,在接口一里调用了接口二,两个接口对应 localhost:5000 的不同 path

回到顶部