Skip to content

Commit

Permalink
Use the modern lower-case Python types in the API typing information (#…
Browse files Browse the repository at this point in the history
…10196)

* changes

* add changeset

* add changeset

* add changeset

* changes

* format backend

* format

* fix imagedata

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
  • Loading branch information
abidlabs and gradio-pr-bot authored Dec 13, 2024
1 parent b4004e3 commit c9ba9a4
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 40 deletions.
6 changes: 6 additions & 0 deletions .changeset/all-tables-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"gradio": patch
"gradio_client": patch
---

feat:Use the modern lower-case Python types in the API typing information
10 changes: 6 additions & 4 deletions client/python/gradio_client/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -906,9 +906,11 @@ def get_type(schema: dict):

FILE_DATA_FORMATS = [
"Dict(path: str | None (Path to a local file), url: str | None (Publicly available url or base64 encoded image), size: int | None (Size of image in bytes), orig_name: str | None (Original filename), mime_type: str | None (mime type of image), is_stream: bool (Can always be set to False), meta: Dict())",
"dict(path: str | None (Path to a local file), url: str | None (Publicly available url or base64 encoded image), size: int | None (Size of image in bytes), orig_name: str | None (Original filename), mime_type: str | None (mime type of image), is_stream: bool (Can always be set to False), meta: dict())",
"Dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None)",
"Dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None, is_stream: bool)",
"Dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None, is_stream: bool, meta: Dict())",
"dict(path: str, url: str | None, size: int | None, orig_name: str | None, mime_type: str | None, is_stream: bool, meta: dict())",
]

CURRENT_FILE_DATA_FORMAT = FILE_DATA_FORMATS[-1]
Expand Down Expand Up @@ -953,15 +955,15 @@ def _json_schema_to_python_type(schema: Any, defs) -> str:
elements = ", ".join(
[_json_schema_to_python_type(i, defs) for i in items["prefixItems"]]
)
return f"Tuple[{elements}]"
return f"tuple[{elements}]"
elif "prefixItems" in schema:
elements = ", ".join(
[_json_schema_to_python_type(i, defs) for i in schema["prefixItems"]]
)
return f"Tuple[{elements}]"
return f"tuple[{elements}]"
else:
elements = _json_schema_to_python_type(items, defs)
return f"List[{elements}]"
return f"list[{elements}]"
elif type_ == "object":

def get_desc(v):
Expand All @@ -980,7 +982,7 @@ def get_desc(v):
f"str, {_json_schema_to_python_type(schema['additionalProperties'], defs)}"
]
des = ", ".join(des)
return f"Dict({des})"
return f"dict({des})"
elif type_ in ["oneOf", "anyOf"]:
desc = " | ".join([_json_schema_to_python_type(i, defs) for i in schema[type_]])
return desc
Expand Down
10 changes: 5 additions & 5 deletions client/python/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ def test_numerical_to_label_space(self):
"label": "output",
"type": {"type": {}, "description": "any valid json"},
"python_type": {
"type": "Dict[Any, Any]",
"type": "dict[Any, Any]",
"description": "any valid json",
},
"component": "Label",
Expand Down Expand Up @@ -954,7 +954,7 @@ def test_numerical_to_label_space(self):
"label": "output",
"type": {"type": {}, "description": "any valid json"},
"python_type": {
"type": "Dict[Any, Any]",
"type": "dict[Any, Any]",
"description": "any valid json",
},
"component": "Label",
Expand Down Expand Up @@ -994,7 +994,7 @@ def test_numerical_to_label_space(self):
"label": "output",
"type": {"type": {}, "description": "any valid json"},
"python_type": {
"type": "Dict[Any, Any]",
"type": "dict[Any, Any]",
"description": "any valid json",
},
"component": "Label",
Expand Down Expand Up @@ -1130,15 +1130,15 @@ def test_file_io(self, file_io_demo):
outputs = info["named_endpoints"]["/predict"]["returns"]

assert inputs[0]["type"]["type"] == "array"
assert inputs[0]["python_type"]["type"] == "List[filepath]"
assert inputs[0]["python_type"]["type"] == "list[filepath]"

assert isinstance(inputs[0]["example_input"], list)
assert isinstance(inputs[0]["example_input"][0], dict)

assert inputs[1]["python_type"]["type"] == "filepath"
assert isinstance(inputs[1]["example_input"], dict)

assert outputs[0]["python_type"]["type"] == "List[filepath]"
assert outputs[0]["python_type"]["type"] == "list[filepath]"
assert outputs[0]["type"]["type"] == "array"

assert outputs[1]["python_type"]["type"] == "filepath"
Expand Down
12 changes: 6 additions & 6 deletions client/python/test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,27 +160,27 @@ def test_json_schema_to_python_type(schema):
elif schema == "StringSerializable":
answer = "str"
elif schema == "ListStringSerializable":
answer = "List[str]"
answer = "list[str]"
elif schema == "BooleanSerializable":
answer = "bool"
elif schema == "NumberSerializable":
answer = "float"
elif schema == "ImgSerializable":
answer = "str"
elif schema == "FileSerializable":
answer = "str | Dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file)) | List[str | Dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file))]"
answer = "str | dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file)) | list[str | dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file))]"
elif schema == "JSONSerializable":
answer = "str | float | bool | list | dict"
elif schema == "GallerySerializable":
answer = "Tuple[Dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file)), str | None]"
answer = "tuple[dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file)), str | None]"
elif schema == "SingleFileSerializable":
answer = "str | Dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file))"
answer = "str | dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file))"
elif schema == "MultipleFileSerializable":
answer = "List[str | Dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file))]"
answer = "list[str | dict(name: str (name of file), data: str (base64 representation of file), size: int (size of image in bytes), is_file: bool (true if the file has been uploaded to the server), orig_name: str (original name of the file))]"
elif schema == "SingleFile":
answer = "str"
elif schema == "MultipleFile":
answer = "List[str]"
answer = "list[str]"
else:
raise ValueError(f"This test has not been modified to check {schema}")
assert utils.json_schema_to_python_type(types[schema]) == answer
Expand Down
50 changes: 25 additions & 25 deletions test/test_api_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

class StringModel(GradioModel):
data: str
answer: ClassVar = "Dict(data: str)"
answer: ClassVar = "dict(data: str)"


class IntegerRootModel(GradioRootModel):
Expand All @@ -27,31 +27,31 @@ class IntegerRootModel(GradioRootModel):
class FloatModel(GradioModel):
data: float

answer: ClassVar = "Dict(data: float)"
answer: ClassVar = "dict(data: float)"


class ListModel(GradioModel):
items: list[int]

answer: ClassVar = "Dict(items: List[int])"
answer: ClassVar = "dict(items: list[int])"


class DictModel(GradioModel):
data_dict: dict[str, int]

answer: ClassVar = "Dict(data_dict: Dict(str, int))"
answer: ClassVar = "dict(data_dict: dict(str, int))"


class DictModel2(GradioModel):
data_dict: dict[str, list[float]]

answer: ClassVar = "Dict(data_dict: Dict(str, List[float]))"
answer: ClassVar = "dict(data_dict: dict(str, list[float]))"


class OptionalModel(GradioModel):
optional_data: Optional[int]

answer: ClassVar = "Dict(optional_data: int | None)"
answer: ClassVar = "dict(optional_data: int | None)"


class ColorEnum(Enum):
Expand All @@ -63,85 +63,85 @@ class ColorEnum(Enum):
class EnumRootModel(GradioModel):
color: ColorEnum

answer: ClassVar = "Dict(color: Literal['red', 'green', 'blue'])"
answer: ClassVar = "dict(color: Literal['red', 'green', 'blue'])"


class EmailModel(GradioModel):
email: EmailStr

answer: ClassVar = "Dict(email: str)"
answer: ClassVar = "dict(email: str)"


class RootWithNestedModel(GradioModel):
nested_int: IntegerRootModel
nested_enum: EnumRootModel
nested_dict: DictModel2

answer: ClassVar = "Dict(nested_int: int, nested_enum: Dict(color: Literal['red', 'green', 'blue']), nested_dict: Dict(data_dict: Dict(str, List[float])))"
answer: ClassVar = "dict(nested_int: int, nested_enum: dict(color: Literal['red', 'green', 'blue']), nested_dict: dict(data_dict: dict(str, list[float])))"


class LessNestedModel(GradioModel):
nested_int: int
nested_enum: ColorEnum
nested_dict: dict[str, list[Union[int, float]]]

answer: ClassVar = "Dict(nested_int: int, nested_enum: Literal['red', 'green', 'blue'], nested_dict: Dict(str, List[int | float]))"
answer: ClassVar = "dict(nested_int: int, nested_enum: Literal['red', 'green', 'blue'], nested_dict: dict(str, list[int | float]))"


class StatusModel(GradioModel):
status: Literal["active", "inactive"]

answer: ClassVar = "Dict(status: Literal['active', 'inactive'])"
answer: ClassVar = "dict(status: Literal['active', 'inactive'])"


class PointModel(GradioRootModel):
root: tuple[float, float]

answer: ClassVar = "Tuple[float, float]"
answer: ClassVar = "tuple[float, float]"


class UuidModel(GradioModel):
uuid: UUID

answer: ClassVar = "Dict(uuid: str)"
answer: ClassVar = "dict(uuid: str)"


class UrlModel(GradioModel):
url: AnyUrl

answer: ClassVar = "Dict(url: str)"
answer: ClassVar = "dict(url: str)"


class CustomFieldModel(GradioModel):
name: str = Field(..., title="Name of the item", max_length=50)
price: float = Field(..., title="Price of the item", gt=0)

answer: ClassVar = "Dict(name: str, price: float)"
answer: ClassVar = "dict(name: str, price: float)"


class DurationModel(GradioModel):
duration: timedelta

answer: ClassVar = "Dict(duration: str)"
answer: ClassVar = "dict(duration: str)"


class IPv4Model(GradioModel):
ipv4_address: IPvAnyAddress

answer: ClassVar = "Dict(ipv4_address: str)"
answer: ClassVar = "dict(ipv4_address: str)"


class DateTimeModel(GradioModel):
created_at: datetime
updated_at: datetime

answer: ClassVar = "Dict(created_at: str, updated_at: str)"
answer: ClassVar = "dict(created_at: str, updated_at: str)"


class SetModel(GradioModel):
unique_numbers: set[int]

answer: ClassVar = "Dict(unique_numbers: List[int])"
answer: ClassVar = "dict(unique_numbers: list[int])"


class ItemModel(GradioModel):
Expand All @@ -152,7 +152,7 @@ class ItemModel(GradioModel):
class OrderModel(GradioModel):
items: list[ItemModel]

answer: ClassVar = "Dict(items: List[Dict(name: str, price: float)])"
answer: ClassVar = "dict(items: list[dict(name: str, price: float)])"


class TemperatureUnitEnum(Enum):
Expand All @@ -170,7 +170,7 @@ class CartItemModel(GradioModel):
class ShoppingCartModel(GradioModel):
items: list[CartItemModel]

answer: ClassVar = "Dict(items: List[Dict(product_name: str, quantity: int, price_per_unit: float)])"
answer: ClassVar = "dict(items: list[dict(product_name: str, quantity: int, price_per_unit: float)])"


class CoordinateModel(GradioModel):
Expand All @@ -181,13 +181,13 @@ class CoordinateModel(GradioModel):
class TupleListModel(GradioModel):
data: list[tuple[int, str]]

answer: ClassVar = "Dict(data: List[Tuple[int, str]]"
answer: ClassVar = "dict(data: list[tuple[int, str]]"


class PathListModel(GradioModel):
file_paths: list[Path]

answer: ClassVar = "Dict(file_paths: List[str])"
answer: ClassVar = "dict(file_paths: list[str])"


class PostModel(GradioModel):
Expand All @@ -196,7 +196,7 @@ class PostModel(GradioModel):
tags: list[str]
likes: int = 0

answer: ClassVar = "Dict(author: str, content: str, tags: List[str], likes: int)"
answer: ClassVar = "dict(author: str, content: str, tags: list[str], likes: int)"


Person = namedtuple("Person", ["name", "age"])
Expand All @@ -205,7 +205,7 @@ class PostModel(GradioModel):
class NamedTupleDictionaryModel(GradioModel):
people: dict[str, Person]

answer: ClassVar = "Dict(people: Dict(str, Tuple[Any, Any]))"
answer: ClassVar = "dict(people: dict(str, tuple[Any, Any]))"


MODELS = [
Expand Down

0 comments on commit c9ba9a4

Please sign in to comment.