mirror of
https://github.com/xtekky/gpt4free.git
synced 2025-12-06 02:30:41 -08:00
Improve slim docker image example, clean up OpenaiChat provider (#2397)
* Improve slim docker image example, clean up OpenaiChat provider * Enhance event loop management for asynchronous generators * Fix attribute " shutdown_default_executor" not found in old python versions * asyncio file added with all async helpers
This commit is contained in:
parent
4be8e69ea2
commit
e4bfd9db5c
9 changed files with 104 additions and 336 deletions
65
g4f/providers/asyncio.py
Normal file
65
g4f/providers/asyncio.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from asyncio import AbstractEventLoop, runners
|
||||
from typing import Union, Callable, AsyncGenerator, Generator
|
||||
|
||||
from ..errors import NestAsyncioError
|
||||
|
||||
try:
|
||||
import nest_asyncio
|
||||
has_nest_asyncio = True
|
||||
except ImportError:
|
||||
has_nest_asyncio = False
|
||||
try:
|
||||
import uvloop
|
||||
has_uvloop = True
|
||||
except ImportError:
|
||||
has_uvloop = False
|
||||
|
||||
def get_running_loop(check_nested: bool) -> Union[AbstractEventLoop, None]:
|
||||
try:
|
||||
loop = asyncio.get_running_loop()
|
||||
# Do not patch uvloop loop because its incompatible.
|
||||
if has_uvloop:
|
||||
if isinstance(loop, uvloop.Loop):
|
||||
return loop
|
||||
if not hasattr(loop.__class__, "_nest_patched"):
|
||||
if has_nest_asyncio:
|
||||
nest_asyncio.apply(loop)
|
||||
elif check_nested:
|
||||
raise NestAsyncioError('Install "nest_asyncio" package | pip install -U nest_asyncio')
|
||||
return loop
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
# Fix for RuntimeError: async generator ignored GeneratorExit
|
||||
async def await_callback(callback: Callable):
|
||||
return await callback()
|
||||
|
||||
async def async_generator_to_list(generator: AsyncGenerator) -> list:
|
||||
return [item async for item in generator]
|
||||
|
||||
def to_sync_generator(generator: AsyncGenerator) -> Generator:
|
||||
loop = get_running_loop(check_nested=False)
|
||||
new_loop = False
|
||||
if loop is None:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
new_loop = True
|
||||
gen = generator.__aiter__()
|
||||
try:
|
||||
while True:
|
||||
yield loop.run_until_complete(await_callback(gen.__anext__))
|
||||
except StopAsyncIteration:
|
||||
pass
|
||||
finally:
|
||||
if new_loop:
|
||||
try:
|
||||
runners._cancel_all_tasks(loop)
|
||||
loop.run_until_complete(loop.shutdown_asyncgens())
|
||||
if hasattr(loop, "shutdown_default_executor"):
|
||||
loop.run_until_complete(loop.shutdown_default_executor())
|
||||
finally:
|
||||
asyncio.set_event_loop(None)
|
||||
loop.close()
|
||||
Loading…
Add table
Add a link
Reference in a new issue