Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share button #4651

Merged
merged 59 commits into from Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
1b9e861
changes
aliabid94 Jun 22, 2023
d1b8935
changes
aliabid94 Jun 22, 2023
fcb3cbb
changes
aliabid94 Jun 22, 2023
155954b
changes
aliabid94 Jun 23, 2023
3d78265
changes
aliabid94 Jun 23, 2023
76967ee
changes
aliabid94 Jun 23, 2023
2acde88
changes
aliabid94 Jun 23, 2023
d3d7739
Merge remote-tracking branch 'origin' into share_button
aliabid94 Jun 27, 2023
7f74cff
changes
aliabid94 Jun 27, 2023
e155ab8
changes
aliabid94 Jun 27, 2023
54e0871
changes
aliabid94 Jun 27, 2023
8d8225f
changes
aliabid94 Jun 27, 2023
c1044fc
changes
aliabid94 Jun 27, 2023
0c3140b
changes
aliabid94 Jun 27, 2023
da6ee43
changes
aliabid94 Jun 27, 2023
bc81f0a
merge
abidlabs Jun 27, 2023
e17ce12
restore
abidlabs Jun 27, 2023
2ee6989
merge
abidlabs Jun 27, 2023
1b426f2
del image'
abidlabs Jun 27, 2023
c0bb33e
update pnpm lock
abidlabs Jun 27, 2023
bf6ad52
merge
aliabid94 Jun 28, 2023
54819ce
changes
aliabid94 Jun 28, 2023
00aab7b
Merge remote-tracking branch 'origin' into share_button
aliabid94 Jun 28, 2023
ce15e07
changes
aliabid94 Jun 28, 2023
af7257c
changes
aliabid94 Jun 28, 2023
8dec9f8
changes
aliabid94 Jun 28, 2023
4e27109
changes
aliabid94 Jun 28, 2023
165d1c7
Merge branch 'main' into share_button
aliabid94 Jun 28, 2023
e2867e7
changes
aliabid94 Jun 29, 2023
d771fee
Merge branch 'main' into share_button
aliabid94 Jun 29, 2023
54fc2e8
Update CHANGELOG.md
aliabid94 Jun 29, 2023
34ad7fe
Merge branch 'main' into share_button
pngwn Jun 30, 2023
4f14b71
Merge branch 'main' into share_button
abidlabs Jun 30, 2023
a74fb5d
changes
aliabid94 Jul 3, 2023
36752b5
changes
aliabid94 Jul 4, 2023
dce9994
fix
aliabid94 Jul 4, 2023
35bdd08
changes
aliabid94 Jul 4, 2023
f9d85ff
Merge branch 'main' into error_handling
aliabid94 Jul 4, 2023
4912c5a
changes
aliabid94 Jul 4, 2023
585f187
changes
aliabid94 Jul 4, 2023
b6b5e75
changes
aliabid94 Jul 4, 2023
8e2ce65
changes
aliabid94 Jul 4, 2023
05ea054
changes
aliabid94 Jul 4, 2023
f5eff47
changes
aliabid94 Jul 4, 2023
c2da8ff
Merge branch 'main' into share_button
aliabid94 Jul 4, 2023
ea24b55
changes
aliabid94 Jul 4, 2023
6d29bf1
changes
aliabid94 Jul 4, 2023
edbfda2
Merge branch 'main' into share_button
aliabid94 Jul 4, 2023
fa60223
changes
aliabid94 Jul 5, 2023
c7402de
Merge branch 'share_button' of https://github.com/gradio-app/gradio i…
aliabid94 Jul 5, 2023
07b6c43
Merge remote-tracking branch 'origin' into share_button
aliabid94 Jul 5, 2023
43e3f44
changes
aliabid94 Jul 5, 2023
e68d082
chagnes
aliabid94 Jul 5, 2023
5e69d3a
changes
aliabid94 Jul 5, 2023
4f332f8
changes
aliabid94 Jul 5, 2023
0f6b920
Merge branch 'main' into share_button
aliabid94 Jul 5, 2023
1d3b94e
changes
aliabid94 Jul 5, 2023
a7bdab2
changes
aliabid94 Jul 5, 2023
ed64773
changes
aliabid94 Jul 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,7 @@
- Spaces Duplication built into Gradio, by [@aliabid94](https://github.com/aliabid94) in [PR 4458](https://github.com/gradio-app/gradio/pull/4458)
- The `api_name` parameter now accepts `False` as a value, which means it does not show up in named or unnamed endpoints. By [@abidlabs](https://github.com/aliabid94) in [PR 4683](https://github.com/gradio-app/gradio/pull/4683)
- Added support for `pathlib.Path` in `gr.Video`, `gr.Gallery`, and `gr.Chatbot` by [sunilkumardash9](https://github.com/sunilkumardash9) in [PR 4581](https://github.com/gradio-app/gradio/pull/4581).
- The `gr.Video`, `gr.Audio`, `gr.Image`, `gr.Chatbot`, and `gr.Gallery` components now include a share icon when deployed on Spaces. This behavior can be modified by setting the `shareable` parameter in the component classes. by [@aliabid94](https://github.com/aliabid94) in [PR 4651](https://github.com/gradio-app/gradio/pull/4651)

## Bug Fixes:

Expand Down
6 changes: 6 additions & 0 deletions gradio/components/audio.py
Expand Up @@ -67,6 +67,7 @@ def __init__(
elem_classes: list[str] | str | None = None,
format: Literal["wav", "mp3"] = "wav",
autoplay: bool = False,
shareable: bool | None = None,
**kwargs,
):
"""
Expand All @@ -86,6 +87,7 @@ def __init__(
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.
format: The file format to save audio files. Either 'wav' or 'mp3'. wav files are lossless but will tend to be larger files. mp3 files tend to be smaller. Default is wav. Applies both when this component is used as an input (when `type` is "format") and when this component is used as an output.
shareable: If True, will allow user to share generation on Hugging Face Spaces Discussions.
aliabid94 marked this conversation as resolved.
Show resolved Hide resolved
"""
valid_sources = ["upload", "microphone"]
if source not in valid_sources:
Expand All @@ -106,6 +108,9 @@ def __init__(
)
self.format = format
self.autoplay = autoplay
self.shareable = (
(utils.get_space() is not None) if shareable is None else shareable
)
IOComponent.__init__(
self,
label=label,
Expand All @@ -129,6 +134,7 @@ def get_config(self):
"value": self.value,
"streaming": self.streaming,
"autoplay": self.autoplay,
"shareable": self.shareable,
**IOComponent.get_config(self),
}

Expand Down
6 changes: 6 additions & 0 deletions gradio/components/chatbot.py
Expand Up @@ -51,6 +51,7 @@ def __init__(
elem_classes: list[str] | str | None = None,
height: int | None = None,
latex_delimiters: list[dict[str, str | bool]] | None = None,
shareable: bool | None = None,
**kwargs,
):
"""
Expand All @@ -67,6 +68,7 @@ def __init__(
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.
height: height of the component in pixels.
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": True }]`, so only expressions enclosed in $$ delimiters will be rendered as LaTeX, and in a new line. Pass in an empty list to disable LaTeX rendering. For more information, see the [KaTeX documentation](https://katex.org/docs/autorender.html).
shareable: If True, will allow user to share generation on Hugging Face Spaces Discussions.
"""
if color_map is not None:
warn_deprecation("The 'color_map' parameter has been deprecated.")
Expand All @@ -80,6 +82,9 @@ def __init__(
if latex_delimiters is None:
latex_delimiters = [{"left": "$$", "right": "$$", "display": True}]
self.latex_delimiters = latex_delimiters
self.shareable = (
(utils.get_space() is not None) if shareable is None else shareable
)

IOComponent.__init__(
self,
Expand All @@ -102,6 +107,7 @@ def get_config(self):
"latex_delimiters": self.latex_delimiters,
"selectable": self.selectable,
"height": self.height,
"shareable": self.shareable,
**IOComponent.get_config(self),
}

Expand Down
6 changes: 6 additions & 0 deletions gradio/components/gallery.py
Expand Up @@ -53,6 +53,7 @@ def __init__(
object_fit: Literal["contain", "cover", "fill", "none", "scale-down"]
| None = None,
allow_preview: bool = True,
shareable: bool | None = None,
**kwargs,
):
"""
Expand All @@ -73,6 +74,7 @@ def __init__(
preview: If True, will display the Gallery in preview mode, which shows all of the images as thumbnails and allows the user to click on them to view them in full size.
object_fit: CSS object-fit property for the thumbnail images in the gallery. Can be "contain", "cover", "fill", "none", or "scale-down".
allow_preview: If True, images in the gallery will be enlarged when they are clicked. Default is True.
shareable: If True, will allow user to share generation on Hugging Face Spaces Discussions.
"""
self.grid_cols = columns
self.grid_rows = rows
Expand All @@ -86,6 +88,9 @@ def __init__(
Uses event data gradio.SelectData to carry `value` referring to caption of selected image, and `index` to refer to index.
See EventData documentation on how to use this event data.
"""
self.shareable = (
(utils.get_space() is not None) if shareable is None else shareable
)
IOComponent.__init__(
self,
label=label,
Expand Down Expand Up @@ -145,6 +150,7 @@ def get_config(self):
"preview": self.preview,
"object_fit": self.object_fit,
"allow_preview": self.allow_preview,
"shareable": self.shareable,
**IOComponent.get_config(self),
}

Expand Down
7 changes: 6 additions & 1 deletion gradio/components/image.py
Expand Up @@ -80,6 +80,7 @@ def __init__(
elem_classes: list[str] | str | None = None,
mirror_webcam: bool = True,
brush_radius: float | None = None,
shareable: bool | None = None,
**kwargs,
):
"""
Expand All @@ -106,6 +107,7 @@ def __init__(
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.
mirror_webcam: If True webcam will be mirrored. Default is True.
brush_radius: Size of the brush for Sketch. Default is None which chooses a sensible default
shareable: If True, will allow user to share generation on Hugging Face Spaces Discussions.
"""
self.brush_radius = brush_radius
self.mirror_webcam = mirror_webcam
Expand Down Expand Up @@ -139,7 +141,9 @@ def __init__(
Uses event data gradio.SelectData to carry `index` to refer to the [x, y] coordinates of the clicked pixel.
See EventData documentation on how to use this event data.
"""

self.shareable = (
(utils.get_space() is not None) if shareable is None else shareable
)
IOComponent.__init__(
self,
label=label,
Expand Down Expand Up @@ -170,6 +174,7 @@ def get_config(self):
"mirror_webcam": self.mirror_webcam,
"brush_radius": self.brush_radius,
"selectable": self.selectable,
"shareable": self.shareable,
**IOComponent.get_config(self),
}

Expand Down
6 changes: 6 additions & 0 deletions gradio/components/video.py
Expand Up @@ -71,6 +71,7 @@ def __init__(
mirror_webcam: bool = True,
include_audio: bool | None = None,
autoplay: bool = False,
shareable: bool | None = None,
**kwargs,
):
"""
Expand All @@ -92,6 +93,7 @@ def __init__(
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.
mirror_webcam: If True webcam will be mirrored. Default is True.
include_audio: Whether the component should record/retain the audio track for a video. By default, audio is excluded for webcam videos and included for uploaded videos.
shareable: If True, will allow user to share generation on Hugging Face Spaces Discussions.
"""
self.format = format
self.autoplay = autoplay
Expand All @@ -107,6 +109,9 @@ def __init__(
self.include_audio = (
include_audio if include_audio is not None else source == "upload"
)
self.shareable = (
(utils.get_space() is not None) if shareable is None else shareable
)
IOComponent.__init__(
self,
label=label,
Expand All @@ -132,6 +137,7 @@ def get_config(self):
"mirror_webcam": self.mirror_webcam,
"include_audio": self.include_audio,
"autoplay": self.autoplay,
"shareable": self.shareable,
**IOComponent.get_config(self),
}

Expand Down
6 changes: 6 additions & 0 deletions gradio/test_data/blocks_configs.py
Expand Up @@ -62,6 +62,7 @@
"container": True,
"min_width": 160,
"name": "image",
"shareable": False,
"visible": True,
},
"serializer": "ImgSerializable",
Expand Down Expand Up @@ -133,6 +134,7 @@
"container": True,
"min_width": 160,
"name": "image",
"shareable": False,
"visible": True,
},
"serializer": "ImgSerializable",
Expand Down Expand Up @@ -376,6 +378,7 @@
"container": True,
"min_width": 160,
"name": "image",
"shareable": False,
"visible": True,
},
"serializer": "ImgSerializable",
Expand Down Expand Up @@ -447,6 +450,7 @@
"container": True,
"min_width": 160,
"name": "image",
"shareable": False,
"visible": True,
},
"serializer": "ImgSerializable",
Expand Down Expand Up @@ -689,6 +693,7 @@
"mirror_webcam": True,
"tool": "editor",
"name": "image",
"shareable": False,
"selectable": False,
},
},
Expand Down Expand Up @@ -739,6 +744,7 @@
"streaming": False,
"mirror_webcam": True,
"name": "image",
"shareable": False,
"selectable": False,
},
},
Expand Down
5 changes: 5 additions & 0 deletions guides/01_getting-started/03_sharing-your-app.md
Expand Up @@ -33,14 +33,19 @@ Share links expire after 72 hours.
If you'd like to have a permanent link to your Gradio demo on the internet, use Hugging Face Spaces. [Hugging Face Spaces](http://huggingface.co/spaces/) provides the infrastructure to permanently host your machine learning model for free!

After you have [created a free Hugging Face account](https://huggingface.co/join), you have three methods to deploy your Gradio app to Hugging Face Spaces:

1. From terminal: run `gradio deploy` in your app directory. The CLI will gather some basic metadata and then launch your app. To update your space, you can re-run this command or enable the Github Actions option to automatically update the Spaces on `git push`.

2. From your browser: Drag and drop a folder containing your Gradio model and all related files [here](https://huggingface.co/new-space).

3. Connect Spaces with your Git repository and Spaces will pull the Gradio app from there. See [this guide how to host on Hugging Face Spaces](https://huggingface.co/blog/gradio-spaces) for more information.

<video autoplay muted loop>
<source src="/assets/guides/hf_demo.mp4" type="video/mp4" />
</video>

Note: Some components, like `gr.Image`, will display a "Share" button only on Spaces, so that users can share generated output easily. You can disable this via `gr.Image(shareable=False)`
aliabid94 marked this conversation as resolved.
Show resolved Hide resolved
aliabid94 marked this conversation as resolved.
Show resolved Hide resolved

## Embedding Hosted Spaces

Once you have hosted your app on Hugging Face Spaces (or on your own server), you may want to embed the demo on a different website, such as your blog or your portfolio. Embedding an interactive demo allows people to try out the machine learning model that you have built, without needing to download or install anything — right in their browser! The best part is that you can embed interactive demos even in static websites, such as GitHub pages.
Expand Down
32 changes: 32 additions & 0 deletions js/app/src/Blocks.svelte
Expand Up @@ -24,6 +24,7 @@
import type { ThemeMode } from "./components/types";
import Toast from "./components/StatusTracker/Toast.svelte";
import type { ToastMessage } from "./components/StatusTracker/types";
import type { ShareData } from "@gradio/utils";

import logo from "./images/logo.svg";
import api_logo from "./api_docs/img/api-logo.svg";
Expand Down Expand Up @@ -369,6 +370,20 @@
}
};

const trigger_share = (title: string, description: string) => {
if (space_id === null) {
return;
}
const discussion_url = new URL(
`https://huggingface.co/spaces/${space_id}/discussions/new`
);
if (title.length > 0) {
discussion_url.searchParams.set("title", title);
}
discussion_url.searchParams.set("description", description);
window.open(discussion_url.toString(), "_blank");
};

function handle_error_close(e: Event & { detail: number }) {
const _id = e.detail;
messages = messages.filter((m) => m.id !== _id);
Expand All @@ -391,6 +406,7 @@
a[i].setAttribute("target", "_blank");
}

let shareable_components: Array<number> = [];
aliabid94 marked this conversation as resolved.
Show resolved Hide resolved
dependencies.forEach((dep, i) => {
let { targets, trigger, inputs, outputs } = dep;
const target_instances: [number, ComponentMeta][] = targets.map((t) => [
Expand All @@ -411,6 +427,7 @@
handled_dependencies[i] = [-1];
}

// component events
target_instances
.filter((v) => !!v && !!v[1])
.forEach(([id, { instance }]: [number, ComponentMeta]) => {
Expand All @@ -422,6 +439,21 @@
if (!handled_dependencies[i]) handled_dependencies[i] = [];
handled_dependencies[i].push(id);
});

// share events
outputs.forEach((output_id: number) => {
const output_component = instance_map[output_id];
if (
output_component.props.shareable &&
!shareable_components.includes(output_id) // only one share listener per component
) {
shareable_components.push(output_id);
output_component.instance.$on("share", (event_data) => {
const { title, description } = event_data.detail as ShareData;
trigger_share(title, description);
});
}
});
});
}

Expand Down
3 changes: 3 additions & 0 deletions js/app/src/components/Audio/Audio.svelte
Expand Up @@ -36,6 +36,7 @@
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
export let autoplay = false;
export let shareable: boolean = false;

let _value: null | FileData;
$: _value = normalise_file(value, root, root_url);
Expand Down Expand Up @@ -97,9 +98,11 @@
<StaticAudio
{autoplay}
{show_label}
{shareable}
value={_value}
name={_value?.name || "audio_file"}
{label}
on:share
/>
{/if}
</Block>
3 changes: 3 additions & 0 deletions js/app/src/components/Chatbot/Chatbot.svelte
Expand Up @@ -29,6 +29,7 @@
export let root_url: null | string;
export let selectable: boolean = false;
export let theme_mode: ThemeMode;
export let shareable: boolean = false;

const redirect_src_url = (src: string) =>
src.replace('src="/file', `src="${root}file`);
Expand Down Expand Up @@ -78,12 +79,14 @@
{/if}
<ChatBot
{selectable}
{shareable}
{theme_mode}
value={_value}
{latex_delimiters}
pending_message={loading_status?.status === "pending"}
on:change
on:select
on:share
/>
</div>
</Block>
Expand Down
3 changes: 3 additions & 0 deletions js/app/src/components/Gallery/Gallery.svelte
Expand Up @@ -24,6 +24,7 @@
export let allow_preview: boolean = true;
export let object_fit: "contain" | "cover" | "fill" | "none" | "scale-down" =
"cover";
export let shareable: boolean = false;
</script>

<Block
Expand All @@ -40,6 +41,7 @@
<StatusTracker {...loading_status} />
<Gallery
on:select
on:share
{label}
{value}
{show_label}
Expand All @@ -51,5 +53,6 @@
{preview}
{object_fit}
{allow_preview}
{shareable}
/>
</Block>