Move markdown & latex processing to the frontend for the gr.Markdown and gr.DataFrame components (#5268)

* changes

* katex

* add changeset

* dataframe

* add changeset

* latex in dataframe

* add changeset

* lint

* lint

* stories and types

* stories

* type

* restore lock

* pnpm lock

* fix backend tests

* xray configs

* test files

* test utils

* fix utils

* add changeset

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
Abubakar Abid 2023-08-21 06:54:20 -07:00 committed by GitHub
parent 46a2b600a7
commit f49028cfe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1833 additions and 1059 deletions

View File

@ -0,0 +1,7 @@
---
"@gradio/dataframe": minor
"@gradio/markdown": minor
"gradio": minor
---
feat:Move markdown & latex processing to the frontend for the gr.Markdown and gr.DataFrame components

View File

@ -135,6 +135,7 @@ class Chatbot(Changeable, Selectable, IOComponent, JSONSerializable):
visible: bool | None = None,
height: int | None = None,
rtl: bool | None = None,
latex_delimiters: list[dict[str, str | bool]] | None = None,
show_share_button: bool | None = None,
show_copy_button: bool | None = None,
):
@ -149,6 +150,7 @@ class Chatbot(Changeable, Selectable, IOComponent, JSONSerializable):
"height": height,
"show_share_button": show_share_button,
"rtl": rtl,
"latex_delimiters": latex_delimiters,
"show_copy_button": show_copy_button,
"__type__": "update",
}

View File

@ -9,7 +9,6 @@ import pandas as pd
from gradio_client.documentation import document, set_documentation_group
from gradio_client.serializing import JSONSerializable
from gradio import utils
from gradio.components.base import IOComponent, _Keywords
from gradio.events import (
Changeable,
@ -39,8 +38,6 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
Demos: filter_records, matrix_transpose, tax_calculator
"""
markdown_parser = None
def __init__(
self,
value: list[list[Any]] | Callable | None = None,
@ -53,6 +50,7 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
max_rows: int | None = 20,
max_cols: int | None = None,
overflow_row_behaviour: Literal["paginate", "show_ends"] = "paginate",
latex_delimiters: list[dict[str, str | bool]] | None = None,
label: str | None = None,
every: float | None = None,
show_label: bool | None = None,
@ -77,6 +75,7 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
max_rows: Maximum number of rows to display at once. Set to None for infinite.
max_cols: Maximum number of columns to display at once. Set to None for infinite.
overflow_row_behaviour: If set to "paginate", will create pages for overflow rows. If set to "show_ends", will show initial and final rows and truncate middle rows.
latex_delimiters: A list of dicts of the form {"left": open delimiter (str), "right": close delimiter (str), "display": whether to display in newline (bool)} that will be used to render LaTeX expressions. If not provided, `latex_delimiters` is set to `[{ "left": "$", "right": "$", "display": False }]`, so only expressions enclosed in $ delimiters will be rendered as LaTeX, and in the same line. Pass in an empty list to disable LaTeX rendering. For more information, see the [KaTeX documentation](https://katex.org/docs/autorender.html). Only applies to columns whose datatype is "markdown".
label: component name in interface.
every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute.
show_label: if True, will display label.
@ -127,6 +126,10 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
self.max_rows = max_rows
self.max_cols = max_cols
self.overflow_row_behaviour = overflow_row_behaviour
if latex_delimiters is None:
latex_delimiters = [{"left": "$", "right": "$", "display": False}]
self.latex_delimiters = latex_delimiters
self.select: EventListenerMethod
"""
Event listener for when the user selects cell within Dataframe.
@ -159,6 +162,7 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
"max_cols": self.max_cols,
"overflow_row_behaviour": self.overflow_row_behaviour,
"wrap": self.wrap,
"latex_delimiters": self.latex_delimiters,
**IOComponent.get_config(self),
}
@ -169,6 +173,7 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
max_cols: str | None = None,
label: str | None = None,
show_label: bool | None = None,
latex_delimiters: list[dict[str, str | bool]] | None = None,
scale: int | None = None,
min_width: int | None = None,
interactive: bool | None = None,
@ -184,6 +189,7 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
"interactive": interactive,
"visible": visible,
"value": value,
"latex_delimiters": latex_delimiters,
"__type__": "update",
}
@ -223,20 +229,12 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
return self.postprocess(self.empty_input)
if isinstance(y, dict):
return y
if isinstance(y, str):
dataframe = pd.read_csv(y)
return {
"headers": list(dataframe.columns),
"data": Dataframe.__process_markdown(
dataframe.to_dict(orient="split")["data"], self.datatype
),
}
if isinstance(y, pd.DataFrame):
if isinstance(y, (str, pd.DataFrame)):
if isinstance(y, str):
y = pd.read_csv(y)
return {
"headers": list(y.columns), # type: ignore
"data": Dataframe.__process_markdown(
y.to_dict(orient="split")["data"], self.datatype # type: ignore
),
"data": y.to_dict(orient="split")["data"], # type: ignore
}
if isinstance(y, (np.ndarray, list)):
if len(y) == 0:
@ -257,7 +255,7 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
return {
"headers": _headers,
"data": Dataframe.__process_markdown(y, self.datatype),
"data": y,
}
raise ValueError("Cannot process value as a Dataframe")
@ -279,21 +277,6 @@ class Dataframe(Changeable, Inputable, Selectable, IOComponent, JSONSerializable
f"Check the values passed to `col_count` and `headers`."
)
@classmethod
def __process_markdown(cls, data: list[list[Any]], datatype: list[str]):
if "markdown" not in datatype:
return data
if cls.markdown_parser is None:
cls.markdown_parser = utils.get_markdown_parser()
for i in range(len(data)):
for j in range(len(data[i])):
if datatype[j] == "markdown":
data[i][j] = cls.markdown_parser.render(data[i][j])
return data
def as_example(self, input_data: pd.DataFrame | np.ndarray | str | None):
if input_data is None:
return ""

View File

@ -8,7 +8,6 @@ from typing import Any, Callable, Literal
from gradio_client.documentation import document, set_documentation_group
from gradio_client.serializing import StringSerializable
from gradio import utils
from gradio.components.base import Component, IOComponent, _Keywords
from gradio.events import (
Changeable,
@ -32,22 +31,27 @@ class Markdown(IOComponent, Changeable, StringSerializable):
self,
value: str | Callable = "",
*,
rtl: bool = False,
latex_delimiters: list[dict[str, str | bool]] | None = None,
visible: bool = True,
elem_id: str | None = None,
elem_classes: list[str] | str | None = None,
rtl: bool = False,
**kwargs,
):
"""
Parameters:
value: Value to show in Markdown component. If callable, the function will be called whenever the app loads to set the initial value of the component.
rtl: If True, sets the direction of the rendered text to right-to-left. Default is False, which renders text left-to-right.
latex_delimiters: A list of dicts of the form {"left": open delimiter (str), "right": close delimiter (str), "display": whether to display in newline (bool)} that will be used to render LaTeX expressions. If not provided, `latex_delimiters` is set to `[{ "left": "$", "right": "$", "display": False }]`, so only expressions enclosed in $ delimiters will be rendered as LaTeX, and in the same line. Pass in an empty list to disable LaTeX rendering. For more information, see the [KaTeX documentation](https://katex.org/docs/autorender.html).
visible: If False, component will be hidden.
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
rtl: If True, sets the direction of the rendered text to right-to-left. Default is False, which renders text left-to-right.
"""
self.md = utils.get_markdown_parser()
self.rtl = rtl
if latex_delimiters is None:
latex_delimiters = [{"left": "$", "right": "$", "display": False}]
self.latex_delimiters = latex_delimiters
IOComponent.__init__(
self,
visible=visible,
@ -67,12 +71,13 @@ class Markdown(IOComponent, Changeable, StringSerializable):
if y is None:
return None
unindented_y = inspect.cleandoc(y)
return self.md.render(unindented_y)
return unindented_y
def get_config(self):
return {
"value": self.value,
"rtl": self.rtl,
"latex_delimiters": self.latex_delimiters,
**Component.get_config(self),
}
@ -81,11 +86,13 @@ class Markdown(IOComponent, Changeable, StringSerializable):
value: Any | Literal[_Keywords.NO_VALUE] | None = _Keywords.NO_VALUE,
visible: bool | None = None,
rtl: bool | None = None,
latex_delimiters: list[dict[str, str | bool]] | None = None,
):
updated_config = {
"visible": visible,
"value": value,
"rtl": rtl,
"latex_delimiters": latex_delimiters,
"__type__": "update",
}
return updated_config

View File

@ -297,16 +297,10 @@ class Interface(Blocks):
self.live = live
self.title = title
md = utils.get_markdown_parser()
simple_description: str | None = None
if description is not None:
description = md.render(description)
simple_description = utils.remove_html_tags(description)
self.simple_description = simple_description
self.simple_description = utils.remove_html_tags(description)
self.description = description
if article is not None:
article = utils.readme_to_html(article)
article = md.render(article)
self.article = article
self.thumbnail = thumbnail

View File

@ -1,870 +0,0 @@
XRAY_CONFIG = {
"version": "3.32.0\n",
"mode": "blocks",
"dev_mode": True,
"analytics_enabled": False,
"components": [
{
"id": 1,
"type": "markdown",
"props": {
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"visible": True,
"rtl": False,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 2,
"type": "checkboxgroup",
"props": {
"choices": [
("Covid", "Covid"),
("Malaria", "Malaria"),
("Lung Cancer", "Lung Cancer"),
],
"value": [],
"label": "Disease to Scan For",
"show_label": True,
"container": True,
"min_width": 160,
"name": "checkboxgroup",
"visible": True,
},
"serializer": "ListStringSerializable",
"api_info": {
"info": {"type": "array", "items": {"type": "string"}},
"serialized_info": False,
},
"example_inputs": {"raw": ["Covid"], "serialized": ["Covid"]},
},
{"id": 3, "type": "tabs", "props": {"visible": True}},
{"id": 4, "type": "tabitem", "props": {"label": "X-ray", "visible": True}},
{
"id": 5,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"visible": True,
},
},
{
"id": 6,
"type": "image",
"props": {
"image_mode": "RGB",
"brush_color": "#000000",
"mask_opacity": 0.7,
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"container": True,
"min_width": 160,
"name": "image",
"show_share_button": False,
"show_download_button": True,
"visible": True,
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image",
},
"serialized_info": True,
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
},
},
{
"id": 7,
"type": "json",
"props": {
"show_label": True,
"container": True,
"min_width": 160,
"name": "json",
"visible": True,
},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
"serialized_info": True,
},
"example_inputs": {"raw": {"a": 1, "b": 2}, "serialized": None},
},
{
"id": 8,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": True,
"name": "button",
"visible": True,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{"id": 9, "type": "tabitem", "props": {"label": "CT Scan", "visible": True}},
{
"id": 10,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"visible": True,
},
},
{
"id": 11,
"type": "image",
"props": {
"image_mode": "RGB",
"brush_color": "#000000",
"mask_opacity": 0.7,
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"container": True,
"min_width": 160,
"name": "image",
"show_share_button": False,
"show_download_button": True,
"visible": True,
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image",
},
"serialized_info": True,
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
},
},
{
"id": 12,
"type": "json",
"props": {
"show_label": True,
"container": True,
"min_width": 160,
"name": "json",
"visible": True,
},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
"serialized_info": True,
},
"example_inputs": {"raw": {"a": 1, "b": 2}, "serialized": None},
},
{
"id": 13,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": True,
"name": "button",
"visible": True,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 14,
"type": "textbox",
"props": {
"autofocus": False,
"lines": 1,
"max_lines": 20,
"value": "",
"type": "text",
"show_label": True,
"container": True,
"min_width": 160,
"name": "textbox",
"show_copy_button": False,
"visible": True,
"rtl": False,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 15,
"type": "form",
"props": {"type": "form", "scale": 0, "min_width": 0, "visible": True},
},
{
"id": 16,
"type": "form",
"props": {"type": "form", "scale": 0, "min_width": 0, "visible": True},
},
],
"css": None,
"title": "Gradio",
"space_id": False,
"enable_queue": None,
"show_error": True,
"show_api": True,
"is_colab": False,
"stylesheets": [
"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap",
"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap",
],
"theme": "default",
"layout": {
"id": 0,
"children": [
{"id": 1},
{"id": 15, "children": [{"id": 2}]},
{
"id": 3,
"children": [
{
"id": 4,
"children": [
{"id": 5, "children": [{"id": 6}, {"id": 7}]},
{"id": 8},
],
},
{
"id": 9,
"children": [
{"id": 10, "children": [{"id": 11}, {"id": 12}]},
{"id": 13},
],
},
],
},
{"id": 16, "children": [{"id": 14}]},
],
},
"dependencies": [
{
"targets": [8],
"trigger": "click",
"inputs": [2, 6],
"outputs": [7],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [13],
"trigger": "click",
"inputs": [2, 11],
"outputs": [12],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [],
"trigger": "load",
"inputs": [],
"outputs": [14],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
],
}
XRAY_CONFIG_DIFF_IDS = {
"version": "3.32.0\n",
"mode": "blocks",
"dev_mode": True,
"analytics_enabled": False,
"components": [
{
"id": 6,
"type": "markdown",
"props": {
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"visible": True,
"rtl": False,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 7,
"type": "checkboxgroup",
"props": {
"choices": [
("Covid", "Covid"),
("Malaria", "Malaria"),
("Lung Cancer", "Lung Cancer"),
],
"value": [],
"label": "Disease to Scan For",
"show_label": True,
"container": True,
"min_width": 160,
"name": "checkboxgroup",
"visible": True,
},
"serializer": "ListStringSerializable",
"api_info": {
"info": {"type": "array", "items": {"type": "string"}},
"serialized_info": False,
},
"example_inputs": {"raw": ["Covid"], "serialized": ["Covid"]},
},
{"id": 8, "type": "tabs", "props": {"visible": True}},
{"id": 9, "type": "tabitem", "props": {"label": "X-ray", "visible": True}},
{
"id": 10,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"visible": True,
},
},
{
"id": 11,
"type": "image",
"props": {
"image_mode": "RGB",
"brush_color": "#000000",
"mask_opacity": 0.7,
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"container": True,
"min_width": 160,
"name": "image",
"show_share_button": False,
"show_download_button": True,
"visible": True,
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image",
},
"serialized_info": True,
},
"example_inputs": {
"raw": "data:image/png;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+fn/9ZWb8/PzWlwv///6wWGbImAPgTEMImIN9gUFCEm/gDALULDN8PAD6atYdCTX9gUNKlj8wZAKUsAOzZz+UMAOsJAP/Z2ccMDA8PD/95eX5NWvsJCOVNQPtfX/8zM8+QePLl38MGBr8JCP+zs9myn/8GBqwpAP/GxgwJCPny78lzYLgjAJ8vAP9fX/+MjMUcAN8zM/9wcM8ZGcATEL+QePdZWf/29uc/P9cmJu9MTDImIN+/r7+/vz8/P8VNQGNugV8AAF9fX8swMNgTAFlDOICAgPNSUnNWSMQ5MBAQEJE3QPIGAM9AQMqGcG9vb6MhJsEdGM8vLx8fH98AANIWAMuQeL8fABkTEPPQ0OM5OSYdGFl5jo+Pj/+pqcsTE78wMFNGQLYmID4dGPvd3UBAQJmTkP+8vH9QUK+vr8ZWSHpzcJMmILdwcLOGcHRQUHxwcK9PT9DQ0O/v70w5MLypoG8wKOuwsP/g4P/Q0IcwKEswKMl8aJ9fX2xjdOtGRs/Pz+Dg4GImIP8gIH0sKEAwKKmTiKZ8aB/f39Wsl+LFt8dgUE9PT5x5aHBwcP+AgP+WltdgYMyZfyywz78AAAAAAAD///8AAP9mZv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAKgALAAAAAA9AEQAAAj/AFEJHEiwoMGDCBMqXMiwocAbBww4nEhxoYkUpzJGrMixogkfGUNqlNixJEIDB0SqHGmyJSojM1bKZOmyop0gM3Oe2liTISKMOoPy7GnwY9CjIYcSRYm0aVKSLmE6nfq05QycVLPuhDrxBlCtYJUqNAq2bNWEBj6ZXRuyxZyDRtqwnXvkhACDV+euTeJm1Ki7A73qNWtFiF+/gA95Gly2CJLDhwEHMOUAAuOpLYDEgBxZ4GRTlC1fDnpkM+fOqD6DDj1aZpITp0dtGCDhr+fVuCu3zlg49ijaokTZTo27uG7Gjn2P+hI8+PDPERoUB318bWbfAJ5sUNFcuGRTYUqV/3ogfXp1rWlMc6awJjiAAd2fm4ogXjz56aypOoIde4OE5u/F9x199dlXnnGiHZWEYbGpsAEA3QXYnHwEFliKAgswgJ8LPeiUXGwedCAKABACCN+EA1pYIIYaFlcDhytd51sGAJbo3onOpajiihlO92KHGaUXGwWjUBChjSPiWJuOO/LYIm4v1tXfE6J4gCSJEZ7YgRYUNrkji9P55sF/ogxw5ZkSqIDaZBV6aSGYq/lGZplndkckZ98xoICbTcIJGQAZcNmdmUc210hs35nCyJ58fgmIKX5RQGOZowxaZwYA+JaoKQwswGijBV4C6SiTUmpphMspJx9unX4KaimjDv9aaXOEBteBqmuuxgEHoLX6Kqx+yXqqBANsgCtit4FWQAEkrNbpq7HSOmtwag5w57GrmlJBASEU18ADjUYb3ADTinIttsgSB1oJFfA63bduimuqKB1keqwUhoCSK374wbujvOSu4QG6UvxBRydcpKsav++Ca6G8A6Pr1x2kVMyHwsVxUALDq/krnrhPSOzXG1lUTIoffqGR7Goi2MAxbv6O2kEG56I7CSlRsEFKFVyovDJoIRTg7sugNRDGqCJzJgcKE0ywc0ELm6KBCCJo8DIPFeCWNGcyqNFE06ToAfV0HBRgxsvLThHn1oddQMrXj5DyAQgjEHSAJMWZwS3HPxT/QMbabI/iBCliMLEJKX2EEkomBAUCxRi42VDADxyTYDVogV+wSChqmKxEKCDAYFDFj4OmwbY7bDGdBhtrnTQYOigeChUmc1K3QTnAUfEgGFgAWt88hKA6aCRIXhxnQ1yg3BCayK44EWdkUQcBByEQChFXfCB776aQsG0BIlQgQgE8qO26X1h8cEUep8ngRBnOy74E9QgRgEAC8SvOfQkh7FDBDmS43PmGoIiKUUEGkMEC/PJHgxw0xH74yx/3XnaYRJgMB8obxQW6kL9QYEJ0FIFgByfIL7/IQAlvQwEpnAC7DtLNJCKUoO/w45c44GwCXiAFB/OXAATQryUxdN4LfFiwgjCNYg+kYMIEFkCKDs6PKAIJouyGWMS1FSKJOMRB/BoIxYJIUXFUxNwoIkEKPAgCBZSQHQ1A2EWDfDEUVLyADj5AChSIQW6gu10bE/JG2VnCZGfo4R4d0sdQoBAHhPjhIB94v/wRoRKQWGRHgrhGSQJxCS+0pCZbEhAAOw==",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
},
},
{
"id": 12,
"type": "json",
"props": {
"show_label": True,
"container": True,
"min_width": 160,
"name": "json",
"visible": True,
},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
"serialized_info": True,
},
"example_inputs": {"raw": {"a": 1, "b": 2}, "serialized": None},
},
{
"id": 13,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": True,
"name": "button",
"visible": True,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{"id": 14, "type": "tabitem", "props": {"label": "CT Scan", "visible": True}},
{
"id": 15,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"visible": True,
},
},
{
"id": 16,
"type": "image",
"props": {
"image_mode": "RGB",
"brush_color": "#000000",
"mask_opacity": 0.7,
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"container": True,
"min_width": 160,
"name": "image",
"show_share_button": False,
"show_download_button": True,
"visible": True,
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image",
},
"serialized_info": True,
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
},
},
{
"id": 17,
"type": "json",
"props": {
"show_label": True,
"container": True,
"min_width": 160,
"name": "json",
"visible": True,
},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
"serialized_info": True,
},
"example_inputs": {"raw": {"a": 1, "b": 2}, "serialized": None},
},
{
"id": 18,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": True,
"name": "button",
"visible": True,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 19,
"type": "textbox",
"props": {
"autofocus": False,
"lines": 1,
"max_lines": 20,
"value": "",
"type": "text",
"show_label": True,
"container": True,
"min_width": 160,
"name": "textbox",
"show_copy_button": False,
"visible": True,
"rtl": False,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 20,
"type": "form",
"props": {"type": "form", "scale": 0, "min_width": 0, "visible": True},
},
{
"id": 21,
"type": "form",
"props": {"type": "form", "scale": 0, "min_width": 0, "visible": True},
},
],
"css": None,
"title": "Gradio",
"space_id": False,
"enable_queue": None,
"show_error": True,
"show_api": True,
"is_colab": False,
"stylesheets": [
"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap",
"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap",
],
"theme": "default",
"layout": {
"id": 0,
"children": [
{"id": 6},
{"id": 20, "children": [{"id": 7}]},
{
"id": 8,
"children": [
{
"id": 9,
"children": [
{"id": 10, "children": [{"id": 11}, {"id": 12}]},
{"id": 13},
],
},
{
"id": 14,
"children": [
{"id": 15, "children": [{"id": 16}, {"id": 17}]},
{"id": 18},
],
},
],
},
{"id": 21, "children": [{"id": 19}]},
],
},
"dependencies": [
{
"targets": [13],
"trigger": "click",
"inputs": [7, 11],
"outputs": [12],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [18],
"trigger": "click",
"inputs": [7, 16],
"outputs": [17],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [],
"trigger": "load",
"inputs": [],
"outputs": [19],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
],
}
XRAY_CONFIG_WITH_MISTAKE = {
"mode": "blocks",
"dev_mode": True,
"analytics_enabled": False,
"theme": "default",
"components": [
{
"id": 1,
"type": "markdown",
"props": {
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"rtl": False,
},
},
{
"id": 2,
"type": "checkboxgroup",
"props": {
"choices": [
("Covid", "Covid"),
("Malaria", "Malaria"),
("Lung Cancer", "Lung Cancer"),
],
"value": [],
"name": "checkboxgroup",
"show_label": True,
"label": "Disease to Scan For",
"container": True,
"min_width": 160,
},
},
{
"id": 3,
"type": "tabs",
"props": {
"value": True,
},
},
{
"id": 4,
"type": "tabitem",
"props": {
"label": "X-ray",
"value": True,
},
},
{
"id": 5,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"value": True,
},
},
{
"id": 6,
"type": "image",
"props": {
"image_mode": "RGB",
"brush_color": "#000000",
"mask_opacity": 0.7,
"source": "upload",
"streaming": False,
"mirror_webcam": True,
"tool": "editor",
"name": "image",
"show_share_button": False,
"selectable": False,
},
},
{
"id": 7,
"type": "json",
"props": {
"name": "json",
},
},
{
"id": 8,
"type": "button",
"props": {
"value": "Run",
"name": "button",
"interactive": True,
"css": {"background-color": "red", "--hover-color": "orange"},
"variant": "secondary",
},
},
{
"id": 9,
"type": "tabitem",
"props": {
"show_label": True,
"label": "CT Scan",
"value": True,
},
},
{
"id": 10,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"value": True,
},
},
{
"id": 11,
"type": "image",
"props": {
"image_mode": "RGB",
"brush_color": "#000000",
"mask_opacity": 0.7,
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"name": "image",
"show_share_button": False,
"selectable": False,
},
},
{
"id": 12,
"type": "json",
"props": {
"name": "json",
},
},
{
"id": 13,
"type": "button",
"props": {
"value": "Run",
"interactive": True,
"name": "button",
"variant": "secondary",
},
},
{
"id": 14,
"type": "textbox",
"props": {
"lines": 1,
"value": "",
"name": "textbox",
"show_copy_button": False,
"type": "text",
"rtl": False,
"autofocus": False,
},
},
],
"layout": {
"id": 0,
"children": [
{"id": 1},
{"id": 2},
{
"id": 3,
"children": [
{
"id": 4,
"children": [
{"id": 5, "children": [{"id": 6}, {"id": 7}]},
{"id": 8},
],
},
{
"id": 9,
"children": [
{"id": 10, "children": [{"id": 12}, {"id": 11}]},
{"id": 13},
],
},
],
},
{"id": 14},
],
},
"dependencies": [
{
"targets": [8],
"trigger": "click",
"inputs": [2, 6],
"outputs": [7],
"api_name": None,
"scroll_to_output": False,
"cancels": [],
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [13],
"trigger": "click",
"inputs": [2, 11],
"outputs": [12],
"api_name": None,
"scroll_to_output": False,
"cancels": [],
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
],
}

View File

@ -37,9 +37,6 @@ import httpx
import matplotlib
import requests
from gradio_client.serializing import Serializable
from markdown_it import MarkdownIt
from mdit_py_plugins.dollarmath.index import dollarmath_plugin
from mdit_py_plugins.footnote.index import footnote_plugin
from pydantic import BaseModel, parse_obj_as
from typing_extensions import ParamSpec
@ -192,7 +189,9 @@ def assert_configs_are_equivalent_besides_ids(
c1.pop("id")
c2 = copy.deepcopy(c2)
c2.pop("id")
assert c1 == c2, f"{pp.pprint(c1)} does not match {pp.pprint(c2)}"
assert json.dumps(c1) == json.dumps(
c2
), f"{pp.pprint(c1)} does not match {pp.pprint(c2)}"
def same_children_recursive(children1, chidren2):
for child1, child2 in zip(children1, chidren2):
@ -994,31 +993,6 @@ def get_serializer_name(block: Block) -> str | None:
return cls.__name__
def get_markdown_parser() -> MarkdownIt:
md = (
MarkdownIt(
"js-default",
{
"linkify": True,
"typographer": True,
"html": True,
},
)
.use(dollarmath_plugin, renderer=tex2svg, allow_digits=False)
.use(footnote_plugin)
.enable("table")
)
# Add target="_blank" to all links. Taken from MarkdownIt docs: https://github.com/executablebooks/markdown-it-py/blob/master/docs/architecture.md
def render_blank_link(self, tokens, idx, options, env):
tokens[idx].attrSet("target", "_blank")
return self.renderToken(tokens, idx, options, env)
md.add_render_rule("link_open", render_blank_link)
return md
HTML_TAG_RE = re.compile("<.*?>")

View File

@ -51,6 +51,24 @@
}}
/>
<Story
name="Dataframe with markdown and math"
args={{
values: [
["Linear", "$y=x$", "Has a *maximum* of 1 root"],
["Quadratic", "$y=x^2$", "Has a *maximum* of 2 roots"],
["Cubic", "$y=x^3$", "Has a *maximum* of 3 roots"]
],
headers: ["Type", "Example", "Roots"],
datatype: ["str", "markdown", "markdown"],
latex_delimiters: [{ left: "$", right: "$", display: false }],
label: "Math",
col_count: [3, "dynamic"],
row_count: [3, "dynamic"],
editable: false
}}
/>
<Story
name="Empty dataframe"
args={{

View File

@ -17,6 +17,12 @@
data: [["", "", ""]],
headers: ["1", "2", "3"]
};
export let latex_delimiters: {
left: string;
right: string;
display: boolean;
}[];
let old_value: string = JSON.stringify(value);
export let value_is_output = false;
export let col_count: [number, "fixed" | "dynamic"];
@ -72,5 +78,6 @@
editable
{wrap}
{datatype}
{latex_delimiters}
/>
</Block>

View File

@ -15,8 +15,13 @@
"@gradio/upload": "workspace:^",
"@gradio/utils": "workspace:^",
"@types/d3-dsv": "^3.0.0",
"@types/dompurify": "^3.0.2",
"@types/katex": "^0.16.0",
"d3-dsv": "^3.0.1",
"dequal": "^2.0.2"
"dequal": "^2.0.2",
"dompurify": "^3.0.3",
"katex": "^0.16.7",
"marked": "^7.0.0"
},
"exports": {
"./package.json": "./package.json",

View File

@ -1,4 +1,10 @@
<script lang="ts">
import { afterUpdate, tick } from "svelte";
import { marked } from "marked";
import DOMPurify from "dompurify";
import render_math_in_element from "katex/dist/contrib/auto-render.js";
import "katex/dist/katex.min.css";
export let edit: boolean;
export let value: string | number = "";
export let el: HTMLInputElement | null;
@ -10,6 +16,32 @@
| "number"
| "bool"
| "date" = "str";
export let latex_delimiters: {
left: string;
right: string;
display: boolean;
}[];
let span: HTMLSpanElement;
let mounted = false;
$: mounted &&
latex_delimiters.length > 0 &&
render_math_in_element(span, {
delimiters: latex_delimiters,
throwOnError: false
});
afterUpdate(() => {
if (datatype == "markdown") {
tick().then(() => {
requestAnimationFrame(() => {
span.innerHTML = DOMPurify.sanitize(marked.parse(value.toString()));
mounted = true;
});
});
}
});
</script>
{#if edit}
@ -25,8 +57,8 @@
}}
/>
{/if}
<span on:dblclick tabindex="-1" role="button" class:edit>
{#if datatype === "markdown" || datatype === "html"}
<span on:dblclick tabindex="-1" role="button" class:edit bind:this={span}>
{#if datatype === "html"}
{@html value}
{:else}
{value}

View File

@ -19,6 +19,11 @@
| { data: (string | number)[][]; headers: string[] } = [[]];
export let col_count: [number, "fixed" | "dynamic"];
export let row_count: [number, "fixed" | "dynamic"];
export let latex_delimiters: {
left: string;
right: string;
display: boolean;
}[];
export let editable = true;
export let wrap = false;
@ -152,7 +157,7 @@
$: _headers &&
dispatch("change", {
data: data.map((r) => r.map(({ value }) => value)),
headers: _headers.map((h) => h.value),
headers: _headers.map((h) => h.value)
});
function get_sort_status(
@ -558,6 +563,7 @@
<div class="cell-wrap">
<EditableCell
{value}
{latex_delimiters}
bind:el={els[id].input}
edit={header_edit === id}
on:keydown={end_header_edit}
@ -609,6 +615,7 @@
<EditableCell
bind:value
bind:el={els[id].input}
{latex_delimiters}
edit={editing === id}
datatype={Array.isArray(datatype)
? datatype[j]

View File

@ -26,6 +26,11 @@
export let datatype: Datatype | Datatype[];
export let scale: number | null = null;
export let min_width: number | undefined = undefined;
export let latex_delimiters: {
left: string;
right: string;
display: boolean;
}[];
const dispatch = createEventDispatcher();
@ -71,6 +76,7 @@
on:select
{wrap}
{datatype}
{latex_delimiters}
editable={false}
/>
</Block>

View File

@ -18,10 +18,19 @@
<Template let:args>
<Markdown
{...args}
value="Here's some <strong>bold</strong> text. And some <em>italics</em> and some <code>code</code>"
{...args}
/>
</Template>
<Story name="Simple inline Markdown with HTML" />
<Story name="Right aligned Markdown with HTML" args={{ rtl: true }} />
<Story
name="Markdown with math"
args={{
value: "What is the solution of $y=x^2$?",
latex_delimiters: [{ left: "$", right: "$", display: false }]
}}
/>

View File

@ -17,6 +17,11 @@
},
"dependencies": {
"@gradio/atoms": "workspace:^",
"@gradio/statustracker": "workspace:^"
"@gradio/statustracker": "workspace:^",
"@types/dompurify": "^3.0.2",
"@types/katex": "^0.16.0",
"dompurify": "^3.0.3",
"katex": "^0.16.7",
"marked": "^7.0.0"
}
}

View File

@ -1,5 +1,10 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import { afterUpdate, createEventDispatcher, tick } from "svelte";
import { marked } from "marked";
import DOMPurify from "dompurify";
import render_math_in_element from "katex/dist/contrib/auto-render.js";
import "katex/dist/katex.min.css";
export let elem_id = "";
export let elem_classes: string[] = [];
export let visible = true;
@ -7,9 +12,35 @@
export let min_height = false;
export let rtl = false;
let div: HTMLDivElement;
const dispatch = createEventDispatcher<{ change: undefined }>();
$: value, dispatch("change");
export let latex_delimiters: {
left: string;
right: string;
display: boolean;
}[];
let mounted = false;
$: mounted &&
latex_delimiters.length > 0 &&
render_math_in_element(div, {
delimiters: latex_delimiters,
throwOnError: false
});
afterUpdate(() => {
tick().then(() => {
requestAnimationFrame(() => {
div.innerHTML = DOMPurify.sanitize(marked.parse(value));
mounted = true;
});
});
});
</script>
<div
@ -19,9 +50,8 @@
class:hide={!visible}
data-testid="markdown"
dir={rtl ? "rtl" : "ltr"}
>
{@html value}
</div>
bind:this={div}
></div>
<style>
div :global(.math.inline) {

View File

@ -13,6 +13,11 @@
export let value = "";
export let loading_status: LoadingStatus;
export let rtl = false;
export let latex_delimiters: {
left: string;
right: string;
display: boolean;
}[];
const dispatch = createEventDispatcher<{ change: undefined }>();
@ -29,6 +34,7 @@
{elem_classes}
{visible}
{rtl}
{latex_delimiters}
on:change
/>
</div>

30
pnpm-lock.yaml generated
View File

@ -738,12 +738,27 @@ importers:
'@types/d3-dsv':
specifier: ^3.0.0
version: 3.0.0
'@types/dompurify':
specifier: ^3.0.2
version: 3.0.2
'@types/katex':
specifier: ^0.16.0
version: 0.16.0
d3-dsv:
specifier: ^3.0.1
version: 3.0.1
dequal:
specifier: ^2.0.2
version: 2.0.2
dompurify:
specifier: ^3.0.3
version: 3.0.3
katex:
specifier: ^0.16.7
version: 0.16.7
marked:
specifier: ^7.0.0
version: 7.0.0
js/dropdown:
dependencies:
@ -913,6 +928,21 @@ importers:
'@gradio/statustracker':
specifier: workspace:^
version: link:../statustracker
'@types/dompurify':
specifier: ^3.0.2
version: 3.0.2
'@types/katex':
specifier: ^0.16.0
version: 0.16.0
dompurify:
specifier: ^3.0.3
version: 3.0.3
katex:
specifier: ^0.16.7
version: 0.16.7
marked:
specifier: ^7.0.0
version: 7.0.0
js/model3D:
dependencies:

View File

@ -7,8 +7,6 @@ httpx
huggingface_hub>=0.14.0
importlib_resources>=1.3,<7.0
Jinja2<4.0
markdown-it-py[linkify]>=2.0.0
mdit-py-plugins<=0.3.3
markupsafe~=2.0
matplotlib~=3.0
numpy~=1.0

View File

@ -0,0 +1,100 @@
import gradio as gr
import random
import json
import os
def fake_func():
return "Hello There"
def xray_model(diseases, img):
return {disease: random.random() for disease in diseases}
def ct_model(diseases, img):
return {disease: 0.1 for disease in diseases}
with gr.Blocks() as demo:
gr.Markdown(
"""
# Detect Disease From Scan
With this model you can lorem ipsum
- ipsum 1
- ipsum 2
"""
)
disease = gr.CheckboxGroup(
choices=["Covid", "Malaria", "Lung Cancer"], label="Disease to Scan For"
)
with gr.Tabs():
with gr.TabItem("X-ray"):
with gr.Row():
xray_scan = gr.Image()
xray_results = gr.JSON()
xray_run = gr.Button("Run")
xray_run.click(
xray_model, inputs=[disease, xray_scan], outputs=xray_results
)
with gr.TabItem("CT Scan"):
with gr.Row():
ct_scan = gr.Image()
ct_results = gr.JSON()
ct_run = gr.Button("Run")
ct_run.click(
ct_model, inputs=[disease, ct_scan], outputs=ct_results
)
textbox = gr.Textbox()
gr.context.Context.id = 100
with gr.Blocks() as demo2:
gr.Markdown(
"""
# Detect Disease From Scan
With this model you can lorem ipsum
- ipsum 1
- ipsum 2
"""
)
disease = gr.CheckboxGroup(
choices=["Covid", "Malaria", "Lung Cancer"], label="Disease to Scan For"
)
with gr.Tabs():
with gr.TabItem("X-ray"):
with gr.Row():
xray_scan = gr.Image()
xray_results = gr.JSON()
xray_run = gr.Button("Run")
xray_run.click(
xray_model, inputs=[disease, xray_scan], outputs=xray_results
)
with gr.TabItem("CT Scan"):
with gr.Row():
ct_scan = gr.Image()
ct_results = gr.JSON()
ct_run = gr.Button("Run")
ct_run.click(
ct_model, inputs=[disease, ct_scan], outputs=ct_results
)
textbox = gr.Textbox()
with gr.Blocks() as demo3:
demo.render()
t = gr.Textbox()
demo3.load(fake_func, [], [t])
config = demo.get_config_file()
config2 = demo2.get_config_file()
config3 = demo3.get_config_file()
json_file_path = "../test/test_files/xray_config.json"
json_file_path2 = "../test/test_files/xray_config_diff_ids.json"
json_file_path3 = "../test/test_files/xray_config_wrong.json"
for c, j in zip([config, config2, config3], [json_file_path, json_file_path2, json_file_path3]):
assert os.path.exists(j), f"{j} does not exist"
with open(j, "w") as fp:
json.dump(c, fp, indent=2)

View File

@ -32,7 +32,6 @@ from gradio.blocks import get_api_info
from gradio.events import SelectData
from gradio.exceptions import DuplicateBlockError
from gradio.networking import Server, get_first_available_port
from gradio.test_data.blocks_configs import XRAY_CONFIG
from gradio.utils import assert_configs_are_equivalent_besides_ids
pytest_plugins = ("pytest_asyncio",)
@ -135,7 +134,13 @@ class TestBlocksMethods:
demo.load(fake_func, [], [textbox])
config = demo.get_config_file()
assert assert_configs_are_equivalent_besides_ids(XRAY_CONFIG, config)
xray_config_file = (
pathlib.Path(__file__).parent / "test_files" / "xray_config.json"
)
with open(xray_config_file) as fp:
xray_config = json.load(fp)
assert assert_configs_are_equivalent_besides_ids(xray_config, config)
assert config["show_api"] is True
_ = demo.launch(prevent_thread_lock=True, show_api=False)
assert demo.config["show_api"] is False

View File

@ -1140,6 +1140,7 @@ class TestDataframe:
"interactive": None,
"root_url": None,
"wrap": False,
"latex_delimiters": [{"display": False, "left": "$", "right": "$"}],
}
dataframe_input = gr.Dataframe()
output = dataframe_input.preprocess(x_data)
@ -1174,6 +1175,7 @@ class TestDataframe:
"interactive": None,
"root_url": None,
"wrap": False,
"latex_delimiters": [{"display": False, "left": "$", "right": "$"}],
}
def test_postprocess(self):
@ -1237,7 +1239,7 @@ class TestDataframe:
0.2233,
84,
True,
"<h1>Hello</h1>\n",
"# Hello",
],
[
pd.Timestamp("2021-01-02 00:00:00"),
@ -1245,7 +1247,7 @@ class TestDataframe:
0.57281,
23,
False,
"<h1>Goodbye</h1>\n",
"# Goodbye",
],
],
}
@ -1292,7 +1294,7 @@ class TestDataset:
"hi",
bus,
"<i>Italics</i>",
"<p><em>Italics</em></p>\n",
"*Italics*",
]
dataset = gr.Dataset(
@ -2110,21 +2112,16 @@ class TestHTML:
class TestMarkdown:
def test_component_functions(self):
markdown_component = gr.Markdown("# Let's learn about $x$", label="Markdown")
assert markdown_component.get_config()["value"].startswith(
"""<h1>Lets learn about <span class="math inline"><span style=\'font-size: 0px\'>x</span><svg xmlns:xlink="http://www.w3.org/1999/xlink" height="0.9678125em" viewBox="0 0 11.6 19.35625" xmlns="http://www.w3.org/2000/svg" version="1.1">\n \n <defs>\n <style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id="figure_1">\n <g id="patch_1">"""
)
assert markdown_component.get_config()["value"] == "# Let's learn about $x$"
def test_in_interface(self):
"""
Interface, process
"""
iface = gr.Interface(lambda x: x, "text", "markdown")
input_data = "Here's an [image](https://gradio.app/images/gradio_logo.png)"
input_data = " Here's an [image](https://gradio.app/images/gradio_logo.png)"
output_data = iface(input_data)
assert (
output_data
== """<p>Heres an <a href="https://gradio.app/images/gradio_logo.png" target="_blank">image</a></p>\n"""
)
assert output_data == input_data.strip()
class TestModel3D:

View File

@ -0,0 +1,476 @@
{
"version": "3.40.1",
"mode": "blocks",
"dev_mode": true,
"analytics_enabled": true,
"components": [
{
"id": 1,
"type": "markdown",
"props": {
"value": "# Detect Disease From Scan\nWith this model you can lorem ipsum\n- ipsum 1\n- ipsum 2",
"rtl": false,
"latex_delimiters": [
{
"left": "$",
"right": "$",
"display": false
}
],
"name": "markdown",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 2,
"type": "checkboxgroup",
"props": {
"choices": [
[
"Covid",
"Covid"
],
[
"Malaria",
"Malaria"
],
[
"Lung Cancer",
"Lung Cancer"
]
],
"value": [],
"label": "Disease to Scan For",
"show_label": true,
"container": true,
"min_width": 160,
"name": "checkboxgroup",
"visible": true
},
"serializer": "ListStringSerializable",
"api_info": {
"info": {
"type": "array",
"items": {
"type": "string"
}
},
"serialized_info": false
},
"example_inputs": {
"raw": [
"Covid"
],
"serialized": [
"Covid"
]
}
},
{
"id": 3,
"type": "tabs",
"props": {
"visible": true
}
},
{
"id": 4,
"type": "tabitem",
"props": {
"label": "X-ray",
"visible": true
}
},
{
"id": 5,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": true,
"visible": true
}
},
{
"id": 6,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": false,
"mirror_webcam": true,
"brush_color": "#000000",
"mask_opacity": 0.7,
"selectable": false,
"show_share_button": false,
"show_download_button": true,
"show_label": true,
"container": true,
"min_width": 160,
"name": "image",
"visible": true
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image"
},
"serialized_info": true
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
}
},
{
"id": 7,
"type": "json",
"props": {
"show_label": true,
"container": true,
"min_width": 160,
"name": "json",
"visible": true
},
"serializer": "JSONSerializable",
"api_info": {
"info": {
"type": {},
"description": "any valid json"
},
"serialized_info": true
},
"example_inputs": {
"raw": {
"a": 1,
"b": 2
},
"serialized": null
}
},
{
"id": 8,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": true,
"name": "button",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 9,
"type": "tabitem",
"props": {
"label": "CT Scan",
"visible": true
}
},
{
"id": 10,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": true,
"visible": true
}
},
{
"id": 11,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": false,
"mirror_webcam": true,
"brush_color": "#000000",
"mask_opacity": 0.7,
"selectable": false,
"show_share_button": false,
"show_download_button": true,
"show_label": true,
"container": true,
"min_width": 160,
"name": "image",
"visible": true
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image"
},
"serialized_info": true
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
}
},
{
"id": 12,
"type": "json",
"props": {
"show_label": true,
"container": true,
"min_width": 160,
"name": "json",
"visible": true
},
"serializer": "JSONSerializable",
"api_info": {
"info": {
"type": {},
"description": "any valid json"
},
"serialized_info": true
},
"example_inputs": {
"raw": {
"a": 1,
"b": 2
},
"serialized": null
}
},
{
"id": 13,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": true,
"name": "button",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 14,
"type": "textbox",
"props": {
"lines": 1,
"max_lines": 20,
"value": "",
"type": "text",
"autofocus": false,
"show_copy_button": false,
"container": true,
"rtl": false,
"show_label": true,
"min_width": 160,
"name": "textbox",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 15,
"type": "form",
"props": {
"type": "form",
"scale": 0,
"min_width": 0,
"visible": true
}
},
{
"id": 16,
"type": "form",
"props": {
"type": "form",
"scale": 0,
"min_width": 0,
"visible": true
}
}
],
"css": null,
"title": "Gradio",
"space_id": null,
"enable_queue": null,
"show_error": true,
"show_api": true,
"is_colab": false,
"stylesheets": [
"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap",
"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap"
],
"theme": "default",
"layout": {
"id": 0,
"children": [
{
"id": 1
},
{
"id": 15,
"children": [
{
"id": 2
}
]
},
{
"id": 3,
"children": [
{
"id": 4,
"children": [
{
"id": 5,
"children": [
{
"id": 6
},
{
"id": 7
}
]
},
{
"id": 8
}
]
},
{
"id": 9,
"children": [
{
"id": 10,
"children": [
{
"id": 11
},
{
"id": 12
}
]
},
{
"id": 13
}
]
}
]
},
{
"id": 16,
"children": [
{
"id": 14
}
]
}
]
},
"dependencies": [
{
"targets": [
8
],
"trigger": "click",
"inputs": [
2,
6
],
"outputs": [
7
],
"backend_fn": true,
"js": null,
"queue": null,
"api_name": null,
"scroll_to_output": false,
"show_progress": "full",
"every": null,
"batch": false,
"max_batch_size": 4,
"cancels": [],
"types": {
"continuous": false,
"generator": false
},
"collects_event_data": false,
"trigger_after": null,
"trigger_only_on_success": false
},
{
"targets": [
13
],
"trigger": "click",
"inputs": [
2,
11
],
"outputs": [
12
],
"backend_fn": true,
"js": null,
"queue": null,
"api_name": null,
"scroll_to_output": false,
"show_progress": "full",
"every": null,
"batch": false,
"max_batch_size": 4,
"cancels": [],
"types": {
"continuous": false,
"generator": false
},
"collects_event_data": false,
"trigger_after": null,
"trigger_only_on_success": false
}
]
}

View File

@ -0,0 +1,476 @@
{
"version": "3.40.1",
"mode": "blocks",
"dev_mode": true,
"analytics_enabled": true,
"components": [
{
"id": 101,
"type": "markdown",
"props": {
"value": "# Detect Disease From Scan\nWith this model you can lorem ipsum\n- ipsum 1\n- ipsum 2",
"rtl": false,
"latex_delimiters": [
{
"left": "$",
"right": "$",
"display": false
}
],
"name": "markdown",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 102,
"type": "checkboxgroup",
"props": {
"choices": [
[
"Covid",
"Covid"
],
[
"Malaria",
"Malaria"
],
[
"Lung Cancer",
"Lung Cancer"
]
],
"value": [],
"label": "Disease to Scan For",
"show_label": true,
"container": true,
"min_width": 160,
"name": "checkboxgroup",
"visible": true
},
"serializer": "ListStringSerializable",
"api_info": {
"info": {
"type": "array",
"items": {
"type": "string"
}
},
"serialized_info": false
},
"example_inputs": {
"raw": [
"Covid"
],
"serialized": [
"Covid"
]
}
},
{
"id": 103,
"type": "tabs",
"props": {
"visible": true
}
},
{
"id": 104,
"type": "tabitem",
"props": {
"label": "X-ray",
"visible": true
}
},
{
"id": 105,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": true,
"visible": true
}
},
{
"id": 106,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": false,
"mirror_webcam": true,
"brush_color": "#000000",
"mask_opacity": 0.7,
"selectable": false,
"show_share_button": false,
"show_download_button": true,
"show_label": true,
"container": true,
"min_width": 160,
"name": "image",
"visible": true
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image"
},
"serialized_info": true
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
}
},
{
"id": 107,
"type": "json",
"props": {
"show_label": true,
"container": true,
"min_width": 160,
"name": "json",
"visible": true
},
"serializer": "JSONSerializable",
"api_info": {
"info": {
"type": {},
"description": "any valid json"
},
"serialized_info": true
},
"example_inputs": {
"raw": {
"a": 1,
"b": 2
},
"serialized": null
}
},
{
"id": 108,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": true,
"name": "button",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 109,
"type": "tabitem",
"props": {
"label": "CT Scan",
"visible": true
}
},
{
"id": 110,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": true,
"visible": true
}
},
{
"id": 111,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": false,
"mirror_webcam": true,
"brush_color": "#000000",
"mask_opacity": 0.7,
"selectable": false,
"show_share_button": false,
"show_download_button": true,
"show_label": true,
"container": true,
"min_width": 160,
"name": "image",
"visible": true
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image"
},
"serialized_info": true
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
}
},
{
"id": 112,
"type": "json",
"props": {
"show_label": true,
"container": true,
"min_width": 160,
"name": "json",
"visible": true
},
"serializer": "JSONSerializable",
"api_info": {
"info": {
"type": {},
"description": "any valid json"
},
"serialized_info": true
},
"example_inputs": {
"raw": {
"a": 1,
"b": 2
},
"serialized": null
}
},
{
"id": 113,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": true,
"name": "button",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 114,
"type": "textbox",
"props": {
"lines": 1,
"max_lines": 20,
"value": "",
"type": "text",
"autofocus": false,
"show_copy_button": false,
"container": true,
"rtl": false,
"show_label": true,
"min_width": 160,
"name": "textbox",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 115,
"type": "form",
"props": {
"type": "form",
"scale": 0,
"min_width": 0,
"visible": true
}
},
{
"id": 116,
"type": "form",
"props": {
"type": "form",
"scale": 0,
"min_width": 0,
"visible": true
}
}
],
"css": null,
"title": "Gradio",
"space_id": null,
"enable_queue": null,
"show_error": true,
"show_api": true,
"is_colab": false,
"stylesheets": [
"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap",
"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap"
],
"theme": "default",
"layout": {
"id": 100,
"children": [
{
"id": 101
},
{
"id": 115,
"children": [
{
"id": 102
}
]
},
{
"id": 103,
"children": [
{
"id": 104,
"children": [
{
"id": 105,
"children": [
{
"id": 106
},
{
"id": 107
}
]
},
{
"id": 108
}
]
},
{
"id": 109,
"children": [
{
"id": 110,
"children": [
{
"id": 111
},
{
"id": 112
}
]
},
{
"id": 113
}
]
}
]
},
{
"id": 116,
"children": [
{
"id": 114
}
]
}
]
},
"dependencies": [
{
"targets": [
108
],
"trigger": "click",
"inputs": [
102,
106
],
"outputs": [
107
],
"backend_fn": true,
"js": null,
"queue": null,
"api_name": null,
"scroll_to_output": false,
"show_progress": "full",
"every": null,
"batch": false,
"max_batch_size": 4,
"cancels": [],
"types": {
"continuous": false,
"generator": false
},
"collects_event_data": false,
"trigger_after": null,
"trigger_only_on_success": false
},
{
"targets": [
113
],
"trigger": "click",
"inputs": [
102,
111
],
"outputs": [
112
],
"backend_fn": true,
"js": null,
"queue": null,
"api_name": null,
"scroll_to_output": false,
"show_progress": "full",
"every": null,
"batch": false,
"max_batch_size": 4,
"cancels": [],
"types": {
"continuous": false,
"generator": false
},
"collects_event_data": false,
"trigger_after": null,
"trigger_only_on_success": false
}
]
}

View File

@ -0,0 +1,548 @@
{
"version": "3.40.1",
"mode": "blocks",
"dev_mode": true,
"analytics_enabled": true,
"components": [
{
"id": 1,
"type": "markdown",
"props": {
"value": "# Detect Disease From Scan\nWith this model you can lorem ipsum\n- ipsum 1\n- ipsum 2",
"rtl": false,
"latex_delimiters": [
{
"left": "$",
"right": "$",
"display": false
}
],
"name": "markdown",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 2,
"type": "checkboxgroup",
"props": {
"choices": [
[
"Covid",
"Covid"
],
[
"Malaria",
"Malaria"
],
[
"Lung Cancer",
"Lung Cancer"
]
],
"value": [],
"label": "Disease to Scan For",
"show_label": true,
"container": true,
"min_width": 160,
"name": "checkboxgroup",
"visible": true
},
"serializer": "ListStringSerializable",
"api_info": {
"info": {
"type": "array",
"items": {
"type": "string"
}
},
"serialized_info": false
},
"example_inputs": {
"raw": [
"Covid"
],
"serialized": [
"Covid"
]
}
},
{
"id": 3,
"type": "tabs",
"props": {
"visible": true
}
},
{
"id": 4,
"type": "tabitem",
"props": {
"label": "X-ray",
"visible": true
}
},
{
"id": 5,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": true,
"visible": true
}
},
{
"id": 6,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": false,
"mirror_webcam": true,
"brush_color": "#000000",
"mask_opacity": 0.7,
"selectable": false,
"show_share_button": false,
"show_download_button": true,
"show_label": true,
"container": true,
"min_width": 160,
"name": "image",
"visible": true
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image"
},
"serialized_info": true
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
}
},
{
"id": 7,
"type": "json",
"props": {
"show_label": true,
"container": true,
"min_width": 160,
"name": "json",
"visible": true
},
"serializer": "JSONSerializable",
"api_info": {
"info": {
"type": {},
"description": "any valid json"
},
"serialized_info": true
},
"example_inputs": {
"raw": {
"a": 1,
"b": 2
},
"serialized": null
}
},
{
"id": 8,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": true,
"name": "button",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 9,
"type": "tabitem",
"props": {
"label": "CT Scan",
"visible": true
}
},
{
"id": 10,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": true,
"visible": true
}
},
{
"id": 11,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": false,
"mirror_webcam": true,
"brush_color": "#000000",
"mask_opacity": 0.7,
"selectable": false,
"show_share_button": false,
"show_download_button": true,
"show_label": true,
"container": true,
"min_width": 160,
"name": "image",
"visible": true
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image"
},
"serialized_info": true
},
"example_inputs": {
"raw": "data:image/png;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+fn/9ZWb8/PzWlwv///6wWGbImAPgTEMImIN9gUFCEm/gDALULDN8PAD6atYdCTX9gUNKlj8wZAKUsAOzZz+UMAOsJAP/Z2ccMDA8PD/95eX5NWvsJCOVNQPtfX/8zM8+QePLl38MGBr8JCP+zs9myn/8GBqwpAP/GxgwJCPny78lzYLgjAJ8vAP9fX/+MjMUcAN8zM/9wcM8ZGcATEL+QePdZWf/29uc/P9cmJu9MTDImIN+/r7+/vz8/P8VNQGNugV8AAF9fX8swMNgTAFlDOICAgPNSUnNWSMQ5MBAQEJE3QPIGAM9AQMqGcG9vb6MhJsEdGM8vLx8fH98AANIWAMuQeL8fABkTEPPQ0OM5OSYdGFl5jo+Pj/+pqcsTE78wMFNGQLYmID4dGPvd3UBAQJmTkP+8vH9QUK+vr8ZWSHpzcJMmILdwcLOGcHRQUHxwcK9PT9DQ0O/v70w5MLypoG8wKOuwsP/g4P/Q0IcwKEswKMl8aJ9fX2xjdOtGRs/Pz+Dg4GImIP8gIH0sKEAwKKmTiKZ8aB/f39Wsl+LFt8dgUE9PT5x5aHBwcP+AgP+WltdgYMyZfyywz78AAAAAAAD///8AAP9mZv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAKgALAAAAAA9AEQAAAj/AFEJHEiwoMGDCBMqXMiwocAbBww4nEhxoYkUpzJGrMixogkfGUNqlNixJEIDB0SqHGmyJSojM1bKZOmyop0gM3Oe2liTISKMOoPy7GnwY9CjIYcSRYm0aVKSLmE6nfq05QycVLPuhDrxBlCtYJUqNAq2bNWEBj6ZXRuyxZyDRtqwnXvkhACDV+euTeJm1Ki7A73qNWtFiF+/gA95Gly2CJLDhwEHMOUAAuOpLYDEgBxZ4GRTlC1fDnpkM+fOqD6DDj1aZpITp0dtGCDhr+fVuCu3zlg49ijaokTZTo27uG7Gjn2P+hI8+PDPERoUB318bWbfAJ5sUNFcuGRTYUqV/3ogfXp1rWlMc6awJjiAAd2fm4ogXjz56aypOoIde4OE5u/F9x199dlXnnGiHZWEYbGpsAEA3QXYnHwEFliKAgswgJ8LPeiUXGwedCAKABACCN+EA1pYIIYaFlcDhytd51sGAJbo3onOpajiihlO92KHGaUXGwWjUBChjSPiWJuOO/LYIm4v1tXfE6J4gCSJEZ7YgRYUNrkji9P55sF/ogxw5ZkSqIDaZBV6aSGYq/lGZplndkckZ98xoICbTcIJGQAZcNmdmUc210hs35nCyJ58fgmIKX5RQGOZowxaZwYA+JaoKQwswGijBV4C6SiTUmpphMspJx9unX4KaimjDv9aaXOEBteBqmuuxgEHoLX6Kqx+yXqqBANsgCtit4FWQAEkrNbpq7HSOmtwag5w57GrmlJBASEU18ADjUYb3ADTinIttsgSB1oJFfA63bduimuqKB1keqwUhoCSK374wbujvOSu4QG6UvxBRydcpKsav++Ca6G8A6Pr1x2kVMyHwsVxUALDq/krnrhPSOzXG1lUTIoffqGR7Goi2MAxbv6O2kEG56I7CSlRsEFKFVyovDJoIRTg7sugNRDGqCJzJgcKE0ywc0ELm6KBCCJo8DIPFeCWNGcyqNFE06ToAfV0HBRgxsvLThHn1oddQMrXj5DyAQgjEHSAJMWZwS3HPxT/QMbabI/iBCliMLEJKX2EEkomBAUCxRi42VDADxyTYDVogV+wSChqmKxEKCDAYFDFj4OmwbY7bDGdBhtrnTQYOigeChUmc1K3QTnAUfEgGFgAWt88hKA6aCRIXhxnQ1yg3BCayK44EWdkUQcBByEQChFXfCB776aQsG0BIlQgQgE8qO26X1h8cEUep8ngRBnOy74E9QgRgEAC8SvOfQkh7FDBDmS43PmGoIiKUUEGkMEC/PJHgxw0xH74yx/3XnaYRJgMB8obxQW6kL9QYEJ0FIFgByfIL7/IQAlvQwEpnAC7DtLNJCKUoO/w45c44GwCXiAFB/OXAATQryUxdN4LfFiwgjCNYg+kYMIEFkCKDs6PKAIJouyGWMS1FSKJOMRB/BoIxYJIUXFUxNwoIkEKPAgCBZSQHQ1A2EWDfDEUVLyADj5AChSIQW6gu10bE/JG2VnCZGfo4R4d0sdQoBAHhPjhIB94v/wRoRKQWGRHgrhGSQJxCS+0pCZbEhAAOw==",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
}
},
{
"id": 12,
"type": "json",
"props": {
"show_label": true,
"container": true,
"min_width": 160,
"name": "json",
"visible": true
},
"serializer": "JSONSerializable",
"api_info": {
"info": {
"type": {},
"description": "any valid json"
},
"serialized_info": true
},
"example_inputs": {
"raw": {
"a": 1,
"b": 2
},
"serialized": null
}
},
{
"id": 13,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": true,
"name": "button",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 14,
"type": "textbox",
"props": {
"lines": 1,
"max_lines": 20,
"value": "",
"type": "text",
"autofocus": false,
"show_copy_button": false,
"container": true,
"rtl": false,
"show_label": true,
"min_width": 160,
"name": "textbox",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 15,
"type": "form",
"props": {
"type": "form",
"scale": 0,
"min_width": 0,
"visible": true
}
},
{
"id": 16,
"type": "form",
"props": {
"type": "form",
"scale": 0,
"min_width": 0,
"visible": true
}
},
{
"id": 118,
"type": "textbox",
"props": {
"lines": 1,
"max_lines": 20,
"value": "",
"type": "text",
"autofocus": false,
"show_copy_button": false,
"container": true,
"rtl": false,
"show_label": true,
"min_width": 160,
"name": "textbox",
"visible": true
},
"serializer": "StringSerializable",
"api_info": {
"info": {
"type": "string"
},
"serialized_info": false
},
"example_inputs": {
"raw": "Howdy!",
"serialized": "Howdy!"
}
},
{
"id": 119,
"type": "form",
"props": {
"type": "form",
"scale": 0,
"min_width": 0,
"visible": true
}
}
],
"css": null,
"title": "Gradio",
"space_id": null,
"enable_queue": null,
"show_error": true,
"show_api": true,
"is_colab": false,
"stylesheets": [
"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap",
"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap"
],
"theme": "default",
"layout": {
"id": 117,
"children": [
{
"id": 1
},
{
"id": 15,
"children": [
{
"id": 2
}
]
},
{
"id": 3,
"children": [
{
"id": 4,
"children": [
{
"id": 5,
"children": [
{
"id": 6
},
{
"id": 7
}
]
},
{
"id": 8
}
]
},
{
"id": 9,
"children": [
{
"id": 10,
"children": [
{
"id": 11
},
{
"id": 12
}
]
},
{
"id": 13
}
]
}
]
},
{
"id": 16,
"children": [
{
"id": 14
}
]
},
{
"id": 119,
"children": [
{
"id": 118
}
]
}
]
},
"dependencies": [
{
"targets": [
8
],
"trigger": "click",
"inputs": [
2,
6
],
"outputs": [
7
],
"backend_fn": true,
"js": null,
"queue": null,
"api_name": null,
"scroll_to_output": false,
"show_progress": "full",
"every": null,
"batch": false,
"max_batch_size": 4,
"cancels": [],
"types": {
"continuous": false,
"generator": false
},
"collects_event_data": false,
"trigger_after": null,
"trigger_only_on_success": false
},
{
"targets": [
13
],
"trigger": "click",
"inputs": [
2,
11
],
"outputs": [
12
],
"backend_fn": true,
"js": null,
"queue": null,
"api_name": null,
"scroll_to_output": false,
"show_progress": "full",
"every": null,
"batch": false,
"max_batch_size": 4,
"cancels": [],
"types": {
"continuous": false,
"generator": false
},
"collects_event_data": false,
"trigger_after": null,
"trigger_only_on_success": false
},
{
"targets": [],
"trigger": "load",
"inputs": [],
"outputs": [
118
],
"backend_fn": true,
"js": null,
"queue": null,
"api_name": null,
"scroll_to_output": false,
"show_progress": "full",
"every": null,
"batch": false,
"max_batch_size": 4,
"cancels": [],
"types": {
"continuous": false,
"generator": false
},
"collects_event_data": false,
"trigger_after": null,
"trigger_only_on_success": false
}
]
}

View File

@ -1,10 +1,11 @@
from __future__ import annotations
import copy
import json
import os
import sys
import unittest.mock as mock
import warnings
from pathlib import Path
from unittest.mock import MagicMock
import pytest
@ -15,11 +16,6 @@ from pydantic import BaseModel
from typing_extensions import Literal
from gradio import EventData, Request
from gradio.test_data.blocks_configs import (
XRAY_CONFIG,
XRAY_CONFIG_DIFF_IDS,
XRAY_CONFIG_WITH_MISTAKE,
)
from gradio.utils import (
AsyncRequest,
abspath,
@ -112,93 +108,19 @@ class TestUtils:
assert not kaggle_check()
class TestAssertConfigsEquivalent:
def test_same_configs(self):
assert assert_configs_are_equivalent_besides_ids(XRAY_CONFIG, XRAY_CONFIG)
def test_assert_configs_are_equivalent():
test_dir = Path(__file__).parent / "test_files"
with open(test_dir / "xray_config.json") as fp:
xray_config = json.load(fp)
with open(test_dir / "xray_config_diff_ids.json") as fp:
xray_config_diff_ids = json.load(fp)
with open(test_dir / "xray_config_wrong.json") as fp:
xray_config_wrong = json.load(fp)
def test_equivalent_configs(self):
assert assert_configs_are_equivalent_besides_ids(
XRAY_CONFIG, XRAY_CONFIG_DIFF_IDS
)
def test_different_configs(self):
with pytest.raises(AssertionError):
assert_configs_are_equivalent_besides_ids(
XRAY_CONFIG_WITH_MISTAKE, XRAY_CONFIG
)
def test_different_dependencies(self):
config1 = {
"version": "3.0.20\n",
"mode": "blocks",
"dev_mode": True,
"components": [
{
"id": 1,
"type": "textbox",
"props": {
"lines": 1,
"max_lines": 20,
"placeholder": "What is your name?",
"value": "",
"show_label": True,
"name": "textbox",
"visible": True,
"style": {},
},
},
{
"id": 2,
"type": "textbox",
"props": {
"lines": 1,
"max_lines": 20,
"value": "",
"show_label": True,
"name": "textbox",
"visible": True,
"style": {},
},
},
{
"id": 3,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": False,
"show_label": True,
"name": "image",
"visible": True,
"style": {"height": 54, "width": 240},
},
},
],
"css": None,
"enable_queue": False,
"layout": {"id": 0, "children": [{"id": 1}, {"id": 2}, {"id": 3}]},
"dependencies": [
{
"targets": [1],
"trigger": "submit",
"inputs": [1],
"outputs": [2],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": "greet",
"scroll_to_output": False,
"show_progress": True,
"documentation": [["(str): text"], ["(str | None): text"]],
}
],
}
config2 = copy.deepcopy(config1)
config2["dependencies"][0]["documentation"] = None
with pytest.raises(AssertionError):
assert_configs_are_equivalent_besides_ids(config1, config2)
assert assert_configs_are_equivalent_besides_ids(xray_config, xray_config)
assert assert_configs_are_equivalent_besides_ids(xray_config, xray_config_diff_ids)
with pytest.raises(AssertionError):
assert_configs_are_equivalent_besides_ids(xray_config, xray_config_wrong)
class TestFormatNERList: