|
from __future__ import annotations |
|
|
|
from abc import ABC, abstractmethod |
|
from pathlib import Path |
|
from typing import Any, Dict |
|
|
|
from gradio import processing_utils, utils |
|
|
|
|
|
class Serializable(ABC): |
|
@abstractmethod |
|
def serialize( |
|
self, x: Any, load_dir: str | Path = "", encryption_key: bytes | None = None |
|
): |
|
""" |
|
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, |
|
encryption_key: bytes | 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 = "", encryption_key: bytes | None = None |
|
) -> 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 |
|
encryption_key: Ignored |
|
""" |
|
return x |
|
|
|
def deserialize( |
|
self, |
|
x: Any, |
|
save_dir: str | Path | None = None, |
|
encryption_key: bytes | 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 |
|
encryption_key: Ignored |
|
""" |
|
return x |
|
|
|
|
|
class ImgSerializable(Serializable): |
|
def serialize( |
|
self, |
|
x: str | None, |
|
load_dir: str | Path = "", |
|
encryption_key: bytes | None = None, |
|
) -> 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 |
|
encryption_key: Used to encrypt the file |
|
""" |
|
if x is None or x == "": |
|
return None |
|
return processing_utils.encode_url_or_file_to_base64( |
|
Path(load_dir) / x, encryption_key=encryption_key |
|
) |
|
|
|
def deserialize( |
|
self, |
|
x: str | None, |
|
save_dir: str | Path | None = None, |
|
encryption_key: bytes | 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 |
|
encryption_key: Used to decrypt the file |
|
""" |
|
if x is None or x == "": |
|
return None |
|
file = processing_utils.decode_base64_to_file( |
|
x, dir=save_dir, encryption_key=encryption_key |
|
) |
|
return file.name |
|
|
|
|
|
class FileSerializable(Serializable): |
|
def serialize( |
|
self, |
|
x: str | None, |
|
load_dir: str | Path = "", |
|
encryption_key: bytes | None = None, |
|
) -> 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 |
|
encryption_key: Used to encrypt the file |
|
""" |
|
if x is None or x == "": |
|
return None |
|
filename = Path(load_dir) / x |
|
return { |
|
"name": filename, |
|
"data": processing_utils.encode_url_or_file_to_base64( |
|
filename, encryption_key=encryption_key |
|
), |
|
"orig_name": Path(filename).name, |
|
"is_file": False, |
|
} |
|
|
|
def deserialize( |
|
self, |
|
x: str | Dict | None, |
|
save_dir: Path | str | None = None, |
|
encryption_key: bytes | 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 |
|
encryption_key: Used to decrypt the file |
|
""" |
|
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, encryption_key=encryption_key |
|
).name |
|
elif isinstance(x, dict): |
|
if x.get("is_file", False): |
|
if utils.validate_url(x["name"]): |
|
file_name = x["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, encryption_key=encryption_key |
|
).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 = "", |
|
encryption_key: bytes | None = None, |
|
) -> 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 |
|
encryption_key: Ignored |
|
""" |
|
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, |
|
encryption_key: bytes | 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 |
|
encryption_key: Ignored |
|
""" |
|
if x is None: |
|
return None |
|
return processing_utils.dict_or_str_to_json_file(x, dir=save_dir).name |
|
|