class ConcurrentRunner: def __init__(self, max_concurrency=5): self.max_concurrency = 5 self.tasks = [] async def put(self, coro): """Starts a coroutine if there are 4 or less already running ones. """ # blocks until there's room while len(self.tasks) >= self.max_concurrency: await asyncio.sleep(0) fut = asyncio.create_task(coro()) self.tasks.append(fut) fut.add_done_callback(self.tasks.remove) return fut async def wait(self): """Wait for remaining routines to finish """ await asyncio.gather(*self.tasks)