So currently I have 4 api requests which are called in synchronous method using a third_party lib which is synchronous. What i want is to run them in parallel. So that my total time to call all 4 apis is reduced.
I am using fastapi as micro framework.
utilities.py
async def get_api_1_data():
data = some_third_party_lib()
return data
async def get_api_2_data():
data = some_third_party_lib()
return data
async def get_api_3_data():
data = some_third_party_lib()
return data
async def get_api_4_data():
data = some_third_party_lib()
return data
my main.py looks something like this
import asyncio
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def fetch_new_exposure_api_data(node: str):
functions_to_run = [get_api_1_data(), get_api_2_data(), get_api_3_data(), get_api_4_data()]
r1, r2, r3, r4 = await asyncio.gather(*functions_to_run)
return [r1, r2, r3, r4]
So the issue is i can not put await in front of some_third_party_lib()
as it's not a async lib it's a sync lib.
So is there any way i can convert them to async functionality to run them in parallel.
CodePudding user response:
Unfortunately, you cannot make a synchronous function asynchronous without changing its implementation. If some_third_party_lib()
is a synchronous function, you cannot make it run in parallel using the asyncio
library.
One workaround is to run each of the calls to some_third_party_lib()
in a separate thread. You can use the concurrent.futures
library in Python to create and manage a pool of worker threads. Here's an example setup that I came up with:
import concurrent.futures
def get_api_1_data():
return some_third_party_lib()
def get_api_2_data():
return some_third_party_lib()
def get_api_3_data():
return some_third_party_lib()
def get_api_4_data():
return some_third_party_lib()
@app.get("/")
async def fetch_new_exposure_api_data(node: str):
with concurrent.futures.ThreadPoolExecutor() as executor:
results = [executor.submit(fn) for fn in [get_api_1_data, get_api_2_data, get_api_3_data, get_api_4_data]]
return [result.result() for result in concurrent.futures.as_completed(results)]
This way, each call to some_third_party_lib()
will run in a separate thread and they will run in parallel. Note that the order of the results in the returned list may not match the order of the functions in the functions_to_run
list.