0

I want to respond to a flask request, but the response is to be received from a socketio callback event. I am able to receive the response to an independent function, but unable to fetch it from there this is my main file

@app.route("/api/<token>")
def recharge(token):
    socket_connected_user_index = next((i for i, x in enumerate(clients) if x["name"] == token), None)
    if socket_connected_user_index is not None:
        user = clients[socket_connected_user_index]['name']
        socket_id = clients[socket_connected_user_index]['id']

        number = request.args['number']
        amount = request.args['amount']
        pin = request.args['pin']
        api_key = token

        recharge_data = dict(number=number,amount=amount,pin=pin,api_key=api_key)
        def server_callback(data):
            print('server call back >> ' , data)
            new_data = data
            return new_data
        response_from_function = socketio.emit('recharge_request', {'data': recharge_data},to=socket_id,callback=server_callback)
        return jsonify(response_from_function)
    else:
        return jsonify({"status":"User not connected"})

I am unable to access the variable "response_from_function"

response_from_function = socketio.emit('recharge_request', {'data': recharge_data},to=socket_id,callback=server_callback)

right now when i call "/api/?params" i get None as a response

I want to fetch the return value from the function "server_callback" and return that value to the user as a response to the request

Let me know if anyone has any idea Thanks

1 Answers1

0

The problem is that you are not waiting for the callback to execute, you are returning immediately after the emit. The emit work happens asynchronously, if not there would not be a need to use callbacks. Also the return value of the callback is not used for anything, you have to store your data in a variable to pass it to the main function.

You can use an event object to wait for your callback to execute:

@app.route("/api/<token>")
def recharge(token):
    # ...
        ev = threading.Event()
        new_data = None

        def server_callback(data):
            nonlocal new_data
            print('server call back >> ' , data)
            new_data = data
            ev.set()

        socketio.emit('recharge_request', {'data': recharge_data},to=socket_id,callback=server_callback)
        ev.wait()
        return jsonify(new_data)

The socketio.call() function sort of does all this for you, so you may want to look into that too:

        data = socketio.call('recharge_request', {'data': recharge_data},to=socket_id)
        new_data = ... # calculate new data here
        return jsonify(new_data)
Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152