mirror of
https://github.com/Skyvern-AI/skyvern.git
synced 2026-05-05 07:10:22 +00:00
101 lines
3.6 KiB
Python
101 lines
3.6 KiB
Python
# This file was auto-generated by Fern from our API Definition.
|
|
|
|
"""
|
|
jsonable_encoder converts a Python object to a JSON-friendly dict
|
|
(e.g. datetimes to strings, Pydantic models to dicts).
|
|
|
|
Taken from FastAPI, and made a bit simpler
|
|
https://github.com/tiangolo/fastapi/blob/master/fastapi/encoders.py
|
|
"""
|
|
|
|
import base64
|
|
import dataclasses
|
|
import datetime as dt
|
|
from enum import Enum
|
|
from pathlib import PurePath
|
|
from types import GeneratorType
|
|
from typing import Any, Callable, Dict, List, Optional, Set, Union
|
|
|
|
import pydantic
|
|
|
|
from .datetime_utils import serialize_datetime
|
|
from .pydantic_utilities import (
|
|
IS_PYDANTIC_V2,
|
|
encode_by_type,
|
|
to_jsonable_with_fallback,
|
|
)
|
|
|
|
SetIntStr = Set[Union[int, str]]
|
|
DictIntStrAny = Dict[Union[int, str], Any]
|
|
|
|
|
|
def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None) -> Any:
|
|
custom_encoder = custom_encoder or {}
|
|
if custom_encoder:
|
|
if type(obj) in custom_encoder:
|
|
return custom_encoder[type(obj)](obj)
|
|
else:
|
|
for encoder_type, encoder_instance in custom_encoder.items():
|
|
if isinstance(obj, encoder_type):
|
|
return encoder_instance(obj)
|
|
if isinstance(obj, pydantic.BaseModel):
|
|
if IS_PYDANTIC_V2:
|
|
encoder = getattr(obj.model_config, "json_encoders", {}) # type: ignore # Pydantic v2
|
|
else:
|
|
encoder = getattr(obj.__config__, "json_encoders", {}) # type: ignore # Pydantic v1
|
|
if custom_encoder:
|
|
encoder.update(custom_encoder)
|
|
obj_dict = obj.dict(by_alias=True)
|
|
if "__root__" in obj_dict:
|
|
obj_dict = obj_dict["__root__"]
|
|
if "root" in obj_dict:
|
|
obj_dict = obj_dict["root"]
|
|
return jsonable_encoder(obj_dict, custom_encoder=encoder)
|
|
if dataclasses.is_dataclass(obj):
|
|
obj_dict = dataclasses.asdict(obj) # type: ignore
|
|
return jsonable_encoder(obj_dict, custom_encoder=custom_encoder)
|
|
if isinstance(obj, bytes):
|
|
return base64.b64encode(obj).decode("utf-8")
|
|
if isinstance(obj, Enum):
|
|
return obj.value
|
|
if isinstance(obj, PurePath):
|
|
return str(obj)
|
|
if isinstance(obj, (str, int, float, type(None))):
|
|
return obj
|
|
if isinstance(obj, dt.datetime):
|
|
return serialize_datetime(obj)
|
|
if isinstance(obj, dt.date):
|
|
return str(obj)
|
|
if isinstance(obj, dict):
|
|
encoded_dict = {}
|
|
allowed_keys = set(obj.keys())
|
|
for key, value in obj.items():
|
|
if key in allowed_keys:
|
|
encoded_key = jsonable_encoder(key, custom_encoder=custom_encoder)
|
|
encoded_value = jsonable_encoder(value, custom_encoder=custom_encoder)
|
|
encoded_dict[encoded_key] = encoded_value
|
|
return encoded_dict
|
|
if isinstance(obj, (list, set, frozenset, GeneratorType, tuple)):
|
|
encoded_list = []
|
|
for item in obj:
|
|
encoded_list.append(jsonable_encoder(item, custom_encoder=custom_encoder))
|
|
return encoded_list
|
|
|
|
def fallback_serializer(o: Any) -> Any:
|
|
attempt_encode = encode_by_type(o)
|
|
if attempt_encode is not None:
|
|
return attempt_encode
|
|
|
|
try:
|
|
data = dict(o)
|
|
except Exception as e:
|
|
errors: List[Exception] = []
|
|
errors.append(e)
|
|
try:
|
|
data = vars(o)
|
|
except Exception as e:
|
|
errors.append(e)
|
|
raise ValueError(errors) from e
|
|
return jsonable_encoder(data, custom_encoder=custom_encoder)
|
|
|
|
return to_jsonable_with_fallback(obj, fallback_serializer)
|