Issue
I have a loop that when it finishes it returns a dataframe. This dataframe is then processed elsewhere within the app. Broadly speaking, in a sequenctial code, it looks like that:
import pandas as pd
def print_int_seq():
col_1 = []
col_2 = []
for i in range(10):
col_1.append(i)
col_2.append(2*i)
print(i)
return pd.DataFrame({'col_1': col_1, 'col_2': col_2})
def run_seq():
df = print_int_seq()
print(df)
if __name__ == "__main__":
run_seq()
I want now to have another function that will run asynchronously with the loop that returns the dataframe. I do not know how to do this please, ie return a value from an async/awaited function. If I didnt need to return anything the program (with the two async functions) would probably look like this:
import pandas as pd
from datetime import datetime
import asyncio
async def print_time(con):
while True:
print(datetime.now().time())
await asyncio.sleep(1)
async def print_int():
# I would like this to return the full 10x2 dataframe
col_1 = []
col_2 = []
for i in range(10):
col_1.append(i)
col_2.append(2*i)
print(i)
await asyncio.sleep(1)
async def main():
# how can I catch and process the 10x2 dataframe returned by print_int()?
await asyncio.gather(
print_time(con),
print_int(),
)
if __name__ == "__main__":
asyncio.run(main())
How can I edit the script above so when the loop is exhausted to catch the dataframe and handle it in another function please? Does it matter that loop in the other async function never ends?
Solution
First and most important: async mimic the behavior of functions a lot - if you want them to return a value, just add a return statement with whatever value you want to return:
async def print_int():
# I would like this to return the full 10x2 dataframe
col_1 = []
col_2 = []
for i in range(10):
...
return pd.Dataframe(...)
Second: asyncio.gather
simply returns a sequence with all return values of the executed tasks, and for that, it must wait until all "gathered" tasks return. If the other task were to be finite, and finshed more or less on the same time, you'd do:
async def main():
result1, result2 = await asyncio.gather(
print_time(con),
print_int(),
)
As you plan to have a concurrent routine that won't end at all, asyncio.gather is not the best thing to: just create a task for both co-routines and await the result of the task you want:
async def main():
# this will get the other co-routine running in the background:
asyncio.create_task(print_time(con))
result = await print_int()
Answered By - jsbueno
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.