mirror of
https://github.com/gradio-app/gradio.git
synced 2025-01-30 11:00:11 +08:00
Refactor examples so they accept data in the same format as is returned by function, rename .as_example()
to .process_example()
(#6933)
* image-editor-examples * add changeset * add changeset * delete changeset * change to process_example() * add changeset * changes for all components until dataset.py * rename * fix checkboxgroup * format * changes * add changeset * changes * add changeset * radio * add changeset * changes * add changeset * changes * examples * remove print * fix * clean * add changeset * fix tests * fix tests * fix test * fix * add changeset * fix video example * add changeset --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
523b6bc534
commit
9cefd2e90a
11
.changeset/large-olives-unite.md
Normal file
11
.changeset/large-olives-unite.md
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
"@gradio/checkboxgroup": minor
|
||||
"@gradio/dropdown": minor
|
||||
"@gradio/image": minor
|
||||
"@gradio/imageeditor": minor
|
||||
"@gradio/radio": minor
|
||||
"@gradio/video": minor
|
||||
"gradio": minor
|
||||
---
|
||||
|
||||
fix:Refactor examples so they accept data in the same format as is returned by function, rename `.as_example()` to `.process_example()`
|
@ -103,5 +103,5 @@ class SimpleDropdown(FormComponent):
|
||||
self._warn_if_invalid_choice(y)
|
||||
return y
|
||||
|
||||
def as_example(self, input_data):
|
||||
def process_example(self, input_data):
|
||||
return next((c[0] for c in self.choices if c[1] == input_data), None)
|
||||
|
@ -292,8 +292,14 @@ class Audio(
|
||||
binary_data = binary_data[44:]
|
||||
return binary_data, output_file
|
||||
|
||||
def as_example(self, input_data: str | None) -> str:
|
||||
return Path(input_data).name if input_data else ""
|
||||
def process_example(
|
||||
self, value: tuple[int, np.ndarray] | str | Path | bytes | None
|
||||
) -> str:
|
||||
if value is None:
|
||||
return ""
|
||||
elif isinstance(value, (str, Path)):
|
||||
return Path(value).name
|
||||
return "(audio)"
|
||||
|
||||
def check_streamable(self):
|
||||
if (
|
||||
|
@ -60,12 +60,12 @@ class ComponentBase(ABC, metaclass=ComponentMeta):
|
||||
return value
|
||||
|
||||
@abstractmethod
|
||||
def as_example(self, value):
|
||||
def process_example(self, value):
|
||||
"""
|
||||
Return the input data in a way that can be displayed by the examples dataset component in the front-end.
|
||||
Process the input data in a way that can be displayed by the examples dataset component in the front-end.
|
||||
|
||||
For example, only return the name of a file as opposed to a full path. Or get the head of a dataframe.
|
||||
Must be able to be converted to a string to put in the config.
|
||||
The return value must be able to be json-serializable to put in the config.
|
||||
"""
|
||||
pass
|
||||
|
||||
@ -241,9 +241,23 @@ class Component(ComponentBase, Block):
|
||||
"""Add a load event that runs `callable`, optionally every `every` seconds."""
|
||||
self.load_event_to_attach = (callable, every)
|
||||
|
||||
def as_example(self, input_data):
|
||||
"""Return the input data in a way that can be displayed by the examples dataset component in the front-end."""
|
||||
return input_data
|
||||
def process_example(self, value):
|
||||
"""
|
||||
Process the input data in a way that can be displayed by the examples dataset component in the front-end.
|
||||
By default, this calls the `.postprocess()` method of the component. However, if the `.postprocess()` method is
|
||||
computationally intensive, or returns a large payload, a custom implementation may be appropriate.
|
||||
|
||||
For example, the `process_example()` method of the `gr.Audio()` component only returns the name of the file, not
|
||||
the processed audio file. The `.process_example()` method of the `gr.Dataframe()` returns the head of a dataframe
|
||||
instead of the full dataframe.
|
||||
|
||||
The return value of this method must be json-serializable to put in the config.
|
||||
"""
|
||||
return self.postprocess(value)
|
||||
|
||||
def as_example(self, value):
|
||||
"""Deprecated and replaced by `process_example()`."""
|
||||
return self.process_example(value)
|
||||
|
||||
def api_info(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
@ -124,16 +124,3 @@ class CheckboxGroup(FormComponent):
|
||||
if not isinstance(value, list):
|
||||
value = [value]
|
||||
return value
|
||||
|
||||
def as_example(self, input_data):
|
||||
if input_data is None:
|
||||
return None
|
||||
elif not isinstance(input_data, list):
|
||||
input_data = [input_data]
|
||||
for data in input_data:
|
||||
if data not in [c[0] for c in self.choices]:
|
||||
raise ValueError(f"Example {data} provided not a valid choice.")
|
||||
return [
|
||||
next((c[0] for c in self.choices if c[1] == data), None)
|
||||
for data in input_data
|
||||
]
|
||||
|
@ -187,11 +187,13 @@ class Dataframe(Component):
|
||||
| dict
|
||||
| str
|
||||
| None,
|
||||
) -> DataframeData | dict:
|
||||
) -> DataframeData:
|
||||
if value is None:
|
||||
return self.postprocess(self.empty_input)
|
||||
if isinstance(value, dict):
|
||||
return value
|
||||
return DataframeData(
|
||||
headers=value.get("headers", []), data=value.get("data", [[]])
|
||||
)
|
||||
if isinstance(value, (str, pd.DataFrame)):
|
||||
if isinstance(value, str):
|
||||
value = pd.read_csv(value) # type: ignore
|
||||
@ -289,14 +291,22 @@ class Dataframe(Component):
|
||||
f"Check the values passed to `col_count` and `headers`."
|
||||
)
|
||||
|
||||
def as_example(self, input_data: pd.DataFrame | np.ndarray | str | None):
|
||||
if input_data is None:
|
||||
def process_example(
|
||||
self,
|
||||
value: pd.DataFrame
|
||||
| Styler
|
||||
| np.ndarray
|
||||
| list
|
||||
| list[list]
|
||||
| dict
|
||||
| str
|
||||
| None,
|
||||
):
|
||||
if value is None:
|
||||
return ""
|
||||
elif isinstance(input_data, pd.DataFrame):
|
||||
return input_data.head(n=5).to_dict(orient="split")["data"] # type: ignore
|
||||
elif isinstance(input_data, np.ndarray):
|
||||
return input_data.tolist()
|
||||
return input_data
|
||||
value_df_data = self.postprocess(value)
|
||||
value_df = pd.DataFrame(value_df_data.data, columns=value_df_data.headers)
|
||||
return value_df.head(n=5).to_dict(orient="split")["data"]
|
||||
|
||||
def example_inputs(self) -> Any:
|
||||
return {"headers": ["a", "b"], "data": [["foo", "bar"]]}
|
||||
|
@ -6,6 +6,7 @@ from typing import Any, Literal
|
||||
|
||||
from gradio_client.documentation import document, set_documentation_group
|
||||
|
||||
from gradio import processing_utils
|
||||
from gradio.components.base import (
|
||||
Component,
|
||||
get_component_instance,
|
||||
@ -89,10 +90,16 @@ class Dataset(Component):
|
||||
self.samples = [[]] if samples is None else samples
|
||||
for example in self.samples:
|
||||
for i, (component, ex) in enumerate(zip(self._components, example)):
|
||||
# If proxy_url is set, that means it is being loaded from an external Gradio app
|
||||
# which means that the example has already been processed.
|
||||
if self.proxy_url is None:
|
||||
# If proxy_url is set, that means it is being loaded from an external Gradio app
|
||||
# which means that the example has already been processed.
|
||||
# The `as_example()` method has been renamed to `process_example()` but we
|
||||
# use the previous name to be backwards-compatible with previously-created
|
||||
# custom components
|
||||
example[i] = component.as_example(ex)
|
||||
example[i] = processing_utils.move_files_to_cache(
|
||||
example[i], component
|
||||
)
|
||||
self.type = type
|
||||
self.label = label
|
||||
if headers is not None:
|
||||
|
@ -176,11 +176,3 @@ class Dropdown(FormComponent):
|
||||
else:
|
||||
self._warn_if_invalid_choice(value)
|
||||
return value
|
||||
|
||||
def as_example(self, input_data):
|
||||
if self.multiselect:
|
||||
return [
|
||||
next((c[0] for c in self.choices if c[1] == data), None)
|
||||
for data in input_data
|
||||
]
|
||||
return next((c[0] for c in self.choices if c[1] == input_data), None)
|
||||
|
@ -160,7 +160,7 @@ class File(Component):
|
||||
size=Path(value).stat().st_size,
|
||||
)
|
||||
|
||||
def as_example(self, input_data: str | list | None) -> str:
|
||||
def process_example(self, input_data: str | list | None) -> str:
|
||||
if input_data is None:
|
||||
return ""
|
||||
elif isinstance(input_data, list):
|
||||
|
@ -188,7 +188,6 @@ class Image(StreamingInput, Component):
|
||||
) -> FileData | None:
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
if isinstance(value, str) and value.lower().endswith(".svg"):
|
||||
return FileData(path=value, orig_name=Path(value).name)
|
||||
saved = image_utils.save_image(value, self.GRADIO_CACHE)
|
||||
@ -201,10 +200,5 @@ class Image(StreamingInput, Component):
|
||||
"Image streaming only available if sources is ['webcam']. Streaming not supported with multiple sources."
|
||||
)
|
||||
|
||||
def as_example(self, input_data: str | Path | None) -> str | None:
|
||||
if input_data is None:
|
||||
return None
|
||||
return self.move_resource_to_block_cache(input_data)
|
||||
|
||||
def example_inputs(self) -> Any:
|
||||
return "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
|
||||
|
@ -8,7 +8,6 @@ from pathlib import Path
|
||||
from typing import Any, Iterable, List, Literal, Optional, TypedDict, Union, cast
|
||||
|
||||
import numpy as np
|
||||
from gradio_client import utils as client_utils
|
||||
from gradio_client.documentation import document, set_documentation_group
|
||||
from PIL import Image as _Image # using _ to minimize namespace pollution
|
||||
|
||||
@ -310,37 +309,6 @@ class ImageEditor(Component):
|
||||
else None,
|
||||
)
|
||||
|
||||
def as_example(
|
||||
self, input_data: EditorExampleValue | str | None
|
||||
) -> EditorExampleValue | None:
|
||||
def resolve_path(file_or_url: str | None) -> str | None:
|
||||
if file_or_url is None:
|
||||
return None
|
||||
input_data = str(file_or_url)
|
||||
# If an externally hosted image or a URL, don't convert to absolute path
|
||||
if self.proxy_url or client_utils.is_http_url_like(input_data):
|
||||
return input_data
|
||||
return self.move_resource_to_block_cache(input_data)
|
||||
|
||||
if input_data is None:
|
||||
return None
|
||||
elif isinstance(input_data, str):
|
||||
input_data = {
|
||||
"background": input_data,
|
||||
"layers": [],
|
||||
"composite": input_data,
|
||||
}
|
||||
|
||||
input_data["background"] = resolve_path(input_data["background"])
|
||||
input_data["layers"] = (
|
||||
[resolve_path(f) for f in input_data["layers"]]
|
||||
if input_data["layers"]
|
||||
else []
|
||||
)
|
||||
input_data["composite"] = resolve_path(input_data["composite"])
|
||||
|
||||
return input_data
|
||||
|
||||
def example_inputs(self) -> Any:
|
||||
return {
|
||||
"background": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
|
||||
|
@ -84,10 +84,6 @@ class Markdown(Component):
|
||||
unindented_y = inspect.cleandoc(value)
|
||||
return unindented_y
|
||||
|
||||
def as_example(self, input_data: str | None) -> str:
|
||||
postprocessed = self.postprocess(input_data)
|
||||
return postprocessed if postprocessed else ""
|
||||
|
||||
def preprocess(self, payload: str | None) -> str | None:
|
||||
return payload
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Model3D(Component):
|
||||
return value
|
||||
return FileData(path=str(value), orig_name=Path(value).name)
|
||||
|
||||
def as_example(self, input_data: str | None) -> str:
|
||||
def process_example(self, input_data: str | Path | None) -> str:
|
||||
return Path(input_data).name if input_data else ""
|
||||
|
||||
def example_inputs(self):
|
||||
|
@ -125,6 +125,3 @@ class Radio(FormComponent):
|
||||
"title": "Radio",
|
||||
"type": "string",
|
||||
}
|
||||
|
||||
def as_example(self, input_data):
|
||||
return next((c[0] for c in self.choices if c[1] == input_data), None)
|
||||
|
@ -338,8 +338,3 @@ class Video(Component):
|
||||
|
||||
def example_inputs(self) -> Any:
|
||||
return "https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/world.mp4"
|
||||
|
||||
def as_example(self, input_data: str | Path | None) -> str | None:
|
||||
if input_data is None:
|
||||
return None
|
||||
return self.move_resource_to_block_cache(input_data)
|
||||
|
@ -237,7 +237,7 @@ def move_resource_to_block_cache(
|
||||
def move_files_to_cache(data: Any, block: Component, postprocess: bool = False):
|
||||
"""Move files to cache and replace the file path with the cache path.
|
||||
|
||||
Runs after postprocess and before preprocess.
|
||||
Runs after .postprocess(), after .process_example(), and before .preprocess().
|
||||
|
||||
Args:
|
||||
data: The input or output data for a component. Can be a dictionary or a dataclass
|
||||
|
@ -110,10 +110,9 @@ To enable the example view, you must have the following two files in the top of
|
||||
* `Example.svelte`: this corresponds to the "example version" of your component
|
||||
* `Index.svelte`: this corresponds to the "regular version"
|
||||
|
||||
In the backend, you typically don't need to do anything unless you would like to modify the user-provided `value` of the examples to something else before it is sent to the frontend.
|
||||
You can do this in the `as_example` method of the component.
|
||||
In the backend, you typically don't need to do anything. The user-provided example `value` is processed using the same `.postprocess()` method described earlier. If you'd like to do process the data differently (for example, if the `.postprocess()` method is computationally expensive), then you can write your own `.process_example()` method for your custom component, which will be used instead.
|
||||
|
||||
The `Example.svelte` and `as_example` methods will be covered in greater depth in the dedicated [frontend](./frontend) and [backend](./backend) guides.
|
||||
The `Example.svelte` file and `process_example()` method will be covered in greater depth in the dedicated [frontend](./frontend) and [backend](./backend) guides respectively.
|
||||
|
||||
### What you need to remember
|
||||
|
||||
|
@ -55,13 +55,13 @@ They handle the conversion from the data sent by the frontend to the format expe
|
||||
return y
|
||||
```
|
||||
|
||||
### `as_example`
|
||||
### `process_example`
|
||||
|
||||
Takes in the original Python value and returns the modified value that should be displayed in the examples preview in the app.
|
||||
Let's look at the following example from the `Radio` component.
|
||||
If not provided, the `.postprocess()` method is used instead. Let's look at the following example from the `SimpleDropdown` component.
|
||||
|
||||
```python
|
||||
def as_example(self, input_data):
|
||||
def process_example(self, input_data):
|
||||
return next((c[0] for c in self.choices if c[1] == input_data), None)
|
||||
```
|
||||
|
||||
@ -69,7 +69,7 @@ Since `self.choices` is a list of tuples corresponding to (`display_name`, `valu
|
||||
|
||||
```python
|
||||
@abstractmethod
|
||||
def as_example(self, y):
|
||||
def process_example(self, y):
|
||||
pass
|
||||
```
|
||||
|
||||
|
@ -22,7 +22,7 @@ If you would like to share your component with the gradio community, it is recom
|
||||
|
||||
## What methods are mandatory for implementing a custom component in Gradio?
|
||||
|
||||
You must implement the `preprocess`, `postprocess`, `as_example`, `api_info`, `example_inputs`, `flag`, and `read_from_flag` methods. Read more in the [backend guide](./backend).
|
||||
You must implement the `preprocess`, `postprocess`, `api_info`, `example_inputs`, `flag`, and `read_from_flag` methods. Read more in the [backend guide](./backend).
|
||||
|
||||
## What is the purpose of a `data_model` in Gradio custom components?
|
||||
|
||||
|
@ -2,6 +2,19 @@
|
||||
export let value: string[];
|
||||
export let type: "gallery" | "table";
|
||||
export let selected = false;
|
||||
export let choices: [string, string | number][];
|
||||
|
||||
let names = value
|
||||
.map(
|
||||
(val) =>
|
||||
(
|
||||
choices.find((pair) => pair[1] === val) as
|
||||
| [string, string | number]
|
||||
| undefined
|
||||
)?.[0]
|
||||
)
|
||||
.filter((name) => name !== undefined);
|
||||
let names_string = names.join(", ");
|
||||
</script>
|
||||
|
||||
<div
|
||||
@ -9,7 +22,7 @@
|
||||
class:gallery={type === "gallery"}
|
||||
class:selected
|
||||
>
|
||||
{#each value as check, i}{check.toLocaleString()}{#if i !== value.length - 1}, {/if}{/each}
|
||||
{names_string}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -1,7 +1,21 @@
|
||||
<script lang="ts">
|
||||
export let value: string;
|
||||
export let value: string | string[];
|
||||
export let type: "gallery" | "table";
|
||||
export let selected = false;
|
||||
export let choices: [string, string | number][];
|
||||
|
||||
let value_array = Array.isArray(value) ? value : [value];
|
||||
let names = value_array
|
||||
.map(
|
||||
(val) =>
|
||||
(
|
||||
choices.find((pair) => pair[1] === val) as
|
||||
| [string, string | number]
|
||||
| undefined
|
||||
)?.[0]
|
||||
)
|
||||
.filter((name) => name !== undefined);
|
||||
let names_string = names.join(", ");
|
||||
</script>
|
||||
|
||||
<div
|
||||
@ -9,7 +23,7 @@
|
||||
class:gallery={type === "gallery"}
|
||||
class:selected
|
||||
>
|
||||
{value}
|
||||
{names_string}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -1,7 +1,8 @@
|
||||
<script lang="ts">
|
||||
import Image from "./shared/Image.svelte";
|
||||
import type { FileData } from "@gradio/client";
|
||||
|
||||
export let value: string;
|
||||
export let value: null | FileData;
|
||||
export let samples_dir: string;
|
||||
export let type: "gallery" | "table";
|
||||
export let selected = false;
|
||||
@ -13,7 +14,7 @@
|
||||
class:gallery={type === "gallery"}
|
||||
class:selected
|
||||
>
|
||||
<Image src={samples_dir + value} alt="" />
|
||||
<Image src={samples_dir + value?.path} alt="" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -14,7 +14,10 @@
|
||||
class:gallery={type === "gallery"}
|
||||
class:selected
|
||||
>
|
||||
<Image src={samples_dir + (value.composite || value.background)} alt="" />
|
||||
<Image
|
||||
src={samples_dir + (value.composite?.path || value.background?.path)}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -2,6 +2,10 @@
|
||||
export let value: string;
|
||||
export let type: "gallery" | "table";
|
||||
export let selected = false;
|
||||
export let choices: [string, string | number][];
|
||||
|
||||
let name = choices.find((pair) => pair[1] === value);
|
||||
let name_string = name ? name[0] : "";
|
||||
</script>
|
||||
|
||||
<div
|
||||
@ -9,7 +13,7 @@
|
||||
class:gallery={type === "gallery"}
|
||||
class:selected
|
||||
>
|
||||
{value}
|
||||
{name_string}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -1,10 +1,11 @@
|
||||
<script lang="ts">
|
||||
import Video from "./shared/Video.svelte";
|
||||
import { playable } from "./shared/utils";
|
||||
import { type FileData } from "@gradio/client";
|
||||
|
||||
export let type: "gallery" | "table";
|
||||
export let selected = false;
|
||||
export let value: string;
|
||||
export let value: { video: FileData; subtitles: FileData | null } | null;
|
||||
export let samples_dir: string;
|
||||
let video: HTMLVideoElement;
|
||||
|
||||
@ -33,7 +34,7 @@
|
||||
on:loadeddata={init}
|
||||
on:mouseover={video.play.bind(video)}
|
||||
on:mouseout={video.pause.bind(video)}
|
||||
src={samples_dir + value}
|
||||
src={samples_dir + value?.video.path}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
|
162
pnpm-lock.yaml
162
pnpm-lock.yaml
@ -1,4 +1,4 @@
|
||||
lockfileVersion: '6.0'
|
||||
lockfileVersion: '6.1'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
@ -262,16 +262,16 @@ importers:
|
||||
version: 2.0.0(@sveltejs/kit@1.26.0)
|
||||
'@sveltejs/kit':
|
||||
specifier: ^1.5.0
|
||||
version: 1.26.0(svelte@4.2.3)(vite@4.5.0)
|
||||
version: 1.26.0(svelte@4.2.2)(vite@4.5.0)
|
||||
prettier:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
prettier-plugin-svelte:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(prettier@3.0.0)(svelte@4.2.3)
|
||||
version: 3.0.0(prettier@3.0.0)(svelte@4.2.2)
|
||||
svelte-check:
|
||||
specifier: ^3.0.1
|
||||
version: 3.4.4(@babel/core@7.23.3)(less@4.2.0)(postcss@8.4.27)(svelte@4.2.3)
|
||||
version: 3.4.4(@babel/core@7.23.3)(less@4.2.0)(postcss@8.4.27)(svelte@4.2.2)
|
||||
typescript:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.2
|
||||
@ -292,7 +292,7 @@ importers:
|
||||
version: 3.0.0
|
||||
mdsvex:
|
||||
specifier: ^0.11.0
|
||||
version: 0.11.0(svelte@4.2.3)
|
||||
version: 0.11.0(svelte@4.2.2)
|
||||
postcss:
|
||||
specifier: '>=8.3.3 <9.0.0'
|
||||
version: 8.4.27
|
||||
@ -305,7 +305,7 @@ importers:
|
||||
version: 2.0.2(@sveltejs/kit@1.27.6)
|
||||
'@sveltejs/kit':
|
||||
specifier: ^1.27.6
|
||||
version: 1.27.6(svelte@4.2.3)(vite@4.5.0)
|
||||
version: 1.27.6(svelte@4.2.2)(vite@4.5.0)
|
||||
'@tailwindcss/forms':
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(tailwindcss@3.1.6)
|
||||
@ -6755,7 +6755,7 @@ packages:
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': ^1.0.0
|
||||
dependencies:
|
||||
'@sveltejs/kit': 1.26.0(svelte@4.2.3)(vite@4.5.0)
|
||||
'@sveltejs/kit': 1.26.0(svelte@4.2.2)(vite@4.5.0)
|
||||
import-meta-resolve: 2.2.2
|
||||
dev: true
|
||||
|
||||
@ -6764,7 +6764,7 @@ packages:
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': ^1.0.0
|
||||
dependencies:
|
||||
'@sveltejs/kit': 1.27.6(svelte@4.2.3)(vite@4.5.0)
|
||||
'@sveltejs/kit': 1.27.6(svelte@4.2.2)(vite@4.5.0)
|
||||
import-meta-resolve: 2.2.2
|
||||
dev: true
|
||||
|
||||
@ -6773,7 +6773,7 @@ packages:
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': ^1.5.0
|
||||
dependencies:
|
||||
'@sveltejs/kit': 1.27.6(svelte@4.2.3)(vite@4.5.0)
|
||||
'@sveltejs/kit': 1.27.6(svelte@4.2.2)(vite@4.5.0)
|
||||
dev: true
|
||||
|
||||
/@sveltejs/adapter-vercel@3.0.3(@sveltejs/kit@1.27.6):
|
||||
@ -6781,7 +6781,7 @@ packages:
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': ^1.5.0
|
||||
dependencies:
|
||||
'@sveltejs/kit': 1.27.6(svelte@4.2.3)(vite@4.5.0)
|
||||
'@sveltejs/kit': 1.27.6(svelte@4.2.2)(vite@4.5.0)
|
||||
'@vercel/nft': 0.23.1
|
||||
esbuild: 0.18.20
|
||||
transitivePeerDependencies:
|
||||
@ -6789,7 +6789,7 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sveltejs/kit@1.26.0(svelte@4.2.3)(vite@4.5.0):
|
||||
/@sveltejs/kit@1.26.0(svelte@4.2.2)(vite@4.5.0):
|
||||
resolution: {integrity: sha512-CV/AlTziC05yrz7UjVqEd0pH6+2dnrbmcnHGr2d3jXtmOgzNnlDkXtX8g3BfJ6nntsPD+0jtS2PzhvRHblRz4A==}
|
||||
engines: {node: ^16.14 || >=18}
|
||||
hasBin: true
|
||||
@ -6798,7 +6798,7 @@ packages:
|
||||
svelte: ^3.54.0 || ^4.0.0-next.0
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 2.5.2(svelte@4.2.3)(vite@4.5.0)
|
||||
'@sveltejs/vite-plugin-svelte': 2.5.2(svelte@4.2.2)(vite@4.5.0)
|
||||
'@types/cookie': 0.5.4
|
||||
cookie: 0.5.0
|
||||
devalue: 4.3.2
|
||||
@ -6809,7 +6809,7 @@ packages:
|
||||
sade: 1.8.1
|
||||
set-cookie-parser: 2.6.0
|
||||
sirv: 2.0.3
|
||||
svelte: 4.2.3
|
||||
svelte: 4.2.2
|
||||
tiny-glob: 0.2.9
|
||||
undici: 5.26.5
|
||||
vite: 4.5.0(@types/node@20.3.2)(less@4.2.0)(lightningcss@1.21.7)(sass@1.66.1)(stylus@0.62.0)(sugarss@4.0.1)
|
||||
@ -6817,7 +6817,7 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@sveltejs/kit@1.27.6(svelte@4.2.3)(vite@4.5.0):
|
||||
/@sveltejs/kit@1.27.6(svelte@4.2.2)(vite@4.5.0):
|
||||
resolution: {integrity: sha512-GsjTkMbKzXdbeRg0tk8S7HNShQ4879ftRr0ZHaZfjbig1xQwG57Bvcm9U9/mpLJtCapLbLWUnygKrgcLISLC8A==}
|
||||
engines: {node: ^16.14 || >=18}
|
||||
hasBin: true
|
||||
@ -6826,7 +6826,7 @@ packages:
|
||||
svelte: ^3.54.0 || ^4.0.0-next.0 || ^5.0.0-next.0
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 2.5.2(svelte@4.2.3)(vite@4.5.0)
|
||||
'@sveltejs/vite-plugin-svelte': 2.5.2(svelte@4.2.2)(vite@4.5.0)
|
||||
'@types/cookie': 0.5.4
|
||||
cookie: 0.5.0
|
||||
devalue: 4.3.2
|
||||
@ -6837,7 +6837,7 @@ packages:
|
||||
sade: 1.8.1
|
||||
set-cookie-parser: 2.6.0
|
||||
sirv: 2.0.3
|
||||
svelte: 4.2.3
|
||||
svelte: 4.2.2
|
||||
tiny-glob: 0.2.9
|
||||
undici: 5.26.5
|
||||
vite: 4.5.0(@types/node@20.3.2)(less@4.2.0)(lightningcss@1.21.7)(sass@1.66.1)(stylus@0.62.0)(sugarss@4.0.1)
|
||||
@ -6859,6 +6859,21 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
/@sveltejs/vite-plugin-svelte-inspector@1.0.4(@sveltejs/vite-plugin-svelte@2.5.2)(svelte@4.2.2)(vite@4.5.0):
|
||||
resolution: {integrity: sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==}
|
||||
engines: {node: ^14.18.0 || >= 16}
|
||||
peerDependencies:
|
||||
'@sveltejs/vite-plugin-svelte': ^2.2.0
|
||||
svelte: ^3.54.0 || ^4.0.0
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 2.5.2(svelte@4.2.2)(vite@4.5.0)
|
||||
debug: 4.3.4
|
||||
svelte: 4.2.2
|
||||
vite: 4.5.0(@types/node@20.3.2)(less@4.2.0)(lightningcss@1.21.7)(sass@1.66.1)(stylus@0.62.0)(sugarss@4.0.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
/@sveltejs/vite-plugin-svelte-inspector@1.0.4(@sveltejs/vite-plugin-svelte@2.5.2)(svelte@4.2.3)(vite@4.5.0):
|
||||
resolution: {integrity: sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==}
|
||||
engines: {node: ^14.18.0 || >= 16}
|
||||
@ -6873,6 +6888,7 @@ packages:
|
||||
vite: 4.5.0(@types/node@20.3.2)(less@4.2.0)(lightningcss@1.21.7)(sass@1.66.1)(stylus@0.62.0)(sugarss@4.0.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sveltejs/vite-plugin-svelte@2.5.2(svelte@4.2.2)(vite@4.3.9):
|
||||
resolution: {integrity: sha512-Dfy0Rbl+IctOVfJvWGxrX/3m6vxPLH8o0x+8FA5QEyMUQMo4kGOVIojjryU7YomBAexOTAuYf1RT7809yDziaA==}
|
||||
@ -6893,6 +6909,25 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
/@sveltejs/vite-plugin-svelte@2.5.2(svelte@4.2.2)(vite@4.5.0):
|
||||
resolution: {integrity: sha512-Dfy0Rbl+IctOVfJvWGxrX/3m6vxPLH8o0x+8FA5QEyMUQMo4kGOVIojjryU7YomBAexOTAuYf1RT7809yDziaA==}
|
||||
engines: {node: ^14.18.0 || >= 16}
|
||||
peerDependencies:
|
||||
svelte: ^3.54.0 || ^4.0.0 || ^5.0.0-next.0
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 1.0.4(@sveltejs/vite-plugin-svelte@2.5.2)(svelte@4.2.2)(vite@4.5.0)
|
||||
debug: 4.3.4
|
||||
deepmerge: 4.3.1
|
||||
kleur: 4.1.5
|
||||
magic-string: 0.30.5
|
||||
svelte: 4.2.2
|
||||
svelte-hmr: 0.15.3(svelte@4.2.2)
|
||||
vite: 4.5.0(@types/node@20.3.2)(less@4.2.0)(lightningcss@1.21.7)(sass@1.66.1)(stylus@0.62.0)(sugarss@4.0.1)
|
||||
vitefu: 0.2.5(vite@4.5.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
/@sveltejs/vite-plugin-svelte@2.5.2(svelte@4.2.3)(vite@4.5.0):
|
||||
resolution: {integrity: sha512-Dfy0Rbl+IctOVfJvWGxrX/3m6vxPLH8o0x+8FA5QEyMUQMo4kGOVIojjryU7YomBAexOTAuYf1RT7809yDziaA==}
|
||||
engines: {node: ^14.18.0 || >= 16}
|
||||
@ -6911,6 +6946,7 @@ packages:
|
||||
vitefu: 0.2.5(vite@4.5.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@tailwindcss/forms@0.5.0(tailwindcss@3.1.6):
|
||||
resolution: {integrity: sha512-KzWugryEBFkmoaYcBE18rs6gthWCFHHO7cAZm2/hv3hwD67AzwP7udSCa22E7R1+CEJL/FfhYsJWrc0b1aeSzw==}
|
||||
@ -12142,7 +12178,7 @@ packages:
|
||||
/mdn-data@2.0.30:
|
||||
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
|
||||
|
||||
/mdsvex@0.11.0(svelte@4.2.3):
|
||||
/mdsvex@0.11.0(svelte@4.2.2):
|
||||
resolution: {integrity: sha512-gJF1s0N2nCmdxcKn8HDn0LKrN8poStqAicp6bBcsKFd/zkUBGLP5e7vnxu+g0pjBbDFOscUyI1mtHz+YK2TCDw==}
|
||||
peerDependencies:
|
||||
svelte: '>=3 <5'
|
||||
@ -12150,7 +12186,7 @@ packages:
|
||||
'@types/unist': 2.0.10
|
||||
prism-svelte: 0.4.7
|
||||
prismjs: 1.29.0
|
||||
svelte: 4.2.3
|
||||
svelte: 4.2.2
|
||||
vfile-message: 2.0.4
|
||||
dev: false
|
||||
|
||||
@ -13281,17 +13317,6 @@ packages:
|
||||
dependencies:
|
||||
prettier: 3.0.0
|
||||
svelte: 4.2.2
|
||||
dev: false
|
||||
|
||||
/prettier-plugin-svelte@3.0.0(prettier@3.0.0)(svelte@4.2.3):
|
||||
resolution: {integrity: sha512-l3RQcPty2UBCoRh3yb9c5XCAmxkrc4BptAnbd5acO1gmSJtChOWkiEjnOvh7hvmtT4V80S8gXCOKAq8RNeIzSw==}
|
||||
peerDependencies:
|
||||
prettier: ^3.0.0
|
||||
svelte: ^3.2.0 || ^4.0.0-next.0
|
||||
dependencies:
|
||||
prettier: 3.0.0
|
||||
svelte: 4.2.3
|
||||
dev: true
|
||||
|
||||
/prettier@2.8.8:
|
||||
resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
|
||||
@ -14645,34 +14670,6 @@ packages:
|
||||
- sass
|
||||
- stylus
|
||||
- sugarss
|
||||
dev: false
|
||||
|
||||
/svelte-check@3.4.4(@babel/core@7.23.3)(less@4.2.0)(postcss@8.4.27)(svelte@4.2.3):
|
||||
resolution: {integrity: sha512-Uys9+R65cj8TmP8f5UpS7B2xKpNLYNxEWJsA5ZoKcWq/uwvABFF7xS6iPQGLoa7hxz0DS6xU60YFpmq06E4JxA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.20
|
||||
chokidar: 3.5.3
|
||||
fast-glob: 3.3.2
|
||||
import-fresh: 3.3.0
|
||||
picocolors: 1.0.0
|
||||
sade: 1.8.1
|
||||
svelte: 4.2.3
|
||||
svelte-preprocess: 5.0.4(@babel/core@7.23.3)(less@4.2.0)(postcss@8.4.27)(svelte@4.2.3)(typescript@5.2.2)
|
||||
typescript: 5.2.2
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- coffeescript
|
||||
- less
|
||||
- postcss
|
||||
- postcss-load-config
|
||||
- pug
|
||||
- sass
|
||||
- stylus
|
||||
- sugarss
|
||||
dev: true
|
||||
|
||||
/svelte-eslint-parser@0.32.2(svelte@4.2.2):
|
||||
resolution: {integrity: sha512-Ok9D3A4b23iLQsONrjqtXtYDu5ZZ/826Blaw2LeFZVTg1pwofKDG4mz3/GYTax8fQ0plRGHI6j+d9VQYy5Lo/A==}
|
||||
@ -14837,57 +14834,6 @@ packages:
|
||||
strip-indent: 3.0.0
|
||||
svelte: 4.2.2
|
||||
typescript: 5.2.2
|
||||
dev: false
|
||||
|
||||
/svelte-preprocess@5.0.4(@babel/core@7.23.3)(less@4.2.0)(postcss@8.4.27)(svelte@4.2.3)(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==}
|
||||
engines: {node: '>= 14.10.0'}
|
||||
requiresBuild: true
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.10.2
|
||||
coffeescript: ^2.5.1
|
||||
less: ^3.11.3 || ^4.0.0
|
||||
postcss: ^7 || ^8
|
||||
postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0
|
||||
pug: ^3.0.0
|
||||
sass: ^1.26.8
|
||||
stylus: ^0.55.0
|
||||
sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0
|
||||
svelte: ^3.23.0 || ^4.0.0-next.0 || ^4.0.0
|
||||
typescript: '>=3.9.5 || ^4.0.0 || ^5.0.0'
|
||||
peerDependenciesMeta:
|
||||
'@babel/core':
|
||||
optional: true
|
||||
coffeescript:
|
||||
optional: true
|
||||
less:
|
||||
optional: true
|
||||
postcss:
|
||||
optional: true
|
||||
postcss-load-config:
|
||||
optional: true
|
||||
pug:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
sugarss:
|
||||
optional: true
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/core': 7.23.3
|
||||
'@types/pug': 2.0.9
|
||||
detect-indent: 6.1.0
|
||||
less: 4.2.0
|
||||
magic-string: 0.27.0
|
||||
postcss: 8.4.27
|
||||
sorcery: 0.11.0
|
||||
strip-indent: 3.0.0
|
||||
svelte: 4.2.3
|
||||
typescript: 5.2.2
|
||||
dev: true
|
||||
|
||||
/svelte-range-slider-pips@2.0.1:
|
||||
resolution: {integrity: sha512-sCHvcTgi0ZYE4c/mwSsdALRsfuqEmpwTsSUdL+PUrumZ8u2gv1GKwZ3GohcAcTB6gfmqRBkyn6ujRXrOIga1gw==}
|
||||
|
@ -430,8 +430,7 @@ class TestCheckboxGroup:
|
||||
cbox = gr.CheckboxGroup(choices=["a", "b"], value="c")
|
||||
assert cbox.get_config()["value"] == ["c"]
|
||||
assert cbox.postprocess("a") == ["a"]
|
||||
with pytest.raises(ValueError):
|
||||
gr.CheckboxGroup().as_example("a")
|
||||
assert cbox.process_example("a") == ["a"]
|
||||
|
||||
def test_in_interface(self):
|
||||
"""
|
||||
@ -638,15 +637,12 @@ class TestImageEditor:
|
||||
"name": "imageeditor",
|
||||
}
|
||||
|
||||
def test_as_example(self):
|
||||
def test_process_example(self):
|
||||
test_image_path = "test/test_files/bus.png"
|
||||
image_editor = gr.ImageEditor()
|
||||
example_value = image_editor.as_example(test_image_path)
|
||||
assert isinstance(example_value, dict)
|
||||
assert example_value["background"]
|
||||
assert utils.is_in_or_equal(
|
||||
example_value["background"], image_editor.GRADIO_CACHE
|
||||
)
|
||||
example_value = image_editor.process_example(test_image_path)
|
||||
assert isinstance(example_value, EditorData)
|
||||
assert example_value.background and example_value.background.path
|
||||
|
||||
|
||||
class TestImage:
|
||||
@ -1081,11 +1077,12 @@ class TestDataframe:
|
||||
"headers": ["Name", "Age", "Member"],
|
||||
"metadata": None,
|
||||
}
|
||||
x_payload = DataframeData(**x_data)
|
||||
dataframe_input = gr.Dataframe(headers=["Name", "Age", "Member"])
|
||||
output = dataframe_input.preprocess(DataframeData(**x_data))
|
||||
output = dataframe_input.preprocess(x_payload)
|
||||
assert output["Age"][1] == 24
|
||||
assert not output["Member"][0]
|
||||
assert dataframe_input.postprocess(x_data) == x_data
|
||||
assert dataframe_input.postprocess(output) == x_payload
|
||||
|
||||
dataframe_input = gr.Dataframe(
|
||||
headers=["Name", "Age", "Member"], label="Dataframe Input"
|
||||
@ -1396,7 +1393,7 @@ class TestDataset:
|
||||
row = dataset.preprocess(1)
|
||||
assert row[0] == 15
|
||||
assert row[1] == "hi"
|
||||
assert row[2].endswith("bus.png")
|
||||
assert row[2]["path"].endswith("bus.png")
|
||||
assert row[3] == "<i>Italics</i>"
|
||||
assert row[4] == "*Italics*"
|
||||
|
||||
@ -1413,7 +1410,7 @@ class TestDataset:
|
||||
|
||||
radio = gr.Radio(choices=[("name 1", "value 1"), ("name 2", "value 2")])
|
||||
dataset = gr.Dataset(samples=[["value 1"], ["value 2"]], components=[radio])
|
||||
assert dataset.samples == [["name 1"], ["name 2"]]
|
||||
assert dataset.samples == [["value 1"], ["value 2"]]
|
||||
|
||||
def test_postprocessing(self):
|
||||
test_file_dir = Path(Path(__file__).parent, "test_files")
|
||||
@ -2336,32 +2333,40 @@ class TestState:
|
||||
assert result["prediction"] == 2
|
||||
|
||||
|
||||
def test_dataframe_as_example_converts_dataframes():
|
||||
def test_dataframe_process_example_converts_dataframes():
|
||||
df_comp = gr.Dataframe()
|
||||
assert df_comp.as_example(pd.DataFrame({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]})) == [
|
||||
assert df_comp.process_example(
|
||||
pd.DataFrame({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]})
|
||||
) == [
|
||||
[1, 5],
|
||||
[2, 6],
|
||||
[3, 7],
|
||||
[4, 8],
|
||||
]
|
||||
assert df_comp.as_example(np.array([[1, 2], [3, 4.0]])) == [[1.0, 2.0], [3.0, 4.0]]
|
||||
assert df_comp.process_example(np.array([[1, 2], [3, 4.0]])) == [
|
||||
[1.0, 2.0],
|
||||
[3.0, 4.0],
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("component", [gr.Model3D, gr.File, gr.Audio])
|
||||
def test_as_example_returns_file_basename(component):
|
||||
def test_process_example_returns_file_basename(component):
|
||||
component = component()
|
||||
assert component.as_example("/home/freddy/sources/example.ext") == "example.ext"
|
||||
assert component.as_example(None) == ""
|
||||
assert (
|
||||
component.process_example("/home/freddy/sources/example.ext") == "example.ext"
|
||||
)
|
||||
assert component.process_example(None) == ""
|
||||
|
||||
|
||||
@patch(
|
||||
"gradio.components.Component.as_example", spec=gr.components.Component.as_example
|
||||
"gradio.components.Component.process_example",
|
||||
spec=gr.components.Component.process_example,
|
||||
)
|
||||
@patch("gradio.components.Image.as_example", spec=gr.Image.as_example)
|
||||
@patch("gradio.components.File.as_example", spec=gr.File.as_example)
|
||||
@patch("gradio.components.Dataframe.as_example", spec=gr.DataFrame.as_example)
|
||||
@patch("gradio.components.Model3D.as_example", spec=gr.Model3D.as_example)
|
||||
def test_dataset_calls_as_example(*mocks):
|
||||
@patch("gradio.components.Image.process_example", spec=gr.Image.process_example)
|
||||
@patch("gradio.components.File.process_example", spec=gr.File.process_example)
|
||||
@patch("gradio.components.Dataframe.process_example", spec=gr.DataFrame.process_example)
|
||||
@patch("gradio.components.Model3D.process_example", spec=gr.Model3D.process_example)
|
||||
def test_dataset_calls_process_example(*mocks):
|
||||
gr.Dataset(
|
||||
components=[gr.Dataframe(), gr.File(), gr.Image(), gr.Model3D(), gr.Textbox()],
|
||||
samples=[
|
||||
|
@ -73,7 +73,7 @@ class TestExamples:
|
||||
[media_data.BASE64_IMAGE, "hi"],
|
||||
]
|
||||
for sample in examples.dataset.samples:
|
||||
assert os.path.isabs(sample[0])
|
||||
assert os.path.isabs(sample[0]["path"])
|
||||
|
||||
def test_examples_per_page(self, patched_cache_folder):
|
||||
examples = gr.Examples(["hello", "hi"], gr.Textbox(), examples_per_page=2)
|
||||
|
Loading…
Reference in New Issue
Block a user