AIOHTTP 在调用 raise_for_status 时有请求 body/content/text
AIOHTTP having request body/content/text when calling raise_for_status
我将 FastAPI
与 aiohttp
一起使用,我为持久性 session 构建了一个单例,我用它在启动时打开 session 并且在关机时关闭它。
需求:response
body在失败的情况下很珍贵我必须用其他细节。
因为 raise_for_status
的行为方式,我不得不编写那些处理每个 HTTP 方法的丑陋函数,这是其中之一:
async def post(self, url: str, json: dict, headers: dict) -> ClientResponse:
response = await self.session.post(url=url, json=json, headers=headers)
response_body = await response.text()
try:
response.raise_for_status()
except Exception:
logger.exception('Request failed',
extra={'url': url, 'json': json, 'headers': headers, 'body': response_body})
raise
return response
如果我能指望 raise_for_status
到 return 还有 body (response.text()
),
我可以启动 session ClientSession(raise_for_status=True)
并编写一个干净的代码:
response = await self.session.post(url=url, json=json, headers=headers)
有没有办法以某种方式强制 raise_for_status
到 return 以及 payload/body,也许在 ClientSession
的初始化中?
感谢您的帮助。
aiohttp
和 raise_for_status
是不可能的。正如@Andrew Svetlov 回答的那样 here:
Consider response as closed after raising an exception.
Technically it can contain a partial body but there is no any guarantee.
There is no reason to read it, the body could be very huge, 1GiB is not a limit.
If you need a response content for non-200 -- read it explicitly.
或者,考虑以这种方式使用 httpx 库。 (广泛与FastAPI结合使用):
def raise_on_4xx_5xx(response):
response.raise_for_status()
async with httpx.AsyncClient(event_hooks={'response': [raise_on_4xx_5xx]}) as client:
try:
r = await client.get('http://httpbin.org/status/418')
except httpx.HTTPStatusError as e:
print(e.response.text)
我将 FastAPI
与 aiohttp
一起使用,我为持久性 session 构建了一个单例,我用它在启动时打开 session 并且在关机时关闭它。
需求:response
body在失败的情况下很珍贵我必须用其他细节。
因为 raise_for_status
的行为方式,我不得不编写那些处理每个 HTTP 方法的丑陋函数,这是其中之一:
async def post(self, url: str, json: dict, headers: dict) -> ClientResponse:
response = await self.session.post(url=url, json=json, headers=headers)
response_body = await response.text()
try:
response.raise_for_status()
except Exception:
logger.exception('Request failed',
extra={'url': url, 'json': json, 'headers': headers, 'body': response_body})
raise
return response
如果我能指望 raise_for_status
到 return 还有 body (response.text()
),
我可以启动 session ClientSession(raise_for_status=True)
并编写一个干净的代码:
response = await self.session.post(url=url, json=json, headers=headers)
有没有办法以某种方式强制 raise_for_status
到 return 以及 payload/body,也许在 ClientSession
的初始化中?
感谢您的帮助。
aiohttp
和 raise_for_status
是不可能的。正如@Andrew Svetlov 回答的那样 here:
Consider response as closed after raising an exception. Technically it can contain a partial body but there is no any guarantee. There is no reason to read it, the body could be very huge, 1GiB is not a limit. If you need a response content for non-200 -- read it explicitly.
或者,考虑以这种方式使用 httpx 库。 (广泛与FastAPI结合使用):
def raise_on_4xx_5xx(response):
response.raise_for_status()
async with httpx.AsyncClient(event_hooks={'response': [raise_on_4xx_5xx]}) as client:
try:
r = await client.get('http://httpbin.org/status/418')
except httpx.HTTPStatusError as e:
print(e.response.text)