Связывание запросов aiohttp с ответами - PullRequest
0 голосов
/ 29 апреля 2020

Я просто хотел бы связать ответы от асинхронных HTTP-запросов aiohttp с идентификатором. Я использую следующий код для обращения к API и извлечения объекта contactproperty, которому для вызова его API требуется внешнее поле (contacid):

def get_contact_properties(self, office_name, api_key, ids, chunk_size=100, **params):
    properties_pages = []
    batch = 0
    while True:

        chunk_ids = [ids[i] for i in range(batch * chunk_size + 1, chunk_size * (1 + batch) + 1)]
        urls = ["{}/{}".format(self.__get_base_url(), "contacts/{}/properties?api_key={}".format(contactid, api_key))
                for contactid in chunk_ids]

        responses_raw = self.get_responses(urls, self.get_office_token(office_name), chunk_size)
        try:
            responses_json = [json.loads(response_raw) for response_raw in responses_raw]
        except Exception as e:
            print(e)

        valid_responses = self.__get_valid_contact_properties_responses(responses_json)
        properties_pages.append(valid_responses)


        if len(valid_responses) < chunk_size:  # this is how we know there are no more pages with data
            break
        else:
            batch = batch + 1

ids - это list идентификаторов. Проблема в том, что я не знаю, какой ответ соответствует какому идентификатору, чтобы позже я мог связать его с контактной сущностью, используя contacid. Это моя функция fetch (), поэтому мне было интересно, как отредактировать эту функцию, чтобы она возвращала контакт и вывод.

async def __fetch(self, url, params, session):
    async with session.get(url, params=params) as response:
        output = await response.read()
        return (output)

async def __bound_fetch(self, sem, url, params, session):
    # Getter function with semaphore.
    async with sem:
        output = await self.__fetch(url, params, session)
        return output

1 Ответ

0 голосов
/ 01 мая 2020

Вы можете вернуть URL (или любой другой ключ, идентифицирующий ваш запрос) вместе с выводом .

Что касается использования данных, я думаю, что вы должны прочитать ответьте прямо как JSON, тем более что aiohttp может сделать это автоматически для вас.

async def __fetch(self, url, params, session):
    async with session.get(url, params=params) as response:
        try:
            data = await response.json()
        except ValueError as exc:
            print(exc)
            return None
        return data

async def __bound_fetch(self, sem, url, params, session):
    # Getter function with semaphore.
    async with sem:
        output = await self.__fetch(url, params, session)
        return {"url": url, "data": data}

Вы не опубликовали функцию get_responses, но я предполагаю, что что-то подобное должно работать:

responses = self.get_responses(urls, self.get_office_token(office_name), chunk_size)

Ответами будет список {"url": url, data: "data"} (данные могут быть Нет для недействительных ответов); однако с кодом выше один неверный запрос не повлияет на другие.

...