“响应”对象不可调用

时间:2019-05-21 05:03:31

标签: python asynchronous python-requests python-asyncio

我正在尝试并行执行多个 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 个答案:

答案 0 :(得分:1)

这行是错误的

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,因为它不是位置参数