structure saas with tools
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import asyncio
|
||||
import functools
|
||||
import inspect
|
||||
|
||||
from fsspec.asyn import AsyncFileSystem, running_async
|
||||
|
||||
|
||||
def async_wrapper(func, obj=None):
|
||||
"""
|
||||
Wraps a synchronous function to make it awaitable.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
func : callable
|
||||
The synchronous function to wrap.
|
||||
obj : object, optional
|
||||
The instance to bind the function to, if applicable.
|
||||
|
||||
Returns
|
||||
-------
|
||||
coroutine
|
||||
An awaitable version of the function.
|
||||
"""
|
||||
|
||||
@functools.wraps(func)
|
||||
async def wrapper(*args, **kwargs):
|
||||
return await asyncio.to_thread(func, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class AsyncFileSystemWrapper(AsyncFileSystem):
|
||||
"""
|
||||
A wrapper class to convert a synchronous filesystem into an asynchronous one.
|
||||
|
||||
This class takes an existing synchronous filesystem implementation and wraps all
|
||||
its methods to provide an asynchronous interface.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
sync_fs : AbstractFileSystem
|
||||
The synchronous filesystem instance to wrap.
|
||||
"""
|
||||
|
||||
protocol = "async_wrapper"
|
||||
cachable = False
|
||||
|
||||
def __init__(self, fs, *args, asynchronous=None, **kwargs):
|
||||
if asynchronous is None:
|
||||
asynchronous = running_async()
|
||||
super().__init__(*args, asynchronous=asynchronous, **kwargs)
|
||||
self.sync_fs = fs
|
||||
self.protocol = self.sync_fs.protocol
|
||||
self._wrap_all_sync_methods()
|
||||
|
||||
@property
|
||||
def fsid(self):
|
||||
return f"async_{self.sync_fs.fsid}"
|
||||
|
||||
def _wrap_all_sync_methods(self):
|
||||
"""
|
||||
Wrap all synchronous methods of the underlying filesystem with asynchronous versions.
|
||||
"""
|
||||
excluded_methods = {"open"}
|
||||
for method_name in dir(self.sync_fs):
|
||||
if method_name.startswith("_") or method_name in excluded_methods:
|
||||
continue
|
||||
|
||||
attr = inspect.getattr_static(self.sync_fs, method_name)
|
||||
if isinstance(attr, property):
|
||||
continue
|
||||
|
||||
method = getattr(self.sync_fs, method_name)
|
||||
if callable(method) and not asyncio.iscoroutinefunction(method):
|
||||
async_method = async_wrapper(method, obj=self)
|
||||
setattr(self, f"_{method_name}", async_method)
|
||||
|
||||
@classmethod
|
||||
def wrap_class(cls, sync_fs_class):
|
||||
"""
|
||||
Create a new class that can be used to instantiate an AsyncFileSystemWrapper
|
||||
with lazy instantiation of the underlying synchronous filesystem.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
sync_fs_class : type
|
||||
The class of the synchronous filesystem to wrap.
|
||||
|
||||
Returns
|
||||
-------
|
||||
type
|
||||
A new class that wraps the provided synchronous filesystem class.
|
||||
"""
|
||||
|
||||
class GeneratedAsyncFileSystemWrapper(cls):
|
||||
def __init__(self, *args, **kwargs):
|
||||
sync_fs = sync_fs_class(*args, **kwargs)
|
||||
super().__init__(sync_fs)
|
||||
|
||||
GeneratedAsyncFileSystemWrapper.__name__ = (
|
||||
f"Async{sync_fs_class.__name__}Wrapper"
|
||||
)
|
||||
return GeneratedAsyncFileSystemWrapper
|
||||
Reference in New Issue
Block a user