0

I have code for async REST API requests which should make quite a lot of asynchronous API requests (independent from each other), gather JSONs from results and return a list. I'm using asyncio and aiohttp for asynchronous bits.

My code:

async def async_get_clients_events(
    client: ApiClient,
    client_tokens: List[ClientToken]
):
    async with ClientSession() as session:
        tasks = [
            async_get_single_organization_events(
                client, ct.client_id, ct.private_token, session
            )
            for ct in client_tokens
        ]

        results = await asyncio.gather(*tasks)

    return results


async def async_get_single_client_events(
    client: ApiClient,
    client_id: str,
    api_key: Optional[str] = None,
    session: ClientSession = None,
) -> List[Dict]:
    if api_key is not None:
        headers = get_default_headers()
        headers["Authorization"] = "Bearer " + client.api_key
    else:
        headers = get_default_headers()

    # prepare request parameters, a bit of code omitted

    events = await asyncio.gather(async_get(session, url, headers, return_json=True))

    return events


async def async_get(
    session: ClientSession,
    url: str,
    headers: Dict[str, str] = None,
    params: Dict[str, Any] = None,
    return_json: bool = True,
) -> ClientResponse:
    headers = headers if headers is not None else {}
    params = params if params is not None else {}

    response = await session.request(
        method="GET", url=url, headers=headers, params=params
    )
    response.raise_for_status()
    if return_json:
        return await response.json()
    else:
        return response

Question: how can I gather results in async_get_clients_events? I just want the requests to be asynchronous, after that I want to wait for all results and gather them.

qalis
  • 1,314
  • 1
  • 16
  • 44

1 Answers1

0

It turns out that async functions in Python are not functions, but coroutines and they are not run when called. They are more like class objects and require separate method call for actually executing them.

The above code was executed with async_get_clients_events(client, client_tokens) call, which I thought was obviously right. It's not. The fixed verion:

task = async_get_organizations_events(self, organizations_tokens)
results = asyncio.run(task)

SO questions I got this from: link 1, link 2.

qalis
  • 1,314
  • 1
  • 16
  • 44