I have an API endpoint which can take one or more object IDs and return responses for them, e.g., http://example.com/api/metadata?id=1&id=2&id=3. API endpoint is rate limited per call and not per ID, so it is better to call the API endpoint with many IDs.
On the other hand, I have existing code which tried to obtain metadata per ID, like:
async def get_metadata(object_id):
response = await session.get(f"http://example.com/api/metadata?id={object_id}")
response.raise_for_status()
return (await response.json())['results'][object_id]
I would like to keep the signature of this function the same but change it so that it does not do individual requests, but blocks until a) 50 IDs are ready to be fetched b) some timeout like 10 seconds occurs inside which some but not 50 IDs are ready to be fetched. Then one API request is made, and then each (blocked) call to get_metadata returns the corresponding result. So external behavior of get_metadata should stay the same.
I tried few things with using semaphore or queues, but I got stuck. So what would be a good approach to implement this?