chainlit 异步以及同步转换处理简单说明
chainlit 提供了工具方法,可以方便的将同步转异步,同时将异步转同步
使用
- 同步转异步
from chainlit import make_async
def my_sync_function():
# Your synchronous code goes here
import time
time.sleep(10)
return 0
async_function = make_async(my_sync_function)
async def main():
result = await async_function()
- 异步转同步
from chainlit import run_sync
async def my_async_function():
# Your asynchronous code goes here
def main():
result = run_sync(my_async_function())
main()
内部处理
内部处理上chainlit使用了syncer以及asyncer 这几个包asyncer,是直接使用的,对于异步转同步,基于上下文进行了判断处理
- 参考处理
import sys
from typing import Any, Coroutine, TypeVar
if sys.version_info >= (3, 10):
from typing import ParamSpec
else:
from typing_extensions import ParamSpec
import asyncio
import threading
from asyncer import asyncify
from chainlit.context import context_var
from syncer import sync
make_async = asyncify
T_Retval = TypeVar("T_Retval")
T_ParamSpec = ParamSpec("T_ParamSpec")
T = TypeVar("T")
def run_sync(co: Coroutine[Any, Any, T_Retval]) -> T_Retval:
"""Run the coroutine synchronously."""
# Copy the current context
current_context = context_var.get()
# Define a wrapper coroutine that sets the context before running the original coroutine
async def context_preserving_coroutine():
# Set the copied context to the coroutine
context_var.set(current_context)
return await co
# Execute from the main thread in the main event loop
if threading.current_thread() == threading.main_thread():
return sync(context_preserving_coroutine())
else: # Execute from a thread in the main event loop
result = asyncio.run_coroutine_threadsafe(
context_preserving_coroutine(), loop=current_context.loop
)
return result.result()
参考资料
https://docs.chainlit.io/guides/sync-async
https://github.com/miyakogi/syncer
https://github.com/fastapi/asyncer