I have callback function in a websocket subscribe method. I can't change the "subscribe" method.
How I can get the current strategy_id
inside get_msg
callback function from the current task that receives the message?
import asyncio
def get_msg(msg):
print(f"msg: {msg}")
async def main_ws(strategy_id):
hlq = HLClass.HLClass(strategy_id)
hlq.hl_info.subscribe({"type": "orderUpdates", "user": strategy_id}, get_msg) # get_msg = callback function from websocket recieve
if __name__ == '__main__':
loop = asyncio.get_event_loop()
strategy_list = [1,2,3,4]
for strategy in strategy_list:
asyncio.ensure_future(main_ws({'strategy_id': strategy}), loop=loop)
loop.run_forever()
Without knowing more about that subscribe
function, we can't know whether or not it's possible to request that extra args be passed to the callback. However, what you can do instead is create a closure. There are a number of ways to do this, but here's one example:
import asyncio
def main_ws(strategy_id):
hlq = HLClass(strategy_id)
def get_msg(msg): # This function 'captures' the local value of `strategy_id`
print(f"msg with id {strategy_id}: {msg}")
hlq.hl_info.subscribe({"type": "orderUpdates", "user": strategy_id}, get_msg)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
strategy_list = [1,2,3,4]
for strategy in strategy_list:
asyncio.ensure_future(main_ws({'strategy_id': strategy}), loop=loop)
loop.run_forever()
Notice that the only change I've made is moving definition get_msg
inside of main_ws
. In practice, what this means is that each time main_ws
is called, a new version of get_msg
is defined which has access to the local value of strategy_id
. This new version gets passed to subscribe
, and continues to exist until nothing needs it anymore.
If your callback is more complex, you might be interested in keeping its definition outside of main_ws
. In that case, you can do something like this:
def get_msg(msg, strategy_id):
print(f"msg with id {strategy_id}: {msg}")
def main_ws(strategy_id):
hlq = HLClass(strategy_id)
def callback(msg): # This function 'captures' the local value of `strategy_id`
get_msg(msg, strategy_id)
hlq.hl_info.subscribe({"type": "orderUpdates", "user": strategy_id}, callback)
Or make it more concise with a lambda, as suggested by JRiggles:
def get_msg(msg, strategy_id):
print(f"msg with id {strategy_id}: {msg}")
def main_ws(strategy_id):
hlq = HLClass(strategy_id)
hlq.hl_info.subscribe(
{"type": "orderUpdates", "user": strategy_id},
lambda msg: get_msg(msg, strategy_id),
)
These solutions are all doing the same thing, just with different style choices. Take your pick.