Как повторно использовать сеанс aiohttp и запуск main () - PullRequest
0 голосов
/ 23 февраля 2020

Я пытаюсь повторно использовать сеансы aiohttp, похоже, это работает, но каждый выбрасывает четное l oop закрыто. Запуск на Python 3.8 на windows 10. Я знаю, что есть проблема с событием l oop на Windows, это может быть связано.

Мне удалось разрешить он начинается с переключения l oop .run_until_complete обычными вызовами ожидания, но теперь у меня ошибка al oop.

У меня раньше не было этих ошибок. Я определяю main () non asyn c, используя l oop = get_event_l oop () и вызывая функции с помощью l oop .run_until_complete ().

Я замечаю странное поведение. Если я добавлю функцию, которая занимает немного времени перед завершением main (), ошибки Event loop is closed не будет.

import requests
from operator import itemgetter
from pprint import pprint

import aiohttp
import asyncio


DEBUG = True


async def fetch(url, session=None):
    if session:
        async with session.get(url) as response:
            if DEBUG:
                print(f'Session used, Status code: {response.status}\t {url}')
            return await response.json()
    else:
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                if DEBUG:
                    print(f'Status code: {response.status}\t {url}')
                return await response.json()


async def get_stories(url, session=None):
    """Get top stories from hacker news."""
    return await fetch(url, session)


async def get_story_details(id, session=None):
    """Get story details."""
    url = f"https://hacker-news.firebaseio.com/v0/item/{id}.json"
    response_dict = await fetch(url, session)
    details = {
        'title': response_dict['title'],
        'hn_link': f"http://news.ycombinator.com/item?id={id}",
        'comments': response_dict['descendants']
        }
    return details


async def main():
    async with aiohttp.ClientSession() as session:  # <- problem here
        url = "https://hacker-news.firebaseio.com/v0/topstories.json"
        stories_ids = await get_stories(url, session)
        print(f"Stories returned: {len(stories_ids)}")

        # fetch data for each submission
        submission_dicts = await asyncio.gather(
            *[get_story_details(story_id, session) for story_id in stories_ids[:30]])

        pprint(submission_dicts)


if __name__ == '__main__':
    asyncio.run(main())

Множество ошибок, которые выглядят так:

Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000022AFEB9CE50>
Traceback (most recent call last):
  File "C:\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
    self.close()
  File "C:\Python38\lib\asyncio\proactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "C:\Python38\lib\asyncio\base_events.py", line 715, in call_soon
    self._check_closed()
  File "C:\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
...