Объект «Response» не вызывается - PullRequest
0 голосов
/ 21 мая 2019

Я пытаюсь выполнить несколько POST запросов параллельно и получаю сообщение об ошибке: 'Response' Object is not callable

Я вижу, что выполняются запросы POST, и кажется, что ошибка возникает именно тогда, когда он пытается получить статус / содержимое ответа.

Я не хочу импортировать aiohttp

import asyncio
import concurrent.futures
import requests
import logging

async def fetchAllPostHttp(params, auth):
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        logger = logging.getLogger(__name__)
        logger.setLevel(config.LOG_LEVEL)

        loop = asyncio.get_event_loop()
        futures = []
        results = []

        for param in params:
            futures.append(loop.run_in_executor(
                executor, 
                requests.post(url=param['url'], json=param['data'], auth=auth)
            ))

        for response in await asyncio.gather(*futures):
            logger.debug(
            f"Received {response.status_code}: {response.content}")
            results.append(response.content)

        return results

def doMultipleHttpPostRequests(params, auth):
    loop = asyncio.get_event_loop()
    return loop.run_until_complete(fetchAllPostHttp(params, auth))

# Array of urls to post
myUrls = [
    {
        "url": "https://example.com",
        "data": {}
    }
]

# Invoking the method to issue multiple http requests
doMultipleHttpPostRequests(
    myUrls,
    auth=("xxx", "xxx")
)

1 Ответ

1 голос
/ 21 мая 2019

Эта строка неверна

futures.append(loop.run_in_executor(
                executor, 
                requests.post(url=param['url'], json=param['data'], auth=auth)
            ))

Вы должны передать функциональный объект, такой как requests.post, вместе с параметрами и передачей результата вызова этой функции requests.post(url=param['url'], json=param['data'], auth=auth) Таким образом, в основном интерпретатор прав, передавая объект Response, который исполнитель пытается вызвать как функция. Чтобы исправить это, используйте functools.partial, чтобы создать функцию с уже установленными аргументами, если вы хотите использовать аргументы с ключевыми словами, например:

func = functools.partial(requests.post,url=param['url'], json=param['data'], auth=auth)

futures.append(loop.run_in_executor(
                executor, 
                func))

Или передайте их вместе в правильном порядке, который requets.post ожидает так:

 for param in params:
            futures.append(loop.run_in_executor(
                executor,
                requests.post,param['url'],None, param['data'],
            ))

Обратите внимание, что вы не можете использовать аргументы ключевых слов здесь, поэтому убедитесь, что вы передаете их в правильном порядке, мне пришлось опустить auth во втором подходе, так как это не позиционный аргумент

...