Load Event Trigger (#2456)

* load event

* fixes

* reformat

* changelog fixes

* rename to uploadable

* formatting

* format

* add cancels

* Update CHANGELOG.md

* Create CHANGELOG.md

* Update CHANGELOG.md

* add batch
This commit is contained in:
Dawood Khan 2022-10-25 20:58:12 -04:00 committed by GitHub
parent 5a090de94a
commit 83a038ea7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 110 additions and 9 deletions

View File

@ -48,6 +48,11 @@ In the example above, 16 requests could be processed in parallel (for a total in
time of 5 seconds), instead of each request being processed separately (for a total
inference time of 80 seconds).
### Load Event
`Video`, `Audio`, `Image`, and `File` components now support a `upload` event that is triggered when a user uploads a file into any of these components.
## Bug Fixes:
* Fixes issue where plotly animations, interactivity, titles, legends, were not working properly. [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2486](https://github.com/gradio-app/gradio/pull/2486)
* Prevent requests to the `/api` endpoint from skipping the queue if the queue is enabled for that event by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2493](https://github.com/gradio-app/gradio/pull/2493)
@ -69,6 +74,7 @@ No changes to highlight.
* Allows the render() function to return self by [@Raul9595](https://github.com/Raul9595) in [PR 2514](https://github.com/gradio-app/gradio/pull/2514)
* Fixes issue where plotly animations, interactivity, titles, legends, were not working properly. [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2486](https://github.com/gradio-app/gradio/pull/2486)
* Gradio now supports batched functions by [@abidlabs](https://github.com/abidlabs) in [PR 2218](https://github.com/gradio-app/gradio/pull/2218)
* Add `upload` event for `Video`, `Audio`, `Image`, and `File` components [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2448](https://github.com/gradio-app/gradio/pull/2456)
## Contributors Shoutout:
No changes to highlight.
@ -206,7 +212,9 @@ No changes to highlight.
* Automatically restart spaces if they're down by [@aliabd](https://github.com/aliabd) in [PR 2405](https://github.com/gradio-app/gradio/pull/2405)
* Carousel component is now deprecated by [@abidlabs](https://github.com/abidlabs) in [PR 2434](https://github.com/gradio-app/gradio/pull/2434)
* Build Gradio from source in ui tests by by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2440](https://github.com/gradio-app/gradio/pull/2440)
* Change "return ValueError" to "raise ValueError" by [@vzakharov](https://github.com/vzakharov) in [PR 2445](https://github.com/gradio-app/gradio/pull/2445)
* Change "return ValueError" to "raise ValueError" by [@vzakharov](https://github.com/vzakharov) in [PR 2445](https://github.com/gradio-app/gradio/pull/2445)
* Add guide on creating a map demo using the `gr.Plot()` component [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2402](https://github.com/gradio-app/gradio/pull/2402)
* Add blur event for `Textbox` and `Number` components [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2448](https://github.com/gradio-app/gradio/pull/2448)
* Stops a gradio launch from hogging a port even after it's been killed [@aliabid94](https://github.com/aliabid94) in [PR 2453](https://github.com/gradio-app/gradio/pull/2453)
* Fix embedded interfaces on touch screen devices by [@aliabd](https://github.com/aliabd) in [PR 2457](https://github.com/gradio-app/gradio/pull/2457)
* Upload all demos to spaces by [@aliabd](https://github.com/aliabd) in [PR 2281](https://github.com/gradio-app/gradio/pull/2281)
@ -233,6 +241,8 @@ You can now see gradio's release history directly on the website, and also keep
4. Fix image_classifier_interface_load demo by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2365](https://github.com/gradio-app/gradio/pull/2365)
5. Fix combining adjacent components without gaps by introducing `gr.Row(variant="compact")` by [@aliabid94](https://github.com/aliabid94) in [PR 2291](https://github.com/gradio-app/gradio/pull/2291) This comes with deprecation of the following arguments for `Component.style`: `round`, `margin`, `border`.
6. Fix audio streaming, which was previously choppy in [PR 2351](https://github.com/gradio-app/gradio/pull/2351). Big thanks to [@yannickfunk](https://github.com/yannickfunk) for the proposed solution.
7. Fix bug where new typeable slider doesn't respect the minimum and maximum values [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2380](https://github.com/gradio-app/gradio/pull/2380)
## Documentation Changes:
@ -272,8 +282,7 @@ No changes to highlight.
* Lets users provide a `gr.update()` dictionary even if post-processing is diabled [@abidlabs](https://github.com/abidlabs) in [PR 2385](https://github.com/gradio-app/gradio/pull/2385)
* Fix bug where errors would cause apps run in reload mode to hang forever by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2394](https://github.com/gradio-app/gradio/pull/2394)
* Fix bug where new typeable slider doesn't respect the minimum and maximum values [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2380](https://github.com/gradio-app/gradio/pull/2380)
* Add guide on creating a map demo using the `gr.Plot()` component [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2402](https://github.com/gradio-app/gradio/pull/2402)
* Add blur event for `Textbox` and `Number` components [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2448](https://github.com/gradio-app/gradio/pull/2448)
## Contributors Shoutout:
No changes to highlight.

View File

@ -48,6 +48,7 @@ from gradio.events import (
Playable,
Streamable,
Submittable,
Uploadable,
)
from gradio.layouts import Column, Form, Row
from gradio.serializing import (
@ -1196,7 +1197,15 @@ class Dropdown(Radio):
@document("edit", "clear", "change", "stream", "change", "style")
class Image(Editable, Clearable, Changeable, Streamable, IOComponent, ImgSerializable):
class Image(
Editable,
Clearable,
Changeable,
Streamable,
Uploadable,
IOComponent,
ImgSerializable,
):
"""
Creates an image component that can be used to upload/draw images (as an input) or display images (as an output).
Preprocessing: passes the uploaded image as a {numpy.array}, {PIL.Image} or {str} filepath depending on `type` -- unless `tool` is `sketch` AND source is one of `upload` or `webcam`. In these cases, a {dict} with keys `image` and `mask` is passed, and the format of the corresponding values depends on `type`.
@ -1536,7 +1545,7 @@ class Image(Editable, Clearable, Changeable, Streamable, IOComponent, ImgSeriali
@document("change", "clear", "play", "pause", "stop", "style")
class Video(Changeable, Clearable, Playable, IOComponent, FileSerializable):
class Video(Changeable, Clearable, Playable, Uploadable, IOComponent, FileSerializable):
"""
Creates a video component that can be used to upload/record videos (as an input) or display videos (as an output).
For the video to be playable in the browser it must have a compatible container and codec combination. Allowed
@ -1717,7 +1726,15 @@ class Video(Changeable, Clearable, Playable, IOComponent, FileSerializable):
@document("change", "clear", "play", "pause", "stop", "stream", "style")
class Audio(Changeable, Clearable, Playable, Streamable, IOComponent, FileSerializable):
class Audio(
Changeable,
Clearable,
Playable,
Streamable,
Uploadable,
IOComponent,
FileSerializable,
):
"""
Creates an audio component that can be used to upload/record audio (as an input) or display audio (as an output).
Preprocessing: passes the uploaded audio as a {Tuple(int, numpy.array)} corresponding to (sample rate, data) or as a {str} filepath, depending on `type`
@ -2010,7 +2027,7 @@ class Audio(Changeable, Clearable, Playable, Streamable, IOComponent, FileSerial
@document("change", "clear", "style")
class File(Changeable, Clearable, IOComponent, FileSerializable):
class File(Changeable, Clearable, Uploadable, IOComponent, FileSerializable):
"""
Creates a file component that allows uploading generic file (when used as an input) and or displaying generic files (output).
Preprocessing: passes the uploaded file as a {file-object} or {List[file-object]} depending on `file_count` (or a {bytes}/{List{bytes}} depending on `type`)

View File

@ -613,10 +613,11 @@ class Blurrable(Block):
inputs: Component | List[Component] | None,
outputs: List[Component],
api_name: AnyStr = None,
status_tracker: Optional[StatusTracker] = None,
scroll_to_output: bool = False,
show_progress: bool = True,
queue: Optional[bool] = None,
batch: bool = False,
max_batch_size: int = 4,
preprocess: bool = True,
postprocess: bool = True,
cancels: Dict[str, Any] | List[Dict[str, Any]] | None = None,
@ -633,6 +634,8 @@ class Blurrable(Block):
scroll_to_output: If True, will scroll to output component on completion
show_progress: If True, will show progress animation while pending
queue: If True, will place the request on the queue, if the queue exists
batch: If True, then the function should process a batch of inputs, meaning that it should accept a list of input values for each parameter. The lists should be of equal length (and be up to length `max_batch_size`). The function is then *required* to return a tuple of lists (even if there is only 1 output component), with each list in the tuple corresponding to one output component.
max_batch_size: Maximum number of inputs to batch together if this is called from the queue (only relevant if batch=True)
preprocess: If False, will not run preprocessing of component data before running 'fn' (e.g. leaving it as a base64 string if this method is called with the `Image` component).
postprocess: If False, will not run postprocessing of component data before returning 'fn' output to the browser.
cancels: A list of other events to cancel when this event is triggered. For example, setting cancels=[click_event] will cancel the click_event, where click_event is the return value of another components .click method.
@ -651,5 +654,61 @@ class Blurrable(Block):
preprocess=preprocess,
postprocess=postprocess,
queue=queue,
batch=batch,
max_batch_size=max_batch_size,
)
set_cancel_events(self, "blur", cancels)
class Uploadable(Block):
def upload(
self,
fn: Callable,
inputs: List[Component],
outputs: List[Component],
api_name: AnyStr = None,
scroll_to_output: bool = False,
show_progress: bool = True,
queue: Optional[bool] = None,
batch: bool = False,
max_batch_size: int = 4,
preprocess: bool = True,
postprocess: bool = True,
cancels: List[Dict[str, Any]] | None = None,
_js: Optional[str] = None,
):
"""
This event is triggered when the user uploads a file into the component (e.g. when the user uploads a video into a video component). This method can be used when this component is in a Gradio Blocks.
Parameters:
fn: Callable function
inputs: List of inputs
outputs: List of outputs
api_name: Defining this parameter exposes the endpoint in the api docs
scroll_to_output: If True, will scroll to output component on completion
show_progress: If True, will show progress animation while pending
queue: If True, will place the request on the queue, if the queue exists
batch: If True, then the function should process a batch of inputs, meaning that it should accept a list of input values for each parameter. The lists should be of equal length (and be up to length `max_batch_size`). The function is then *required* to return a tuple of lists (even if there is only 1 output component), with each list in the tuple corresponding to one output component.
max_batch_size: Maximum number of inputs to batch together if this is called from the queue (only relevant if batch=True)
preprocess: If False, will not run preprocessing of component data before running 'fn' (e.g. leaving it as a base64 string if this method is called with the `Image` component).
postprocess: If False, will not run postprocessing of component data before returning 'fn' output to the browser.
cancels: A list of other events to cancel when this event is triggered. For example, setting cancels=[click_event] will cancel the click_event, where click_event is the return value of another components .click method.
"""
# _js: Optional frontend js method to run before running 'fn'. Input arguments for js method are values of 'inputs' and 'outputs', return should be a list of values for output components.
self.set_event_trigger(
"upload",
fn,
inputs,
outputs,
api_name=api_name,
scroll_to_output=scroll_to_output,
show_progress=show_progress,
js=_js,
preprocess=preprocess,
postprocess=postprocess,
queue=queue,
batch=batch,
max_batch_size=max_batch_size,
)
set_cancel_events(self, "upload", cancels)

View File

@ -72,6 +72,7 @@
on:play
on:pause
on:ended
on:upload
on:error={({ detail }) => {
loading_status = loading_status || {};
loading_status.status = "error";

View File

@ -45,6 +45,7 @@
on:drag={({ detail }) => (dragging = detail)}
on:change
on:clear
on:upload
drop_text={$_("interface.drop_file")}
or_text={$_("or")}
upload_text={$_("interface.click_to_upload")}

View File

@ -54,6 +54,7 @@
on:change
on:stream
on:drag={({ detail }) => (dragging = detail)}
on:upload
on:error={({ detail }) => {
loading_status = loading_status || {};
loading_status.status = "error";

View File

@ -63,6 +63,7 @@
on:clear
on:play
on:pause
on:upload
/>
{/if}
</Block>

View File

@ -69,6 +69,8 @@
ended: undefined;
drag: boolean;
error: string;
upload: FileData;
clear: undefined;
}>();
function blob_to_data_url(blob: Blob): Promise<string> {
@ -192,6 +194,7 @@
function clear() {
dispatch("change");
dispatch("clear");
mode = "";
value = null;
}
@ -241,6 +244,7 @@
}) {
value = detail;
dispatch("change", { data: detail.data, name: detail.name });
dispatch("upload", detail);
}
export let dragging = false;

View File

@ -24,6 +24,7 @@
value = detail;
await tick();
dispatch("change", value);
dispatch("upload", detail);
}
function handle_clear({ detail }: CustomEvent<null>) {
@ -36,6 +37,7 @@
change: FileData | null;
clear: undefined;
drag: boolean;
upload: FileData;
}>();
let dragging = false;

View File

@ -48,6 +48,7 @@
? { image: detail, mask: null }
: detail;
}
dispatch("upload", detail);
}
function handle_clear({ detail }: CustomEvent<null>) {
@ -89,6 +90,7 @@
edit: undefined;
clear: undefined;
drag: boolean;
upload: FileData;
}>();
$: dispatch("change", value as string);

View File

@ -27,10 +27,12 @@
ended: undefined;
drag: boolean;
error: string;
upload: FileData;
}>();
function handle_load({ detail }: CustomEvent<FileData | null>) {
dispatch("change", detail);
dispatch("upload", detail!);
value = detail;
}

View File

@ -1,7 +1,7 @@
import os
from gradio.documentation import generate_documentation, document_cls
import gradio.templates
from gradio.events import Changeable, Clearable, Submittable, Editable, Playable, Clickable, Blurrable
from gradio.events import Changeable, Clearable, Submittable, Editable, Playable, Clickable, Blurrable, Uploadable
from ..guides import guides
DIR = os.path.dirname(__file__)
@ -58,6 +58,8 @@ def add_supported_events():
component["events"].append("submit()")
if issubclass(component["class"], Blurrable):
component["events"].append("blur()")
if issubclass(component["class"], Uploadable):
component["events"].append("upload()")
if component["events"]:
component["events"] = ", ".join(component["events"])