structure saas with tools
This commit is contained in:
121
.venv/lib/python3.10/site-packages/fsspec/json.py
Normal file
121
.venv/lib/python3.10/site-packages/fsspec/json.py
Normal file
@@ -0,0 +1,121 @@
|
||||
import json
|
||||
from contextlib import suppress
|
||||
from pathlib import PurePath
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
ClassVar,
|
||||
Dict,
|
||||
List,
|
||||
Mapping,
|
||||
Optional,
|
||||
Sequence,
|
||||
Tuple,
|
||||
)
|
||||
|
||||
from .registry import _import_class, get_filesystem_class
|
||||
from .spec import AbstractFileSystem
|
||||
|
||||
|
||||
class FilesystemJSONEncoder(json.JSONEncoder):
|
||||
include_password: ClassVar[bool] = True
|
||||
|
||||
def default(self, o: Any) -> Any:
|
||||
if isinstance(o, AbstractFileSystem):
|
||||
return o.to_dict(include_password=self.include_password)
|
||||
if isinstance(o, PurePath):
|
||||
cls = type(o)
|
||||
return {"cls": f"{cls.__module__}.{cls.__name__}", "str": str(o)}
|
||||
|
||||
return super().default(o)
|
||||
|
||||
def make_serializable(self, obj: Any) -> Any:
|
||||
"""
|
||||
Recursively converts an object so that it can be JSON serialized via
|
||||
:func:`json.dumps` and :func:`json.dump`, without actually calling
|
||||
said functions.
|
||||
"""
|
||||
if isinstance(obj, (str, int, float, bool)):
|
||||
return obj
|
||||
if isinstance(obj, Mapping):
|
||||
return {k: self.make_serializable(v) for k, v in obj.items()}
|
||||
if isinstance(obj, Sequence):
|
||||
return [self.make_serializable(v) for v in obj]
|
||||
|
||||
return self.default(obj)
|
||||
|
||||
|
||||
class FilesystemJSONDecoder(json.JSONDecoder):
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
object_hook: Optional[Callable[[Dict[str, Any]], Any]] = None,
|
||||
parse_float: Optional[Callable[[str], Any]] = None,
|
||||
parse_int: Optional[Callable[[str], Any]] = None,
|
||||
parse_constant: Optional[Callable[[str], Any]] = None,
|
||||
strict: bool = True,
|
||||
object_pairs_hook: Optional[Callable[[List[Tuple[str, Any]]], Any]] = None,
|
||||
) -> None:
|
||||
self.original_object_hook = object_hook
|
||||
|
||||
super().__init__(
|
||||
object_hook=self.custom_object_hook,
|
||||
parse_float=parse_float,
|
||||
parse_int=parse_int,
|
||||
parse_constant=parse_constant,
|
||||
strict=strict,
|
||||
object_pairs_hook=object_pairs_hook,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def try_resolve_path_cls(cls, dct: Dict[str, Any]):
|
||||
with suppress(Exception):
|
||||
fqp = dct["cls"]
|
||||
|
||||
path_cls = _import_class(fqp)
|
||||
|
||||
if issubclass(path_cls, PurePath):
|
||||
return path_cls
|
||||
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def try_resolve_fs_cls(cls, dct: Dict[str, Any]):
|
||||
with suppress(Exception):
|
||||
if "cls" in dct:
|
||||
try:
|
||||
fs_cls = _import_class(dct["cls"])
|
||||
if issubclass(fs_cls, AbstractFileSystem):
|
||||
return fs_cls
|
||||
except Exception:
|
||||
if "protocol" in dct: # Fallback if cls cannot be imported
|
||||
return get_filesystem_class(dct["protocol"])
|
||||
|
||||
raise
|
||||
|
||||
return None
|
||||
|
||||
def custom_object_hook(self, dct: Dict[str, Any]):
|
||||
if "cls" in dct:
|
||||
if (obj_cls := self.try_resolve_fs_cls(dct)) is not None:
|
||||
return AbstractFileSystem.from_dict(dct)
|
||||
if (obj_cls := self.try_resolve_path_cls(dct)) is not None:
|
||||
return obj_cls(dct["str"])
|
||||
|
||||
if self.original_object_hook is not None:
|
||||
return self.original_object_hook(dct)
|
||||
|
||||
return dct
|
||||
|
||||
def unmake_serializable(self, obj: Any) -> Any:
|
||||
"""
|
||||
Inverse function of :meth:`FilesystemJSONEncoder.make_serializable`.
|
||||
"""
|
||||
if isinstance(obj, dict):
|
||||
obj = self.custom_object_hook(obj)
|
||||
if isinstance(obj, dict):
|
||||
return {k: self.unmake_serializable(v) for k, v in obj.items()}
|
||||
if isinstance(obj, (list, tuple)):
|
||||
return [self.unmake_serializable(v) for v in obj]
|
||||
|
||||
return obj
|
||||
Reference in New Issue
Block a user