Разбор примера с асинхронными запросами

В базовом примере aiohttp всё очень сложно. Для чего такие сложности с контекстами?

async with aiohttp.ClientSession() as session:
    async with session.get('http://httpbin.org/get') as resp:
        print(resp.status)
        print(await resp.text())

Зачем тут используется второй, вложенный контекст. Какую роль он играет? Более того, он почему-то делает await (ну или просто подвисает), хотя в коде этого явно не указано. Также почему-то происходит await resp.text(). Зачем он нужен, если он есть на уровне get-request?


Один из возможных способов использования следующий

resp = await session.get()
await resp.text()
await resp.close()

Вопрос. Что происходит в каждой строке? Почему используется 3 await, вместо 1?


Часть ответа есть здесь. Но пока что не ясно, для чего использовать await с close?


Ответы (1 шт):

Автор решения: eri
async with aiohttp.ClientSession() as session:
    async with session.get('http://httpbin.org/get') as resp:
        print(resp.status)
        print(await resp.text())

Переписывается это на 5 await (хотя на мой взглад тут нужно 6), так:

session = await aiohttp.ClientSession() 

первый await - возможна работа с файлами, с куками, например. await нужен чтоб не блокировать паралельные таски если есть. Готовит несколько сокетов на коннекты.

resp = await session.get('http://httpbin.org/get')

Установка соединения и отправка запроса - тут понятно. Получение ответа началось.

print(resp.status)

на get клиент читает первые строки ответа, до \r\n\r\n - вместе с хидерами.

print(await resp.text())

Перед тем как читать остальной текст можно решить нужен ли он нам. там может быть и видео на 100ГБ и ничего.

await resp.close()

Дальше нужно закрыть соединение и вернуть сокет в сессию, чтоб им пожно было воспользоваться ещё раз.

await session.close()

Записать куки, закрыть сокеты.

→ Ссылка