python - 如何使用 Python+aiohttp 获取 HTTP 403 响应的正文?

标签 python python-3.x rest http-status-code-403 aiohttp

我正在使用 Python 3.6 和 aiohttp 库向服务器发出 API Post 请求。如果我在发出请求时使用了错误的用户名,我会如预期收到 HTTP 403 错误。当我在 Postman 中发出此请求时,响应正文显示:

{"error_message": "No entitlements for User123"}

但是,当我使用 aiohttp 发出请求时,我在任何地方都看不到此响应正文。该消息只是说“禁止”。如何在我的 Python 代码中获取上述错误消息?

编辑:这是我的 aiohttp 代码,尽管它非常简单:

try:
    async with self.client_session.post(url, json=my_data, headers=my_headers) as response:
        return await response.json()
except ClientResponseError as e:
    print(e.message)  # I want to access the response body here
    raise e

编辑2:我找到了一个解决方法。当我创建 client_session 时,我将 raise_for_status 值设置为 False。然后,当我从 API 调用获得响应时,我检查状态是否 >= 400。如果是,我自己处理错误,其中包括响应正文。

编辑 3:这是我的解决方法的代码:

self.client_session = ClientSession(loop=asyncio.get_event_loop(), raise_for_status=False)
####################### turn off the default exception handling ---^

try:
    async with self.client_session.post(url, json=my_data, headers=my_headers) as response:
    body = await response.text()

    # handle the error myself so that I have access to the response text
    if response.status >= 400:
        print('Error is %s' % body)
        self.handle_error(response)

最佳答案

是的,如果您来自 requests 包,该包的异常对象具有 .request.response (或相反)属性,这可能确实令人困惑。

您显然已经弄清楚了这一点,但这里是 aiohttp 旧版本的正确答案。

async with session.post(...) as response:
    try:
        response.raise_for_status()
    except ClientResponseError as err:
        logger.error("Error: %s, Error body: %s", err, (await response.text()))

    return await response.json()

不幸的是,新版本一旦调用 raise_for_status() 就会回收连接,因此您以后无法获取错误正文。这是现在对我有用的东西(来自 http-noah 包):

        logger = structlog.get_logger(__name__)

        async with session.post(url, **req_kwargs) as res:
            # Fetching text as error just in case - raise_for_status() will
            # release the connection so the error body will be lost already.
            # The text will be cached in the response internally for the use later on
            # so no waste here.
            err_body = await res.text()
            try:
                res.raise_for_status()
            except aiohttp.ClientResponseError as err:
                logger.error("Request failed", err=err, err_body=err_body)
                raise

关于python - 如何使用 Python+aiohttp 获取 HTTP 403 响应的正文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55142824/

相关文章:

python - AppEngine 服务器无法导入 atom 模块

python - Rabbitmq - 在同一 channel 上消费和发布?

python - 比较两个字符串中的字符,无论其位置如何

C# 调用 REST 服务调用并提供证书

java - SpringMVC 处理剩余 Controller 中的错误

java - 如何将自定义类型作为参数传递给 RestEasy 服务?

python - 如何将实例转换为派生类?

python - Colorbar offsetText(科学基础乘数)从colorbar的顶部移动到底部

python - 我如何让这个 python 登录/注册程序工作? (我是Python新手)

python - 使用 for 循环限制程序的线程