1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

aiohttpライブラリを使用して非同期リクエストを行った時に、何回かに一回、asyncio.exceptions.TimeoutErrorが発生しました。
ローカル環境ではサーバーでエラーが出なかったため、原因に思い至るまでに試行錯誤して時間がかかったので、メモしておきます。

HTTPリクエストのテストコード

以下に、aiohttpを使用した非同期のGETリクエスト関数と、それに対するaioresponsesを使用したテストの例を示します。

test()はテストが通ります。
test_ngはaiohttp.client_exceptions.ClientConnectionError: Connection closedが発生してテストが通りません。
違いは、コンテキストマネージャasyncの内と外のどちらでresponse.text()を実行するかですね。
自分は最初、NGパターンの方でやっていて、相手先サーバーが正常にレスポンスを返しているログはあるのになんでタイムアウトエラーが出るんだろう?と不思議でしたが、書いてみるとasync with ブロックを抜けてからだとreadできないのがわかります。

import aiohttp
import pytest
from aioresponses import aioresponses


async def fetch_data_pattern_1(url):
    async with aiohttp.ClientSession(timeout=1) as session:
        async with session.get(url) as response:
            return await response.text()


async def fetch_data_pattern_2(url):
    async with aiohttp.ClientSession(timeout=1) as session:
        response = await session.get(url)
        return response


@pytest.mark.asyncio()
async def test():
    mock_response_content = "Hello World!"
    test_url = "http://example.com"

    with aioresponses() as mocked:
        mocked.get(
            test_url,
            body=mock_response_content,
        )
        response = await fetch_data_pattern_1(test_url)
        assert response == mock_response_content
        print(f"response: {response}")


@pytest.mark.asyncio()
async def test_ng():
    mock_response_content = "Hello World!"
    test_url = "http://example.com"

    with aioresponses() as mocked:
        mocked.get(
            test_url,
            body=mock_response_content,
        )
        response = await fetch_data_pattern_2(test_url)
    data = await response.text()
    assert data == mock_response_content

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?