Закрытие клиента httpx приводит к ошибке «RuntimeError: цикл событий закрыт»Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Закрытие клиента httpx приводит к ошибке «RuntimeError: цикл событий закрыт»

Сообщение Anonymous »

Мне необходимо поддерживать постоянный httpx-клиент в своем коде, чтобы использовать его пул соединений на протяжении всего срока службы моего приложения. Ниже приведена упрощенная версия моей реализации:

Код: Выделить всё

import asyncio
import weakref
from threading import Lock

import nest_asyncio
from httpx import AsyncClient

class Request:
_instance = None
_lock = Lock()
_loop: asyncio.AbstractEventLoop = None
_new_loop = False
_session = None

def __new__(cls):
if not cls._instance:
with cls._lock:
if not cls._instance:
instance = super().__new__(cls)
cls._instance = instance
weakref.finalize(instance, instance._close)

if cls._loop is None:
try:
cls._loop = asyncio.get_running_loop()
except RuntimeError:
cls._loop = asyncio.new_event_loop()
cls._new_loop = True
asyncio.set_event_loop(cls._loop)

if cls._new_loop:
# nest_asyncio.apply()
cls._loop.run_until_complete(cls.create_client())
else:
cls._loop.create_task(cls.create_client())

return cls._instance

@classmethod
async def create_client(cls):
cls._session = AsyncClient()

@classmethod
def _close(cls):
cls._loop.run_until_complete(cls.close())

if cls._new_loop:
cls._loop.close()

@classmethod
async def close(cls):
if cls._session:
await cls._session.aclose()

async def get(self, url):
try:
return await self._session.get(url)

except Exception:
return None

req = Request()

async def main():
result = await req.get('https://www.google.com')
if result:
print(result.text[:100])

asyncio.run(main())
Это приводит к ошибке RuntimeError: цикл событий закрыт:

Код: Выделить всё

...
await self._pool.aclose()
File "/home/user/.cache/pypoetry/virtualenvs/app-gEFTwlce-py3.12/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 313, in aclose
await self._close_connections(closing_connections)
File "/home/user/.cache/pypoetry/virtualenvs/app-gEFTwlce-py3.12/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 305, in _close_connections
await connection.aclose()
File "/home/user/.cache/pypoetry/virtualenvs/app-gEFTwlce-py3.12/lib/python3.12/site-packages/httpcore/_async/connection.py", line 171, in aclose
await self._connection.aclose()
File "/home/user/.cache/pypoetry/virtualenvs/app-gEFTwlce-py3.12/lib/python3.12/site-packages/httpcore/_async/http11.py", line 265, in aclose
await self._network_stream.aclose()
File "/home/user/.cache/pypoetry/virtualenvs/app-gEFTwlce-py3.12/lib/python3.12/site-packages/httpcore/_backends/anyio.py", line 55, in aclose
await self._stream.aclose()
File "/home/user/.cache/pypoetry/virtualenvs/app-gEFTwlce-py3.12/lib/python3.12/site-packages/anyio/streams/tls.py", line 201, in aclose
await self.transport_stream.aclose()
File "/home/user/.cache/pypoetry/virtualenvs/app-gEFTwlce-py3.12/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1287, in aclose
self._transport.close()
File "/nix/store/gmx7bwrwy6s0kk89ij5yj8r8ayai95x1-python3-3.12.5/lib/python3.12/asyncio/selector_events.py", line 1210, in close
super().close()
File "/nix/store/gmx7bwrwy6s0kk89ij5yj8r8ayai95x1-python3-3.12.5/lib/python3.12/asyncio/selector_events.py", line 875, in close
self._loop.call_soon(self._call_connection_lost, None)
File "/nix/store/gmx7bwrwy6s0kk89ij5yj8r8ayai95x1-python3-3.12.5/lib/python3.12/asyncio/base_events.py", line 795, in call_soon
self._check_closed()
File "/nix/store/gmx7bwrwy6s0kk89ij5yj8r8ayai95x1-python3-3.12.5/lib/python3.12/asyncio/base_events.py", line 541, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Единственный способ решить эту проблему — раскомментировать строку, содержащую neg_asyncio.apply(). Однако, поскольку пакет pest_asyncio в значительной степени основан на внутренних функциях asyncio и больше не поддерживается, я не заинтересован в его использовании в своем коде.
Мой вопрос: Почему цикл закрывается, когда я вызываю run_until_complete() (из функции _close()), которая создает новый цикл событий и немедленно вызывает AyncClient.aclose( ) функция? Как это исправить?
Для справки: тот же код работает и для aiohttp.ClientSession без необходимости использовать Nest_asyncio.

Подробнее здесь: https://stackoverflow.com/questions/791 ... -is-closed
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Закрытие клиента httpx приводит к ошибке «RuntimeError: цикл событий закрыт»
    Anonymous » » в форуме Python
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Закрытие клиента httpx приводит к ошибке «RuntimeError: цикл событий закрыт»
    Anonymous » » в форуме Python
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • RuntimeError («Цикл событий закрыт») в Django Rest Framework с генеративным искусственным интеллектом Google
    Anonymous » » в форуме Python
    0 Ответы
    32 Просмотры
    Последнее сообщение Anonymous
  • RuntimeError («Цикл событий закрыт») в Django Rest Framework с помощью Google Generative AI
    Anonymous » » в форуме Python
    0 Ответы
    27 Просмотры
    Последнее сообщение Anonymous
  • Asyncio вызывает ошибку «RuntimeError: цикл событий закрыт»
    Anonymous » » в форуме Python
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»