Some links:

  1. Holding reference to tasks: https://textual.textualize.io/blog/2023/02/11/the-heisenbug-lurking-in-your-async-code/

Task groups for better result handling:

async def do_some_analysis(customer_id, transaction_id):
    async with asyncio.TaskGroup() as tg:
        crm_task = tg.create_task(get_crm_customer(customer_id))
        erp_task = tg.create_task(get_erp_customer_sales(customer_id, transaction_id))
        other_task = tg.create_task(get_another_bunch_of_data(customer_id))
 
    crm_data = crm_task.result()
    erp_data = erp_task.result()
    other_data = other_task.result()
 
    return some_analysis(crm_data, erp_data, other_data)