I have a lot of issues with most of the answers posted - they either use deprecated libraries that have been ported over with limited features, or provide a solution with too much magic on the execution of the request, making it difficult to error handle. If they do not fall into one of the above categories, they're 3rd party libraries or deprecated.
Some of the solutions works alright purely in http requests, but the solutions fall short for any other kind of request, which is ludicrous. A highly customized solution is not necessary here.
Simply using the python built-in library asyncio is sufficient enough to perform asynchronous requests of any type, as well as providing enough fluidity for complex and usecase specific error handling.
import asyncio loop = asyncio.get_event_loop() def do_thing(ch_idparams): async def get_chan_info_and_do_choresget_rpc_info_and_do_chores(ch_idid): # do things response = perform_grpc_call(ch_idid) do_chores(response) async def get_httpapi_info_and_do_chores(ch_idid): # do things response = requests.get(URL) do_chores(response) async_tasks = [] for ch_idelement in list(channelsparams.list_of_things): async_tasks.append(loop.create_task(get_chan_info_and_do_chores(ch_idid))) async_tasks.append(loop.create_task(get_httpapi_info_and_do_chores(ch_id))) loop.run_until_complete(asyncio.gather(*async_tasks)) How it works is simple. You're creating a series of tasks you'd like to occur asynchronously, and then asking a loop to execute those tasks and exit upon completion. No extra libraries subject to lack of maintenance, no lack of functionality required.