File size: 6,584 Bytes
947e9b9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
from __future__ import annotations
from abc import ABC, abstractmethod
from pathlib import Path
from typing import Any, Dict
from gradio import processing_utils, utils
from gradio.context import Context
class Serializable(ABC):
@abstractmethod
def serialize(self, x: Any, load_dir: str | Path = ""):
"""
Convert data from human-readable format to serialized format for a browser.
"""
pass
@abstractmethod
def deserialize(
self,
x: Any,
save_dir: str | Path | None = None,
root_url: str | None = None,
):
"""
Convert data from serialized format for a browser to human-readable format.
"""
pass
class SimpleSerializable(Serializable):
def serialize(self, x: Any, load_dir: str | Path = "") -> Any:
"""
Convert data from human-readable format to serialized format. For SimpleSerializable components, this is a no-op.
Parameters:
x: Input data to serialize
load_dir: Ignored
"""
return x
def deserialize(
self,
x: Any,
save_dir: str | Path | None = None,
root_url: str | None = None,
):
"""
Convert data from serialized format to human-readable format. For SimpleSerializable components, this is a no-op.
Parameters:
x: Input data to deserialize
save_dir: Ignored
root_url: Ignored
"""
return x
class ImgSerializable(Serializable):
def serialize(
self,
x: str | None,
load_dir: str | Path = "",
) -> str | None:
"""
Convert from human-friendly version of a file (string filepath) to a seralized
representation (base64).
Parameters:
x: String path to file to serialize
load_dir: Path to directory containing x
"""
if x is None or x == "":
return None
is_url = utils.validate_url(x)
path = x if is_url else Path(load_dir) / x
return processing_utils.encode_url_or_file_to_base64(path)
def deserialize(
self,
x: str | None,
save_dir: str | Path | None = None,
root_url: str | None = None,
) -> str | None:
"""
Convert from serialized representation of a file (base64) to a human-friendly
version (string filepath). Optionally, save the file to the directory specified by save_dir
Parameters:
x: Base64 representation of image to deserialize into a string filepath
save_dir: Path to directory to save the deserialized image to
root_url: Ignored
"""
if x is None or x == "":
return None
file = processing_utils.decode_base64_to_file(x, dir=save_dir)
return file.name
class FileSerializable(Serializable):
def serialize(
self,
x: str | None,
load_dir: str | Path = "",
) -> Dict | None:
"""
Convert from human-friendly version of a file (string filepath) to a
seralized representation (base64)
Parameters:
x: String path to file to serialize
load_dir: Path to directory containing x
"""
if x is None or x == "":
return None
filename = str(Path(load_dir) / x)
return {
"name": filename,
"data": processing_utils.encode_url_or_file_to_base64(filename),
"orig_name": Path(filename).name,
"is_file": False,
}
def deserialize(
self,
x: str | Dict | None,
save_dir: Path | str | None = None,
root_url: str | None = None,
) -> str | None:
"""
Convert from serialized representation of a file (base64) to a human-friendly
version (string filepath). Optionally, save the file to the directory specified by `save_dir`
Parameters:
x: Base64 representation of file to deserialize into a string filepath
save_dir: Path to directory to save the deserialized file to
root_url: If this component is loaded from an external Space, this is the URL of the Space
"""
if x is None:
return None
if isinstance(save_dir, Path):
save_dir = str(save_dir)
if isinstance(x, str):
file_name = processing_utils.decode_base64_to_file(x, dir=save_dir).name
elif isinstance(x, dict):
if x.get("is_file", False):
if root_url is not None:
file_name = processing_utils.download_tmp_copy_of_file(
root_url + "file=" + x["name"],
access_token=Context.access_token,
dir=save_dir,
).name
else:
file_name = processing_utils.create_tmp_copy_of_file(
x["name"], dir=save_dir
).name
else:
file_name = processing_utils.decode_base64_to_file(
x["data"], dir=save_dir
).name
else:
raise ValueError(
f"A FileSerializable component cannot only deserialize a string or a dict, not a: {type(x)}"
)
return file_name
class JSONSerializable(Serializable):
def serialize(
self,
x: str | None,
load_dir: str | Path = "",
) -> Dict | None:
"""
Convert from a a human-friendly version (string path to json file) to a
serialized representation (json string)
Parameters:
x: String path to json file to read to get json string
load_dir: Path to directory containing x
"""
if x is None or x == "":
return None
return processing_utils.file_to_json(Path(load_dir) / x)
def deserialize(
self,
x: str | Dict,
save_dir: str | Path | None = None,
root_url: str | None = None,
) -> str | None:
"""
Convert from serialized representation (json string) to a human-friendly
version (string path to json file). Optionally, save the file to the directory specified by `save_dir`
Parameters:
x: Json string
save_dir: Path to save the deserialized json file to
root_url: Ignored
"""
if x is None:
return None
return processing_utils.dict_or_str_to_json_file(x, dir=save_dir).name
|