没有属性 response.status_code 的 grequests

grequests not having the attributes response.status_code

我能否获得有关如何使用 grequests 通过 VOLTTRON agent 执行 http 请求的提示?根据我对 VOLTTRON 的了解,我认为异步方法需要 grequests。

我的 VOLTTRON 代理代码的小片段,line 140 on git gist

    _log.info(f'*** [grequests INFO] *** -  onstart sucess!')
    self.core.schedule(cron('*/1 * * * *'), self.cron_function)


def cron_function(self):
    def simple_request(url):
        page = requests.get(url)
        return page

    _log.info(f'*** [grequests INFO] *** - starting CRON Processes')


    request = grequests.get(simple_request(self.url1))
    _log.info(f'*** [grequests INFO] *** - sending out {request}')

    response = grequests.send(request)

    _log.info(f'*** [grequests INFO] *** - response code {response.status_code}')
    _log.info(f'*** [grequests INFO] *** - response text {response.content}')

我安装代理时的回溯与没有属性 response.status_code 的 grequests 有关。我应该用 grequests 包装 requests 库以使我的脚本异步吗?抱歉这里没有太多智慧,但我只需要做一个 http 请求,我想我意识到我的代理代码需要异步以适应 VOLTTRON 平台上发生的所有其他事情。

2021-05-02 10:28:10,875 (grequesteragent-0.1 39693) <stderr> ERROR: Traceback (most recent call last):
2021-05-02 10:28:10,875 (grequesteragent-0.1 39693) <stderr> ERROR:   File "src/gevent/greenlet.py", line 854, in gevent._gevent_cgreenlet.Greenlet.run
2021-05-02 10:28:10,875 (grequesteragent-0.1 39693) <stderr> ERROR:   File "/home/dan/Desktop/volttron/volttron/platform/vip/agent/core.py", line 455, in wrapper
2021-05-02 10:28:10,875 (grequesteragent-0.1 39693) <stderr> ERROR:     event.function(*event.args, **event.kwargs)
2021-05-02 10:28:10,876 (grequesteragent-0.1 39693) <stderr> ERROR:   File "/home/dan/.volttron/agents/5b1bc704-ff6e-4d3d-a186-d5ec6b348686/grequesteragent-0.1/grequester/agent.py", line 153, in cron_function
2021-05-02 10:28:10,877 (grequesteragent-0.1 39693) <stderr> ERROR:     _log.info(f'*** [grequests INFO] *** - response code {response.status_code}')
2021-05-02 10:28:10,877 (grequesteragent-0.1 39693) <stderr> ERROR: AttributeError: 'gevent._gevent_cgreenlet.Greenlet' object has no attribute 'status_code'
2021-05-02 10:28:10,877 (grequesteragent-0.1 39693) <stderr> ERROR: 2021-05-02T15:20:00Z <Greenlet at 0x7f44a146c9d0: wrapper> failed with AttributeError
2021-05-02 10:28:10,877 (grequesteragent-0.1 39693) <stderr> ERROR:

来自我注释的 Ecobee 驱动程序的示例代码:

def call_grequest(method_name, url, **kwargs):
    """
    Make grequest calls to remote api
    :param method_name: method type - put/get/delete
    :param url: http URL suffix
    :param kwargs: Additional arguments for http request
    :return: grequest response
    """
    try:
        # Get the correct grequests method for the HTTP request type
        fn = getattr(grequests, method_name)
        # use that method with the url and any args to send the request
        request = fn(url, **kwargs)
        # use map to pull out the response
        response = grequests.map([request])[0]
        if response and isinstance(response, list):
            response = response[0]
        # handle cases were we receive a non-200 response
        response.raise_for_status()
        return response
    # handle specific error cases by logging a message and re-raising so we can handle it elsewhere
    except (ConnectionError, NewConnectionError) as e:
        _log.error(f"Error connecting to {url} with args {kwargs}: {e}")
        raise e


def make_ecobee_request(request_type, url, **kwargs):
    """
    Wrapper around making arbitrary GET and POST requests to remote Ecobee API
    :return: Ecobee API response using provided request content
    """
    # Generate appropriate grequests object
    # HTTP request method
    if request_type.lower() in ["get", "post"]:
        # we use verify so we can work with SSL
        response = call_grequest(request_type.lower(), url, verify=requests.certs.where(), timeout=30, **kwargs)
    else:
        raise ValueError(f"Unsupported request type {request_type} for Ecobee driver.")
    # Send request and extract data from response
    headers = response.headers
    # parse JSON content
    if "json" in headers.get("Content-Type"):
        return response.json()
    else:
        # parse Text content
        content = response.content
        if isinstance(content, bytes):
            content = jsonapi.loads(response.decode("UTF-8"))
        return content