This commit is contained in:
Ali Abid 2022-07-25 02:18:42 +01:00
parent 595357e37b
commit 3a93202fd6
54 changed files with 497 additions and 880 deletions

View File

@ -1,23 +1,19 @@
import gradio as gr
def change_textbox(choice):
if choice == "short":
return gr.update(lines=2, visible=True)
return gr.update(lines=2, visible=True, value="Short story: ")
elif choice == "long":
return gr.update(lines=8, visible=True)
return gr.update(lines=8, visible=True, value="Long story...")
else:
return gr.update(visible=False)
with gr.Blocks() as demo:
radio = gr.Radio(
["short", "long", "none"], label="What kind of essay would you like to write?"
["short", "long", "none"], label="Essay Length to Write?"
)
text = gr.Textbox(lines=2, interactive=True)
radio.change(fn=change_textbox, inputs=radio, outputs=text)
if __name__ == "__main__":
demo.launch()

View File

@ -1,17 +1,13 @@
import numpy as np
import gradio as gr
demo = gr.Blocks()
def flip_text(x):
return x[::-1]
def flip_image(x):
return np.fliplr(x)
with demo:
with gr.Blocks() as demo:
gr.Markdown("Flip text or image files using this demo.")
with gr.Tabs():
with gr.TabItem("Flip Text"):

View File

@ -27,6 +27,5 @@ with gr.Blocks() as demo:
[error_box, diagnosis_box, patient_summary_box],
)
if __name__ == "__main__":
demo.launch()

View File

@ -1,12 +1,9 @@
import gradio as gr
def update(name):
def welcome(name):
return f"Welcome to Gradio, {name}!"
demo = gr.Blocks()
with demo:
with gr.Blocks() as demo:
gr.Markdown(
"""
# Hello World!
@ -14,9 +11,7 @@ with demo:
""")
inp = gr.Textbox(placeholder="What is your name?")
out = gr.Textbox()
inp.change(welcome, inp, out)
inp.change(fn=update,
inputs=inp,
outputs=out)
demo.launch()
if __name__ == "__main__":
demo.launch()

View File

@ -10,10 +10,13 @@ def calculator(num1, operation, num2):
elif operation == "divide":
return num1 / num2
demo = gr.Interface(
calculator,
[gr.Number(value=4), gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
[
"number",
gr.Radio(["add", "subtract", "multiply", "divide"]),
"number"
],
"number",
examples=[
[5, "add", 3],
@ -21,9 +24,8 @@ demo = gr.Interface(
[-4, "multiply", 2.5],
[0, "subtract", 1.2],
],
title="test calculator",
description="heres a sample toy calculator. enjoy!",
title="Toy Calculator",
description="Here's a sample toy calculator. Enjoy!",
)
if __name__ == "__main__":
demo.launch()

View File

@ -1,6 +1,5 @@
import gradio as gr
def calculator(num1, operation, num2):
if operation == "add":
return num1 + num2
@ -11,13 +10,15 @@ def calculator(num1, operation, num2):
elif operation == "divide":
return num1 / num2
demo = gr.Interface(
calculator,
["number", gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
[
"number",
gr.Radio(["add", "subtract", "multiply", "divide"]),
"number"
],
"number",
live=True,
)
if __name__ == "__main__":
demo.launch()

View File

@ -1,22 +1,20 @@
import random
import gradio as gr
def chat(message, history):
history = history or []
if message.startswith("How many"):
message = message.lower()
if message.startswith("how many"):
response = random.randint(1, 10)
elif message.startswith("How"):
elif message.startswith("how"):
response = random.choice(["Great", "Good", "Okay", "Bad"])
elif message.startswith("Where"):
elif message.startswith("where"):
response = random.choice(["Here", "There", "Somewhere"])
else:
response = "I don't know"
history.append((message, response))
return history, history
chatbot = gr.Chatbot().style(color_map=("green", "pink"))
demo = gr.Interface(
chat,

View File

@ -1,10 +1,8 @@
import numpy as np
import gradio as gr
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
def generate_tone(note, octave, duration):
sr = 48000
a4_freq, tones_from_a4 = 440, 12 * (octave - 4) + (note - 9)
@ -14,7 +12,6 @@ def generate_tone(note, octave, duration):
audio = (20000 * np.sin(audio * (2 * np.pi * frequency))).astype(np.int16)
return sr, audio
demo = gr.Interface(
generate_tone,
[
@ -24,6 +21,5 @@ demo = gr.Interface(
],
"audio",
)
if __name__ == "__main__":
demo.launch()

13
demo/hello_blocks/run.py Normal file
View File

@ -0,0 +1,13 @@
import gradio as gr
def greet(name):
return "Hello " + name + "!"
with gr.Blocks() as demo:
name = gr.Textbox(label="Name")
output = gr.Textbox(label="Output Box")
greet_btn = gr.Button("Greet")
greet_btn.click(fn=greet, inputs=name, outputs=output)
if __name__ == "__main__":
demo.launch()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -1,10 +1,8 @@
import gradio as gr
def greet(name):
return "Hello " + name + "!!"
return "Hello " + name + "!"
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
if __name__ == "__main__":
demo.launch()

View File

@ -1,15 +1,12 @@
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(
fn=greet,
inputs=gr.Textbox(lines=2, placeholder="Name Here..."),
outputs="text",
)
if __name__ == "__main__":
demo.launch()

View File

@ -1,13 +1,11 @@
import gradio as gr
def greet(name, is_morning, temperature):
salutation = "Good morning" if is_morning else "Good evening"
greeting = "%s %s. It is %s degrees today" % (salutation, name, temperature)
greeting = f"{salutation} {name}. It is {temperature} degrees today"
celsius = (temperature - 32) * 5 / 9
return greeting, round(celsius, 2)
demo = gr.Interface(
fn=greet,
inputs=["text", "checkbox", gr.Slider(0, 100)],

View File

@ -0,0 +1,15 @@
import gradio as gr
def increase(num):
return num + 1
with gr.Blocks() as demo:
a = gr.Number(label="a")
b = gr.Number(label="b")
btoa = gr.Button("a > b")
atob = gr.Button("b > a")
atob.click(increase, a, b)
btoa.click(increase, b, a)
if __name__ == "__main__":
demo.launch()

16
demo/score_tracker/run.py Normal file
View File

@ -0,0 +1,16 @@
import gradio as gr
scores = []
def track_score(score):
scores.append(score)
top_scores = sorted(scores, reverse=True)[:3]
return top_scores
demo = gr.Interface(
track_score,
gr.Number(label="Score"),
gr.JSON(label="Top Scores")
)
if __name__ == "__main__":
demo.launch()

View File

@ -1,18 +1,16 @@
import numpy as np
import gradio as gr
def sepia(input_img):
sepia_filter = np.array(
[[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]]
)
sepia_filter = np.array([
[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]
])
sepia_img = input_img.dot(sepia_filter.T)
sepia_img /= sepia_img.max()
return sepia_img
demo = gr.Interface(sepia, gr.Image(shape=(200, 200)), "image")
if __name__ == "__main__":
demo.launch()

View File

@ -1,13 +1,14 @@
import gradio as gr
import numpy as np
with gr.Blocks() as demo:
inp = gr.Image(source="webcam")
out = gr.Image()
def flip(im):
def flip(im):
return np.flipud(im)
inp.stream(flip, [inp], [out])
demo = gr.Interface(
flip,
gr.Image(source="webcam", streaming=True),
"image",
live=True
)
if __name__ == "__main__":
demo.launch()

View File

@ -4,13 +4,9 @@ Docs: examples
**Prerequisite**: Gradio requires Python 3.7 or above, that's it!
## What Problem is Gradio Solving?
## What does Gradio Do?
One of the *best ways to share* your machine learning model, API, or data science workflow with others is to create an **interactive demo** that allows your users or colleagues to try out the demo in their browsers.
A web-based demo is great as it allows anyone who can use a browser (not just technical people) to intuitively try their own inputs and understand what you've built.
However, creating such web-based demos has traditionally been difficult, as you needed to know web hosting to serve the web app and web development (HTML, CSS, JavaScript) to build a GUI for your demo.
One of the *best ways to share* your machine learning model, API, or data science workflow with others is to create an **interactive app** that allows your users or colleagues to try out the demo in their browsers.
Gradio allows you to **build demos and share them, all in Python.** And usually in just a few lines of code! So let's get started.
@ -32,9 +28,9 @@ $code_hello_world
$demo_hello_world
## The `Interface` class
## The `Interface` Class
You'll notice that in order to create the demo, we defined a `gradio.Interface` class. This `Interface` class can wrap almost any Python function with a user interface. In the example above, we saw a simple text-based function. But the function could be anything from music generator to a tax calculator to (most commonly) the prediction function of a pretrained machine learning model.
You'll notice that in order to make the demo, we created a `gradio.Interface`. This `Interface` class can wrap any Python function with a user interface. In the example above, we saw a simple text-based function. But the function could be anything from music generator to a tax calculator to the prediction function of a pretrained machine learning model.
The core `Interface` class is initialized with three required parameters:
@ -42,83 +38,75 @@ The core `Interface` class is initialized with three required parameters:
- `inputs`: which component(s) to use for the input, e.g. `"text"` or `"image"` or `"audio"`
- `outputs`: which component(s) to use for the output, e.g. `"text"` or `"image"` `"label"`
Gradio includes more than 20 different components, most of which can be used as inputs or outputs. ([See docs for complete list](https://gradio.app/docs))
Let's take a closer look at these Components used to provide input and output.
## Components Attributes
## Components
With these three arguments to `Interface`, you can quickly create user interfaces and `launch()` them. But what if you want to change how the UI components look or behave?
### Components Attributes
Let's say you want to customize the input text field - for example, you wanted it to be larger and have a text hint. If we use the actual input class for `Textbox` instead of using the string shortcut, you have access to much more customizability through component attributes.
We saw some simple Textbox components in the previous example. But what if you want to change how the UI components look or behave?
Let's say you want to customize the input text field - for example, you wanted it to be larger and have a text placeholder. If we use the actual class for `Textbox` instead of using the string shortcut, you have access to much more customizability through component attributes.
$code_hello_world_2
$demo_hello_world_2
To see a list of all the components Gradio supports and what attributes you can use to customize them, check out the [Docs](https://gradio.app/docs).
### Multiple Input and Output Components
## Multiple Inputs and Outputs
Let's say you had a much more complex function, with multiple inputs and outputs. In the example below, we define a function that takes a string, boolean, and number, and returns a string and number. Take a look how you pass a list of input and output components.
Let's say you had a more complex function, with multiple inputs and outputs. In the example below, we define a function that takes a string, boolean, and number, and returns a string and number. Take a look how you pass a list of input and output components.
$code_hello_world_3
$demo_hello_world_3
You simply wrap the components in a list. Each component in the `inputs` list corresponds to one of the parameters of the function, in order. Each component in the `outputs` list corresponds to one of the values returned by the function, again in order.
## Images
### An Image Example
Let's try an image-to-image function! When using the `Image` component, your function will receive a numpy array of your specified size, with the shape `(width, height, 3)`, where the last dimension represents the RGB values. We'll return an image as well in the form of a numpy array.
Gradio supports many types of Components, such as `Image`, `DataFrame`, `Video`, or `Label`. Let's try an image-to-image function to get a feel for these!
$code_sepia_filter
$demo_sepia_filter
Additionally, our `Image` input interface comes with an 'edit' button ✏️ which opens tools for cropping and zooming into images. We've found that manipulating images in this way can help reveal biases or hidden flaws in a machine learning model!
When using the `Image` Component as input, your function will receive a numpy array with the shape `(width, height, 3)`, where the last dimension represents the RGB values. We'll return an image as well in the form of a numpy array. You can learn the Python datatype used by each Component in the [Docs](https://gradio.app/docs).
In addition to images, Gradio supports other media types, such as audio or video. Read about these in the [Docs](https://gradio.app/docs).
You can also set the datatype used by the Component with the `type=` keyword argument. For example, if you wanted your function to take a filepath to an image instead of a numpy array, the input `Image` component could be written as
## DataFrames and Graphs
```python
gr.Image(type='filepath', shape=...)
```
You can use Gradio to support inputs and outputs from your typical data libraries, such as numpy arrays, pandas dataframes, and plotly graphs. Take a look at the demo below (ignore the complicated data manipulation in the function!)
Also note that our input `Image` Component comes with an 'edit' button, which allows for cropping and zooming into images. Manipulating images in this way can help reveal biases or hidden flaws in a machine learning model!
$code_sales_projections
$demo_sales_projections
Read more about the many Components and how to use them in the [Docs](https://gradio.app/docs).
## Blocks: More Flexibility and Control
Gradio offers two APIs to users: (1) **Interface**, a high level abstraction for creating demos (that we've been discussing so far), and (2) **Blocks**, a low-level API for designing web apps with more flexible layouts and data flows. Blocks allows you to do things like: group together related demos, change where components appear on the page, handle complex data flows (e.g. outputs can serve as inputs to other functions), and update properties/visibility of components based on user interaction -- still all in Python.
Gradio offers two classes to build apps:
As an example, Blocks uses nested `with` statements in Python to lay out components on a page, like this:
(1) **Interface**, a high level abstraction for creating demos (that we've been discussing so far), and
(2) **Blocks**, a low-level API for designing web apps with more flexible layouts and data flows. Blocks allows you to do things like: feature multiple data flows and demos, control where components appear on the page, handle complex data flows (e.g. outputs can serve as inputs to other functions), and update properties/visibility of components based on user interaction -- still all in Python. If this customizability is what you need, try `Blocks` instead!
### Hello, Blocks
Let's take a look at a simple example. Note how the API here differs from `Interface`.
$code_hello_blocks
$demo_hello_blocks
A couple things to note:
- a `Blocks` is created with a `with` clause, and any Component created inside this clause is automatically added to the app.
- Components appear vertically in the app in the order they are created. (Later we will cover customizing layouts!)
- a `Button` was created, and then a `click` event-listener was added to this button. The API for this should look familiar! Like an `Interface`, the `click` method takes (1) a python function, (2) input components, and (3) output components.
### More Complexity
Here's an app to give you a taste of what's possible with Blocks.
$code_blocks_flipper
$demo_blocks_flipper
A lot more going on here! We'll cover how to create complex `Blocks` apps like this in the [Building with Blocks](/building_with_blocks) section of the guides.
If you are interested in how Blocks works, [read its dedicated Guide](https://gradio.app/introduction_to_blocks/).
## Sharing Demos
Gradio demos can be easily shared publicly by setting `share=True` in the `launch()` method. Like this:
```python
gr.Interface(classify_image, "image", "label").launch(share=True)
```
This generates a public, shareable link that you can send to anybody! When you send this link, the user on the other side can try out the model in their browser. Because the processing happens on your device (as long as your device stays on!), you don't have to worry about any packaging any dependencies. A share link usually looks something like this: **XXXXX.gradio.app**. Although the link is served through a Gradio URL, we are only a proxy for your local server, and do not store any data sent through the interfaces.
Keep in mind, however, that these links are publicly accessible, meaning that anyone can use your model for prediction! Therefore, make sure not to expose any sensitive information through the functions you write, or allow any critical changes to occur on your device. If you set `share=False` (the default, except in colab notebooks), only a local link is created, which can be shared by [port-forwarding](https://www.ssh.com/ssh/tunneling/example) with specific users.
Share links expire after 72 hours. For permanent hosting, see the next section.
![Sharing diagram](/assets/guides/sharing.svg)
## Hosting Gradio Demo on Spaces
If you'd like to have a permanent link to your Gradio demo on the internet, use Huggingface Spaces. Hugging Face Spaces provides the infrastructure to permanently host your machine learning model for free!
You can either drag and drop a folder containing your Gradio model and all related files, or you can point Spaces to your Git repository and Spaces will pull the Gradio interface from there. See [Huggingface Spaces](http://huggingface.co/spaces/) for more information.
![Hosting Demo](/assets/guides/hf_demo.gif)
## Next Steps
Now that you're familiar with the basics of Gradio, here are some good next steps:
Congrats, you're now familiar with the basics of Gradio 🥳. Onto the next guide - or skip around the curriculum if you wish!

View File

@ -0,0 +1,103 @@
# Common Features
Let's go through some of the most popular features of Gradio!
## Example Inputs
You can provide example data that a user can easily load into `Interface`. This can be helpful to demonstrate the types of inputs the model expects, as well as to provide a way to explore your dataset in conjunction with your model. To load example data, you can provide a **nested list** to the `examples=` keyword argument of the Interface constructor. Each sublist within the outer list represents a data sample, and each element within the sublist represents an input for each input component. The format of example data for each component is specified in the [Docs](https://gradio.app/docs).
$code_calculator
$demo_calculator
You can load a large dataset into the examples to browse and interact with the dataset through Gradio. The examples will be automatically paginated (you can configure this through the `examples_per_page` argument of `Interface`).
## Decriptive Content
In the previous example, you may have noticed the `title=` and `description=` keyword arguments in the `Interface` constructor that helps users understand your app.
There are three arguments in `Interface` constructor to specify where this content should go:
* `title`: which accepts text and can displays it at the very top of interface, and also becomes the page title.
* `description`: which accepts text, markdown or HTML and places it right under the title.
* `article`: which is also accepts text, markdown or HTML and places it below the interface.
![annotated](/assets/guides/annotated.png)
If you're using the `Blocks` API instead, you can insert text, markdown, or HTML anywhere using the `gr.Markdown(...)` or `gr.HTML(...)` components, with descriptive content inside the `Component` constructor.
Another useful keyword argument is `label=`, which is present in every `Component`. This modifies the label text at the top of each `Component`.
```python
gr.Number(label='Age')
```
## Flagging
By default, an `Interface` will have "Flag" button. When a user testing your `Interface` sees input with interesting output, such as erroneous or unexpected model behaviour, they can flag the input for you to review. Within the directory provided by the `flagging_dir=` argument to the `Interface` constructor, a CSV file will log the flagged inputs. If the interface involves file data, such as for Image and Audio components, folders will be created to store those flagged data as well.
For example, with the calculator interface shown above, we would have the flagged data stored in the flagged directory shown below:
```directory
+-- calculator.py
+-- flagged/
| +-- logs.csv
```
*flagged/logs.csv*
```csv
num1,operation,num2,Output
5,add,7,12
6,subtract,1.5,4.5
```
With the sepia interface shown above, we would have the flagged data stored in the flagged directory shown below:
```directory
+-- sepia.py
+-- flagged/
| +-- logs.csv
| +-- im/
| | +-- 0.png
| | +-- 1.png
| +-- Output/
| | +-- 0.png
| | +-- 1.png
```
*flagged/logs.csv*
```csv
im,Output
im/0.png,Output/0.png
im/1.png,Output/1.png
```
If you wish for the user to provide a reason for flagging, you can pass a list of strings to the `flagging_options` argument of Interface. Users will have to select one of the strings when flagging, which will be saved as an additional column to the CSV.
## Queuing
If your app expects heavy traffic, set `enable_queue` parameter in the `launch` method to `True` to prevent timeouts. You should also do this if the inference time of your function is long (> 1min). This will queue up calls so only a single call is processed at a time.
With `Interface`:
```python
demo = gr.Interface(...)
demo.launch(enable_queue=True)
```
With `Blocks`:
```python
with gr.Blocks() as demo:
#...
demo.launch(enable_queue=True)
# or to specify only certain functions for queueing
with gr.Blocks() as demo2:
num1 = gr.Number()
num2 = gr.Number()
output = gr.Number()
gr.Button("Add").click(
lambda a, b: a + b, [num1, num2], output)
gr.Button("Multiply").click(
lambda a, b: a * b, [num1, num2], output, queue=True)
demo2.launch()
```

View File

@ -0,0 +1,55 @@
# Sharing Your App
## Sharing Demos
Gradio demos can be easily shared publicly by setting `share=True` in the `launch()` method. Like this:
```python
demo.launch(share=True)
```
This generates a public, shareable link that you can send to anybody! When you send this link, the user on the other side can try out the model in their browser. Because the processing happens on your device (as long as your device stays on!), you don't have to worry about any packaging any dependencies. A share link usually looks something like this: **XXXXX.gradio.app**. Although the link is served through a Gradio URL, we are only a proxy for your local server, and do not store any data sent through the interfaces.
Keep in mind, however, that these links are publicly accessible, meaning that anyone can use your model for prediction! Therefore, make sure not to expose any sensitive information through the functions you write, or allow any critical changes to occur on your device. If you set `share=False` (the default, except in colab notebooks), only a local link is created, which can be shared by [port-forwarding](https://www.ssh.com/ssh/tunneling/example) with specific users.
![Sharing diagram](/assets/guides/sharing.svg)
Share links expire after 72 hours.
## Hosting on HF Spaces
If you'd like to have a permanent link to your Gradio demo on the internet, use Hugging Face Spaces. Hugging Face Spaces provides the infrastructure to permanently host your machine learning model for free!
You can either drag and drop a folder containing your Gradio model and all related files, or you can point Spaces to your Git repository and Spaces will pull the Gradio interface from there. See [Huggingface Spaces](http://huggingface.co/spaces/) for more information.
![Hosting Demo](/assets/guides/hf_demo.gif)
## API Page
$demo_hello_world
See the link to the "API" in the app above? This is a page that documents the REST API that users can use to query the `Interface` function. `Blocks` apps can also generate an API page, though the API has to be explicitly named for each event listener, such as
```python
btn.click(add, [num1, num2], output, api_name="addition")
```
This will document the endpoint `/api/addition/` to the automatically generated API page.
## Authentication
You may wish to put an authentication page in front of your interface to limit who can open your interface. With the `auth=` keyword argument in the `launch()` method, you can pass a list of acceptable username/password tuples; or, for more complex authentication handling, you can even pass a function that takes a username and password as arguments, and returns True to allow authentication, False otherwise. Here's an example that provides password-based authentication for a single user named "admin":
```python
demo.launch(auth=("admin", "pass1234"))
```
Here's one that accepts any login where the username and password are the same.
```python
def same_auth(username, password):
return username == password
demo.launch(auth=same_auth)
```

View File

@ -0,0 +1,26 @@
# Interface State
## Global State
Your function may use data that persists beyond a single function call. If the data is something accessible to all function calls and all users, you can create a variable outside the function call and access it inside the function. For example, you may load a large model outside the function and use it inside the function so that every function call does not need to reload the model.
$code_score_tracker
In the code above, the `scores` array is shared between all users. If multiple users are accessing this demo, their scores will all be added to the same list, and the returned top 3 scores will be collected from this shared reference.
## Session State
Another type of data persistence Gradio supports is session **state**, where data persists across multiple submits within a page session. However, data is *not* shared between different users of your model. To store data in a session state, you need to do three things:
1. Pass in an extra parameter into your function, which represents the state of the interface.
2. At the end of the function, return the updated value of the state as an extra return value.
3. Add the `'state'` input and `'state'` output components when creating your `Interface`
A chatbot is an example where you would need session state - you want access to a users previous submissions, but you cannot store chat history in a global variable, because then chat history would get jumbled between different users.
$code_chatbot_demo
$demo_chatbot_demo
Notice how the state persists across submits within each page, but if you load this demo in another tab (or refresh the page), the demos will not share chat history.
The default value of `state` is None. If you pass a default value to the state parameter of the function, it is used as the default value of the state instead.

View File

@ -1,9 +0,0 @@
# Providing Examples
## The `examples=` argument
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
## Cached Examples
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

View File

@ -0,0 +1,20 @@
# Reactive Interfaces
## Live Interfaces
You can make interfaces automatically refresh by setting `live=True` in the interface. Now the interface will recalculate as soon as the user input changes.
$code_calculator_live
$demo_calculator_live
Note there is no submit button, because the interface resubmits automatically on change.
## Streaming Components
Some components have a "streaming" mode, such as `Audio` component in microphone mode, or the `Image` component in webcam mode. Streaming means data is sent continuously to the backend and the `Interface` function is continuously being rerun.
The difference between `gr.Audio(source='microphone')` and `gr.Audio(source='microphone', streaming=True)`, when both are used in `gr.Interface(live=True)`, is that the first `Component` will automatically submit data and run the `Interface` function when the user stops recording, whereas the second `Component` will continuously send data and run the `Interface` function *during* recording.
Here is example code of streaming images from the webcam.
$code_stream_frames

View File

@ -0,0 +1,39 @@
# More on Examples & Flagging
## Providing Examples
As covered in the Quickstart, adding examples to an Interface is as easy as providing a list of lists to the `examples`
keyword argument.
Each sublist is a data sample, where each element corresponds to an input of the prediction function.
The inputs must be ordered in the same order as the prediction function expects them.
If your interface only has one input component, then you can provide your examples as a regular list instead of a list of lists.
### Loading Examples from a Directory
You can also specify a path to a directory containing your examples. If your Interface takes only a single file-type input, e.g. an image classifier, you can simply pass a directory filepath to the `examples=` argument, and the `Interface` will load the images in the directory as examples.
In the case of multiple inputs, this directory must
contain a log.csv file with the example values.
In the context of the calculator demo, we can set `examples='/demo/calculator/examples'` and in that directory we include the following `log.csv` file:
```csv
num,operation,num2
5,"add",3
4,"divide",2
5,"multiply",3
```
This can be helpful when browsing flagged data. Simply point to the flagged directory and the `Interface` will load the examples from the flagged data.
### Providing Partial Examples
Sometimes your app has many input components, but you would only like to provide examples for a subset of them. In order to exclude some inputs from the examples, pass `None` for all data samples corresponding to those particular components.
## Caching examples
You may wish to provide some cached examples of your model for users to quickly try out, in case your model takes a while to run normally.
If `cache_examples=True`, the `Interface` will run all of your examples through your app and save the outputs when you call the `launch()` method. This data will be saved in a directory called `gradio_cached_examples`.
Whenever a user clicks on an example, the output will automatically be populated in the app now, using data from this cached directory instead of actually running the function. This is useful so users can quickly try out your model without adding any load!
Keep in mind once the cache is generated, it will not be updated in future launches. If the examples or function logic change, delete the cache folder to clear the cache and rebuild it with another `launch()`.

View File

@ -1,24 +1,6 @@
# Advanced Interface Features
Docs: series, parallel
**Prerequisite**: This Guide builds on the Quickstart. Make sure to [read the Quickstart first](/getting_started).
<span id="advanced-features"></span>
In this Guide, we go through several advanced functionalities that your `gradio.Interface` demo can include without you needing to write much more code!
## Authentication 🔒
You may wish to put an authentication page in front of your interface to limit who can open your interface. With the `auth=` keyword argument in the `launch()` method, you can pass a list of acceptable username/password tuples; or, for more complex authentication handling, you can even pass a function that takes a username and password as arguments, and returns True to allow authentication, False otherwise. Here's an example that provides password-based authentication for a single user named "admin":
```python
gr.Interface(fn=classify_image, inputs=image, outputs=label).launch(
auth=("admin", "pass1234")
)
```
## Interpreting your Predictions 🔬
## Interpreting your Predictions
Most models are black boxes such that the internal logic of the function is hidden from the end user. To encourage transparency, we've made it very easy to add interpretation to your model by simply setting the `interpretation` keyword in the `Interface` class to `default`. This allows your users to understand what parts of the input are responsible for the output. Take a look at the simple interface below which shows an image classifier that also includes interpretation:
@ -37,25 +19,15 @@ $code_gender_sentence_default_interpretation
So what is happening under the hood? With these interpretation methods, Gradio runs the prediction multiple times with modified versions of the input. Based on the results, you'll see that the interface automatically highlights the parts of the text (or image, etc.) that contributed increased the likelihood of the class as red. The intensity of color corresponds to the importance of that part of the input. The parts that decrease the class confidence are highlighted blue.
You can also write your own interpretation function. The demo below adds custom interpretation to the previous demo. This function will take the same inputs as the main wrapped function. The output of this interpretation function will be used to highlight the input of each input interface - therefore the number of outputs here corresponds to the number of input interfaces. To see the format for interpretation for each input interface, check the Docs.
You can also write your own interpretation function. The demo below adds custom interpretation to the previous demo. This function will take the same inputs as the main wrapped function. The output of this interpretation function will be used to highlight the input of each input component - therefore the function must return a list where the number of elements corresponds to the number of input components. To see the format for interpretation for each input component, check the Docs.
$code_gender_sentence_custom_interpretation
## Custom Styling 🧑‍🎨
## Custom Styling
If you'd like to have more fine-grained control over any aspect of your demo, you can also write your own css or pass in a css file, with the `css` parameter of the `Interface` class.
## Custom Flagging Options 🎌
In some cases, you might like to provide your users or testers with *more* than just a binary option to flag a sample. You can provide `flagging_options` that they select from a dropdown each time they click the flag button. This lets them provide additional feedback every time they flag a sample.
Here's an example:
```python
gr.Interface(fn=classify_image, inputs=image, outputs=label, flagging_options=["incorrect", "ambiguous", "offensive", "other"]).launch()
```
## Loading Hugging Face Models and Spaces 🤗
## Loading Hugging Face Models and Spaces
Gradio integrates nicely with the Hugging Face Hub, allowing you to load models and Spaces with just one line of code. To use this, simply use the `load()` method in the `Interface` class. So:
@ -84,7 +56,7 @@ io = gr.Interface.load("models/EleutherAI/gpt-neo-2.7B")
io("It was the best of times") # outputs model completion
```
## Putting Interfaces in Parallel and Series
## Putting Interfaces in Parallel and Series
Gradio also lets you mix interfaces very easily using the `gradio.Parallel` and `gradio.Series` classes. `Parallel` lets you put two similar models (if they have the same input type) in parallel to compare model predictions:
@ -106,41 +78,3 @@ gr.Series(generator, translator).launch() # this demo generates text, then tran
```
And of course, you can also mix `Parallel` and `Series` together whenever that makes sense!
## Queuing to Manage Long Inference Times 👥
If many people are using your interface or if the inference time of your function is long (> 1min), simply set the `enable_queue` parameter in the `launch` method to `True` to prevent timeouts.
```python
gr.Interface(fn=classify_image, inputs=image, outputs=label).launch(enable_queue=True)
```
This sets up a queue of workers to handle the predictions and return the response to the front end. This is strongly recommended if you are planning on uploading your demo to Hugging Face Spaces (as described above) so that you can manage a large number of users simultaneously using your demo.
## Stateful Demos ✨
Your function may use data that persists beyond a single function call. If the data is something accessible to all function calls and all users, you can create a variable outside the function call and access it inside the function. For example, you may load a large model outside the function and use it inside the function so that every function call does not need to reload the model.
Another type of data persistence Gradio supports is session **state**, where data persists across multiple submits within a page load. However, data is *not* shared between different users of your model. To store data in a session state, you need to do three things:
1. Pass in an extra parameter into your function, which represents the state of the interface.
2. At the end of the function, return the updated value of the state as an extra return value.
3. Add the `'state'` input and `'state'` output components when creating your `Interface`
See the chatbot example below:
$code_chatbot_demo
$demo_chatbot_demo
Notice how the state persists across submits within each page, but the state is not shared between the two pages. Some more points to note: you can pass in a default value to the state parameter, which is used as the initial value of the state. The state must be a something that can be serialized to a JSON format (e.g. a dictionary, a list, or a single value. Typically, objects will not work).
## Next Steps
Now that you know all about `gradio.Interface`, here are some good next steps:
* Check out [the free Gradio course](https://huggingface.co/course/chapter9/1) for a step-by-step walkthrough of everything Gradio-related with lots of examples of how to build your own machine learning demos 📖
* Gradio offers two APIs to users: **Interface**, a high level abstraction covered in this guide, and **Blocks**, a more flexible API for designing web apps with more flexible layouts and data flows. [Read more about Blocks here](/introduction_to_blocks/) 🧱
* If you just want to explore what demos other people have built with Gradio, [browse public Hugging Face Spaces](http://hf.space/), view the underlying Python code, and be inspired 🤗

View File

@ -0,0 +1,94 @@
# Blocks and Event Listeners
We took a quick look at Blocks in the Quickstart. Let's dive deeper.
## Blocks Structure
Take a look at the demo below.
$code_hello_blocks
$demo_hello_blocks
- First, note the `with gr.Blocks() as demo:` clause. The Blocks app code will be contained within this clause.
- Next come the Components. These are the same Components used in `Interface`. However, instead of being being passed to some constructor, Components are automatically added to the Blocks as they are created within the `with` clause.
- Finally, the `click()` event listener. Event listeners define the data flows within the app. In the example above, the listener ties the two Textboxes together. The Textbox `name` acts as the input and Textbox `output` acts as the output to the `greet` method. This dataflow is triggered when the Button `greet_btn` is clicked. Like an Interface, an event listener can take multiple inputs or outputs.
## Event Listeners and Interactivity
In the example above, you'll notice that you are able to edit Textbox `name`, but not Textbox `output`. This is because any Component that acts as an input to an event listener is made interactive. However, since Textbox `output` acts only as an output, it is not interactive. You can directly configure the interactivity of a Component with the `interactive=` keyword argument.
```python
output = gr.Textbox(label="Output", interactive=True)
```
## Types of Event Listeners
Take a look at the demo below:
$code_blocks_hello
$demo_blocks_hello
Instead of being triggered by a click, the `welcome` function is triggered by typing in the Textbox `inp`. This is due to the `change()` event listener. Different Components support different event listeners. For example, the `Video` Commponent supports a `play()` event listener, triggered when a user presses play. See the [Docs](http://gradio.app/docs) for the event listeners for each Component.
## Multiple Data Flows
A Blocks app is not limited to a single data flow the way Interfaces are. Take a look at the demo below:
$code_reversible_flow
$demo_reversible_flow
Note that `num1` can act as input to `num2`, and also vice-versa! As your apps get more complex, you will have many data flows connecting various Components.
## Function Return List vs Dict
So far, you have seen event listener functions return a single value for every output component, in the order listed by the event listener. For example:
```python
with gr.Blocks() as demo:
food_box = gr.Number(value=10, label="Food Count")
status_box = gr.Textbox()
def eat(food):
if food > 0:
return food - 1, "full"
else:
return 0, "hungry"
gr.Button("EAT").click(
fn=eat,
inputs=food_box,
outputs=[food_box, status_box]
)
```
Instead of returning a list of values corresponing to each output component in order, you can also return a dictionary, with the key corresponding to the output component and the value as the new value. This also allows you to skip updating some output components.
```python
with gr.Blocks() as demo:
food_box = gr.Number(value=10, label="Food Count")
status_box = gr.Textbox()
def eat(food):
if food > 0:
return {food_box: food - 1, status_box: "full"}
else:
return {status_box: "hungry"}
gr.Button("EAT").click(
fn=eat,
inputs=food_box,
outputs=[food_box, status_box]
)
```
Notice how when there is no food, we only update the `status_box` element. We skipped updating the `food_box` component.
Dictionary returns are helpful when an event listener affects many components on return, or conditionally affects outputs and not others.
Keep in mind that with dictionary returns, we still need to specify the possible outputs in the event listener.
## Updating Component Configurations
The return value of an event listener function is usually the updated value of the corresponding output Component. Sometimes we want to update the configuration of the Component as well, such as the visibility. In this case, we return a `gr.update()` object instead of just the update Component value.
$code_blocks_essay_update
$demo_blocks_essay_update
See how we can configure the Textbox itself through the `gr.update()` method. The `value=` argument can still be used to update the value along with Component configuration.

View File

@ -0,0 +1,16 @@
## Adding examples to a Blocks app
In order to add examples to an app written with the Blocks API, you need to use the `gr.Examples` component helper.
This class is a wrapper over the `gr.Dataset` component.
During class creation, `gr.Examples` will instantiate a `gr.Dataset` and attach an event listener on the dataset click event
that will populate all the inputs with the values of that row of the dataset.
To show this in practice, we will build the same calculator but with Blocks instead of an Interface.
$code_calculator_blocks
$demo_calculator_blocks
By the way, Interface uses `gr.Examples` under the hood too!
So if you know how this example works you also know how the Interface examples work! 🥳

View File

@ -1,91 +0,0 @@
# Adding Examples To Your App
Docs: examples
## Introduction
As we saw in the [Quickstart](/getting_started#example-inputs), providing example inputs to your app are a helpful way
to let your audience explore the functionality of your app without having them specify all of your app's expected inputs.
In this guide we'll go into greater depth on how you can provide example inputs to your apps.
## Adding examples to an Interface
As covered in the Quickstart, adding examples to an Interface is as easy as providing a list of lists to the `examples`
keyword argument.
Each sublist is a data sample, where each element corresponds to an input of the prediction function.
The inputs must be ordered in the same order as the prediction function expects them.
We can see the `examples` parameter in action in this calculator demo:
$code_calculator
$demo_calculator
If your interface only has one input component, then you can provide your examples as a regular list instead of a list of lists.
You can also specify a path to a directory containing your examples. In the case of multiple inputs, this directory must
contain a log.csv file with the example values.
In the context of the calculator demo, we can change `examples` to be `examples=/demo/calculator/examples` and in that directory we include the following `log.csv` file:
```csv
num,operation,num2
5,"add",3
4,"divide",2
5,"multiply",3
```
## Adding examples to a Blocks app
In order to add examples to an app written with the Blocks API, you need to use the `gr.Examples` component helper.
This class is a wrapper over the `gr.Dataset` component.
During class creation, `gr.Examples` will instantiate a `gr.Dataset` and attach an event listener on the dataset click event
that will populate all the inputs with the values of that row of the dataset.
To show this in practice, we will build the same calculator but with Blocks instead of an Interface.
$code_calculator_blocks
$demo_calculator_blocks
By the way, Interface uses `gr.Examples` under the hood too!
So if you know how this example works you also know how the Interface examples work! 🥳
## Caching examples
Both `gr.Examples` and `Interface` have a `cache_examples` parameter.
The default in the previous demos is to not cache examples, but if `cache_examples=True`, the `gr.Examples` component will
run all of your examples through your app and save the outputs when you call the `launch()` method.
Whenever someone clicks on an example, the output will automatically be populated in the app.
This is useful especially when your model can take a while to run!
We can see this in the following demo.
It's the same as the previous calculator with only the changes needed to cache examples.
$code_calculator_blocks_cached
$demo_calculator_blocks_cached
Note that when using `gr.Examples` and with `cache_examples=True`, you must specify the output component and the function
to run.
## Providing examples for only a subset of inputs
Sometimes your app has many possible inputs, but you would only like to provide examples for a subset of them.
For example, consider an app showcasing an image classification algorithm.
The app inputs are a sample image to classify with some additional sliders to control the algorithm.
In this case, you may want to only provide examples for the image and let your users control the sliders themselves.
In order to exclude some inputs from the examples, pass `None` for all data samples corresponding to that particular input.
In the following example, we have an app demoing a GAN. Note how the last three examples do not show up in the examples
dataset.
$code_fake_gan
$demo_fake_gan
## Next Steps
Now that you know all about adding examples to your apps, here are some good next steps:
* Check out [the free Gradio course](https://huggingface.co/course/chapter9/1) for a step-by-step walkthrough of everything Gradio-related with lots of examples of how to build your own machine learning demos 📖
* If you just want to explore what demos other people have built with Gradio, [browse public Hugging Face Spaces](http://hf.space/), view the underlying Python code, and be inspired 🤗

View File

@ -1,81 +0,0 @@
# Adding Rich Descriptions to Your Demo
Related spaces: https://huggingface.co/spaces/ThomasSimonini/Chat-with-Gandalf-GPT-J6B, https://huggingface.co/spaces/kingabzpro/Rick_and_Morty_Bot, https://huggingface.co/spaces/nateraw/cryptopunks-generator
Tags: MARKDOWN, DESCRIPTION, ARTICLE
## Introduction
When an interface is shared, it is usually accompanied with some form of explanatory text, links or images. This guide will go over how to easily add these on gradio.
For example, take a look at this fun chatbot interface below. It has a title, description, image as well as a link in the bottom.
<iframe src="https://hf.space/embed/aliabd/rick-and-morty/+" frameBorder="0" height="875" title="Gradio app" class="container p-0 flex-grow space-iframe" allow="accelerometer; ambient-light-sensor; autoplay; battery; camera; document-domain; encrypted-media; fullscreen; geolocation; gyroscope; layout-animations; legacy-image-formats; magnetometer; microphone; midi; oversized-images; payment; picture-in-picture; publickey-credentials-get; sync-xhr; usb; vr ; wake-lock; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-downloads"></iframe>
## The parameters in `Interface`
There are three parameters in `Interface` where text can go:
* `title`: which accepts text and can displays it at the very top of interface
* `description`: which accepts text, markdown or HTML and places it right under the title.
* `article`: which is also accepts text, markdown or HTML but places it below the interface.
![annotated](/assets/guides/annotated.png)
## Code example
Here's all the text-related code required to recreate the interface shown above.
```python
import gradio as gr
title = "Ask Rick a Question"
description = """
<center>
The bot was trained to answer questions based on Rick and Morty dialogues. Ask Rick anything!
<img src="https://huggingface.co/spaces/course-demos/Rick_and_Morty_QA/resolve/main/rick.png" width=200px>
</center>
"""
article = "Check out [the original Rick and Morty Bot](https://huggingface.co/spaces/kingabzpro/Rick_and_Morty_Bot) that this demo is based off of."
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
tokenizer = AutoTokenizer.from_pretrained("ericzhou/DialoGPT-Medium-Rick_v2")
model = AutoModelForCausalLM.from_pretrained("ericzhou/DialoGPT-Medium-Rick_v2")
def predict(input):
# tokenize the new input sentence
new_user_input_ids = tokenizer.encode(input + tokenizer.eos_token, return_tensors='pt')
# generate a response
history = model.generate(new_user_input_ids, max_length=1000, pad_token_id=tokenizer.eos_token_id).tolist()
# convert the tokens to text, and then split the responses into the right format
response = tokenizer.decode(history[0]).split("<|endoftext|>")
return response[1]
gr.Interface(fn = predict, inputs = ["textbox"], outputs = ["text"], title = title, description = description, article = article).launch()
```
Of course, you don't have to use HTML and can instead rely on markdown, like we've done in the `article` parameter above.
The table below shows the syntax for the most common markdown commands.
| Type | Syntax |
| ----------- | ----------- |
| Header | # Heading 1 ## Heading 2 ### Heading 3 |
| Link | \[gradio's website](https://gradio.app) |
| Image | !\[gradio's logo](https://gradio.app/assets/guides/logo.png) |
| Text Formatting | \_italic_ \*\*bold** |
| List | \* Item 1 \* Item 2 |
| Quote | \> this is a quote |
| Code | Inline \`code\` has \`back-ticks around\` it. |
Here's a neat [cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) with more.
### That's all! Happy building :)

View File

@ -1,190 +0,0 @@
# Quickstart
Docs: examples
**Prerequisite**: Gradio requires Python 3.7 or above, that's it!
## What Problem is Gradio Solving? 😲
One of the *best ways to share* your machine learning model, API, or data science workflow with others is to create an **interactive demo** that allows your users or colleagues to try out the demo in their browsers.
A web-based demo is great as it allows anyone who can use a browser (not just technical people) to intuitively try their own inputs and understand what you've built.
However, creating such web-based demos has traditionally been difficult, as you needed to know web hosting to serve the web app and web development (HTML, CSS, JavaScript) to build a GUI for your demo.
Gradio allows you to **build demos and share them, all in Python.** And usually in just a few lines of code! So let's get started.
## Hello, World ⚡
To get Gradio running with a simple "Hello, World" example, follow these three steps:
<span>1.</span> Install Gradio from pip. Note, the minimal supported Python version is 3.7.
```bash
pip install gradio
```
<span>2.</span> Run the code below as a Python script or in a Python notebook (or in a [colab notebook](https://colab.research.google.com/drive/18ODkJvyxHutTN0P5APWyGFO_xwNcgHDZ?usp=sharing)).
$code_hello_world
<span>3.</span> The demo below will appear automatically within the Python notebook, or pop in a browser on [http://localhost:7860](http://localhost:7860/) if running from a script.
$demo_hello_world
## The `Interface` class 🧡
You'll notice that in order to create the demo, we defined a `gradio.Interface` class. This `Interface` class can wrap almost any Python function with a user interface. In the example above, we saw a simple text-based function. But the function could be anything from music generator to a tax calculator to (most commonly) the prediction function of a pretrained machine learning model.
The core `Interface` class is initialized with three required parameters:
- `fn`: the function to wrap a UI around
- `inputs`: which component(s) to use for the input, e.g. `"text"` or `"image"` or `"audio"`
- `outputs`: which component(s) to use for the output, e.g. `"text"` or `"image"` `"label"`
Gradio includes more than 20 different components, most of which can be used as inputs or outputs. ([See docs for complete list](https://gradio.app/docs))
## Components Attributes 💻
With these three arguments to `Interface`, you can quickly create user interfaces and `launch()` them. But what if you want to change how the UI components look or behave?
Let's say you want to customize the input text field - for example, you wanted it to be larger and have a text hint. If we use the actual input class for `Textbox` instead of using the string shortcut, you have access to much more customizability through component attributes.
$code_hello_world_2
$demo_hello_world_2
To see a list of all the components Gradio supports and what attributes you can use to customize them, check out the [Docs](https://gradio.app/docs).
## Multiple Inputs and Outputs 🔥
Let's say you had a much more complex function, with multiple inputs and outputs. In the example below, we define a function that takes a string, boolean, and number, and returns a string and number. Take a look how you pass a list of input and output components.
$code_hello_world_3
$demo_hello_world_3
You simply wrap the components in a list. Each component in the `inputs` list corresponds to one of the parameters of the function, in order. Each component in the `outputs` list corresponds to one of the values returned by the function, again in order.
## Images 🎨
Let's try an image-to-image function! When using the `Image` component, your function will receive a numpy array of your specified size, with the shape `(width, height, 3)`, where the last dimension represents the RGB values. We'll return an image as well in the form of a numpy array.
$code_sepia_filter
$demo_sepia_filter
Additionally, our `Image` input interface comes with an 'edit' button ✏️ which opens tools for cropping and zooming into images. We've found that manipulating images in this way can help reveal biases or hidden flaws in a machine learning model!
In addition to images, Gradio supports other media types, such as audio or video. Read about these in the [Docs](https://gradio.app/docs).
## DataFrames and Graphs 📈
You can use Gradio to support inputs and outputs from your typical data libraries, such as numpy arrays, pandas dataframes, and plotly graphs. Take a look at the demo below (ignore the complicated data manipulation in the function!)
$code_sales_projections
$demo_sales_projections
## Example Inputs 🦮
You can provide example data that a user can easily load into the model. This can be helpful to demonstrate the types of inputs the model expects, as well as to provide a way to explore your dataset in conjunction with your model. To load example data, you can provide a **nested list** to the `examples=` keyword argument of the Interface constructor. Each sublist within the outer list represents a data sample, and each element within the sublist represents an input for each input component. The format of example data for each component is specified in the [Docs](https://gradio.app/docs).
$code_calculator
$demo_calculator
You can load a large dataset into the examples to browse and interact with the dataset through Gradio. The examples will be automatically paginated (you can configure this through the `examples_per_page` argument of `Interface`).
## Live Interfaces 🪁
You can make interfaces automatically refresh by setting `live=True` in the interface. Now the interface will recalculate as soon as the user input changes.
$code_calculator_live
$demo_calculator_live
Note there is no submit button, because the interface resubmits automatically on change.
## Flagging 🚩
Underneath the output interfaces, there is a "Flag" button. When a user testing your model sees input with interesting output, such as erroneous or unexpected model behaviour, they can flag the input for the interface creator to review. Within the directory provided by the `flagging_dir=` argument to the Interface constructor, a CSV file will log the flagged inputs. If the interface involves file data, such as for Image and Audio components, folders will be created to store those flagged data as well.
For example, with the calculator interface shown above, we would have the flagged data stored in the flagged directory shown below:
```directory
+-- calculator.py
+-- flagged/
| +-- logs.csv
```
*flagged/logs.csv*
```csv
num1,operation,num2,Output
5,add,7,12
6,subtract,1.5,4.5
```
With the sepia interface shown above, we would have the flagged data stored in the flagged directory shown below:
```directory
+-- sepia.py
+-- flagged/
| +-- logs.csv
| +-- im/
| | +-- 0.png
| | +-- 1.png
| +-- Output/
| | +-- 0.png
| | +-- 1.png
```
*flagged/logs.csv*
```csv
im,Output
im/0.png,Output/0.png
im/1.png,Output/1.png
```
You can review these flagged inputs by manually exploring the flagging directory, or load them into the examples of the Gradio interface by pointing the `examples=` argument to the flagged directory. If you wish for the user to provide a reason for flagging, you can pass a list of strings to the `flagging_options` argument of Interface. Users will have to select one of the strings when flagging, which will be saved as an additional column to the CSV.
## Blocks: More Flexibility and Control 🧱
Gradio offers two APIs to users: (1) **Interface**, a high level abstraction for creating demos (that we've been discussing so far), and (2) **Blocks**, a low-level API for designing web apps with more flexible layouts and data flows. Blocks allows you to do things like: group together related demos, change where components appear on the page, handle complex data flows (e.g. outputs can serve as inputs to other functions), and update properties/visibility of components based on user interaction -- still all in Python.
As an example, Blocks uses nested `with` statements in Python to lay out components on a page, like this:
$code_blocks_flipper
$demo_blocks_flipper
If you are interested in how Blocks works, [read its dedicated Guide](https://gradio.app/introduction_to_blocks/).
## Sharing Demos 🌎
Gradio demos can be easily shared publicly by setting `share=True` in the `launch()` method. Like this:
```python
gr.Interface(classify_image, "image", "label").launch(share=True)
```
This generates a public, shareable link that you can send to anybody! When you send this link, the user on the other side can try out the model in their browser. Because the processing happens on your device (as long as your device stays on!), you don't have to worry about any packaging any dependencies. A share link usually looks something like this: **XXXXX.gradio.app**. Although the link is served through a Gradio URL, we are only a proxy for your local server, and do not store any data sent through the interfaces.
Keep in mind, however, that these links are publicly accessible, meaning that anyone can use your model for prediction! Therefore, make sure not to expose any sensitive information through the functions you write, or allow any critical changes to occur on your device. If you set `share=False` (the default, except in colab notebooks), only a local link is created, which can be shared by [port-forwarding](https://www.ssh.com/ssh/tunneling/example) with specific users.
Share links expire after 72 hours. For permanent hosting, see the next section.
![Sharing diagram](/assets/guides/sharing.svg)
## Hosting Gradio Demo on Spaces 🤗
If you'd like to have a permanent link to your Gradio demo on the internet, use Huggingface Spaces. Hugging Face Spaces provides the infrastructure to permanently host your machine learning model for free!
You can either drag and drop a folder containing your Gradio model and all related files, or you can point Spaces to your Git repository and Spaces will pull the Gradio interface from there. See [Huggingface Spaces](http://huggingface.co/spaces/) for more information.
![Hosting Demo](/assets/guides/hf_demo.gif)
## Next Steps
Now that you're familiar with the basics of Gradio, here are some good next steps:
* Check out [the free Gradio course](https://huggingface.co/course/chapter9/1) for a step-by-step walkthrough of everything Gradio-related with lots of examples of how to build your own machine learning demos 📖
* Gradio offers two APIs to users: **Interface**, a high level abstraction for quickly creating demos, and **Blocks**, a more flexible API for designing web apps with more controlled layouts and data flows. [Read more about Blocks here](https://gradio.app/introduction_to_blocks/) 🧱
* If you'd like to stick with **Interface**, but want to add more advanced features to your demo (like authentication, interpretation, or state), check out our guide on [advanced features with the Interface class](https://gradio.app/advanced_interface_features/) 💪
* If you just want to explore what demos other people have built with Gradio and see the underlying Python code, [browse public Hugging Face Spaces](https://hf.space/), and be inspired 🤗

View File

@ -1,152 +0,0 @@
# Introduction to Gradio Blocks 🧱
Docs: update
Gradio is a Python library that allows you to quickly build web-based machine learning demos, data science dashboards, or other kinds of web apps, **entirely in Python**. These web apps can be launched from wherever you use Python (jupyter notebooks, colab notebooks, Python terminal, etc.) and shared with anyone instantly using Gradio's auto-generated share links.
To offer both simplicity and more powerful and flexible control for advanced web apps, Gradio offers two different APIs to users:
* ⚡`gradio.Interface`: a high-level API that allows you to create a full machine learning demo simply by providing a list of inputs and outputs.
* 🧱 `gradio.Blocks`: a low-level API that allows you to have full control over the data flows and layout of your application. You can build very complex, multi-step applications using Blocks (as in "building blocks").
This Guide will teach you the **Blocks API** and we will create several custom web apps in the process. It will be helpful but not necessary to be familiar with the Interface API before you read this tutorial.
## Why Blocks 🧱?
If you have already used `gradio.Interface`, you know that you can easily create fully-fledged machine learning demos with just a few lines of code. The Interface API is very convenient but in some cases may not be sufficiently flexible for your needs. For example, you might want to:
* Group together related demos as multiple tabs in one web app
* Change the layout of your demo instead of just having all of the inputs on the left and outputs on the right
* Have multi-step interfaces, in which the output of one model becomes the input to the next model, or have more flexible data flows in general
* Change a component's properties (for example, the choices in a Dropdown) or its visibilty based on user input
These are all use cases where you should use the Blocks API!
## "Hello World" with Blocks
After you have installed Gradio, run the code below as a Python script or in a Python notebook (or in a [colab notebook](https://colab.research.google.com/drive/1n_uB44G_uENGf0zroeVKgcytFQ-7UwZt?usp=sharing))
$code_blocks_hello
The interface below will appear automatically within the Python notebook, or pop in a browser on [http://localhost:7860](http://localhost:7860/) if running from a script.
$demo_blocks_hello
## Understanding this Example
This simple example introduces 5 concepts that underlie Blocks:
1. Blocks allow you to build web applications that combine markdown, HTML, buttons, and interactive **components** simply by *instantiating* objects in Python inside of a "`with gradio.Blocks`" context. The *order* in which you instantiate components <u>matters</u> as each element gets rendered into the web app in the order it was created. (More complex layouts are discussed below)
2. You can define **regular Python functions** anywhere in your code and run them with user input using BLocks. In our example, we have a simple function that adds a welcome message before a user's name, but you can write *any* Python function, from a simple calculation to large machine learning model's inference.
3. You can assign **events** to any Blocks component. This will run your function when the component is clicked/changed/etc. When you assign an event, you pass in three parameters: `fn`: the function that should be called, `inputs`: the (list) of input component(s), and `outputs`: the (list) of output components that should be called.<p />
In this example, we run the `update()` function when the value in the `Textbox` named `inp` changes. The event reads the value in `inp`, passes it as the `name` parameter to `update()`, which then returns a value that gets assigned to our second `Textbox` named `out`. <p /> To see a list of events that each component supports, see [the documentation](https://www.gradio.app/docs).
4. Blocks automatically figures out whether a component should be **interactive** (accept user input) or not, based on the event triggers you define. In our example, the first textbox is interactive, since its value is used by the `update()` function. The second textbox is not interactive, since its value is never used as an input. In some cases, you might want to override this, which you can do by passing the appropriate boolean to `interactive`, a parameter that every component accepts.
5. You can write and `launch()` your Blocks anywhere: jupyter notebooks, colab notebooks, or regular Python IDEs since Gradio uses the standard Python interpreter. You can also share Blocks with other people by setting a single parameter: `launch(share=True)`, which we will discuss towards the end of this guide.
## Layouts
By default, `Blocks` renders the components that you create *vertically in one column*. You can change that by creating additional columns (`with gradio.Column():`) or rows (`with gradio.Row():`) and creating components within those contexts.
Here's what you should keep in mind: any components created under a `Column` (this is also the default) will be laid out *vertically*. Any component created under a `Row` will be laid out *horizontally*, similar to the [flexbox model in web development](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox).
Finally, you can also create a `with gradio.Tabs():` and within it create multiple `with gradio.TabItem(name_of_tab):` children. Any component created inside of a `with gradio.TabItem(name_of_tab):` context appears in that tab.
Here is a example with tabs, rows, and columns:
$code_blocks_flipper
$demo_blocks_flipper
You'll notice that in this example, we've also created a `Button` component in each tab, and we've assigned a click event to each button, which is what actually runs the function. So let's talk more about events...
## Events
Just as you can control the layout, `Blocks` gives you fine-grained control over what events trigger function calls. Each component and many layouts have specific events that they support.
For example, the `Textbox` component has 2 events: `change()` (when the value inside of the textbox changes), and `submit()` (when a user presses the enter key while focused on the textbox). More complex components can have even more events: for example, the `Audio` component also has separate events for when the audio file is played, cleared, paused, etc. See [the documentation](https://www.gradio.app/docs) for the events each component supports.
You can attach event trigger to none, one, or more of these events. You create an event trigger by calling the name of the event on the component instance as a function -- e.g. `textbox.change(...)` or `btn.click(...)`. The function takes in three parameters, as discussed above:
* `fn`: the function to run
* `inputs`: a (list of) component(s) whose values should supplied as the input parameters to the function. Each component's value gets mapped to the corresponding function parameter, in order. This parameter can be `None` if the function does not take any parameters.
* `outputs`: a (list of) component(s) whose values should be updated based on the values returned by the function. Each return value gets sets the corresponding component's value, in order. This parameter can be `None` if the function does not return anything.
You can even make the input and output component be the same component, as we do in this example that uses a GPT model to do text completion:
$code_blocks_gpt
$demo_blocks_gpt
## Multistep Demos
In some cases, you might want want a "multi-step" demo, in which you reuse the output of one function as the input to the next. This is really easy to do with Blocks, as you can use a component for the input of one event trigger but the output of another. Take a look at the `text` component in the example below, its value is the result of a speech-to-text model, but also gets passed into a sentiment analysis model:
$code_blocks_speech_text_length
$demo_blocks_speech_text_length
## Updating Component Properties
So far, we have seen how to create events to update the value of another component. But if you want to change *other properties* of a component (like the visibility of a textbox or the choices in a radio button group)? You can do this by returning a component class's `update()` method instead of a regular return value from your function.
This is perhaps most easily illustrated with an example:
$code_blocks_essay
$demo_blocks_essay
You can also use the `gradio.update` function as a short-hand for using the component class's update method.
Here is the previous demo rewritten with `gradio.update`:
$code_blocks_essay_update
## Setting Default Values on Components
You can control the default value displayed in your components when the app first launches by setting the `value` parameter in the component constructor.
In the following simple calculator demo, `num_1` and `num_2` take on the values 4 and 0, respectively, when the app launches.
$code_calculator_blocks
$demo_calculator_blocks
This will work for all components, not just numbers. For example, setting `value` on a `gr.Image` equal to the full filepath of an image
will load that image into the component when the app launches.
## Sharing Blocks Publicly
Blocks can be easily shared publicly by setting `share=True` in the `launch()` method. Like this:
```python
demo = gr.Blocks()
with demo:
... # define components & events here
demo.launch(share=True)
```
This generates a public, shareable link that you can send to anybody! When you send this link, the user on the other side can try out the demo in their browser. Because the processing happens on your device (as long as your device stays on!), you don't have to worry about any packaging any dependencies. If you're working out of colab notebook, a share link is always automatically created. It usually looks something like this: **XXXXX.gradio.app**. Although the link is served through a gradio link, we are only a proxy for your local server, and do not store any data sent through the demo.
Keep in mind, however, that these links are publicly accessible, meaning that anyone can use your model for prediction! Therefore, make sure not to expose any sensitive information through the functions you write, or allow any critical changes to occur on your device. If you set `share=False` (the default), only a local link is created, which can be shared by [port-forwarding](https://www.ssh.com/ssh/tunneling/example) with specific users.
Share links expire after 72 hours. For permanent hosting, see Hosting Gradio Blocks on Spaces below.
![Sharing diagram](/assets/guides/sharing.svg)
## Hosting Gradio Blocks on Spaces
Huggingface provides the infrastructure to permanently host your Gradio demo on the internet, for free! You can either drag and drop a folder containing your Gradio model and all related files, or you can point HF Spaces to your Git repository and HF Spaces will pull the Gradio interface from there. It's just as easy to share a Blocks demo as it is a regular Gradio Interface.
See [Huggingface Spaces](http://huggingface.co/spaces/) for more information.
![Hosting Demo](/assets/guides/hf_demo.gif)

View File

@ -1,161 +0,0 @@
# Using Flagging
Related spaces: https://huggingface.co/spaces/aliabd/calculator-flagging-crowdsourced, https://huggingface.co/spaces/aliabd/calculator-flagging-options, https://huggingface.co/spaces/aliabd/calculator-flag-basic
Tags: FLAGGING, DATA
## Introduction
When you deploy or demo a machine learning model, you may find that it behaves differently than how you expected (e.g. the model makes an incorrect prediction) when a user tries it with their own data. Capturing these "hard" data points is important because it allows you to make you machine learning model more reliable and robust.
Gradio simplifies the collection of this data by including a FLAG button with every `Interface`. This allows your user or tester to easily send data back to you, whether the model is running locally or has been shared by setting `share=True`.
## The **Flag** button
Underneath the output interfaces, there is a button marked **Flag**. When a user testing your model sees input with interesting output, such as erroneous or unexpected model behaviour, they can flag the input for the interface creator to review.
![flag button](/assets/guides/flag_button.gif)
There are four parameters `gr.Interface` that control how flagging works. We will go over them in greater detail.
* `allow_flagging`: this parameter can be set to either `"manual"`, `"auto"`, or `"never"`.
* `manual`: users will see a button to flag, and events are only flagged when it's clicked.
* `auto`: users will not see a button to flag, but every event will be flagged automatically.
* `never`: users will not see a button to flag, and no event will be flagged.
* `flagging_options`: this parameter can be either `None` (default) or a list of strings.
* If `None`, then the user simply clicks on the **Flag** button and no additional options are shown.
* If a list of strings are provided, this allows user to select from a list of options when flagging. Only applies if `allow_flagging` is `"manual"`.
* The chosen option is then piped along with the input and output.
* `flagging_dir`: this parameter takes a string.
* It represents what to name the directory where flagged data is stored.
* `flagging_callback`: this parameter takes an instance of a subclass of the `FlaggingCallback` class
* Using this parameter allows you to write custom code that gets run when the flag button is clicked
* By default, this is set to an instance of `gr.CSVLogger`
* One example is setting it to an instance of `gr.HuggingFaceDatasetSaver` which can allow you to pipe any flagged data into a HuggingFace Dataset.
## What happens to flagged data?
Within the directory provided by the `flagging_dir` argument, a CSV file will log the flagged data.
Here's an example: The code below creates the calculator interface embedded below it:
```python
import gradio as gr
def calculator(num1, operation, num2):
if operation == "add":
return num1 + num2
elif operation == "subtract":
return num1 - num2
elif operation == "multiply":
return num1 * num2
elif operation == "divide":
return num1 / num2
iface = gr.Interface(
calculator,
["number", gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
"number",
allow_flagging="manual"
)
iface.launch()
```
<iframe src="https://hf.space/embed/aliabd/calculator-flag-basic/+" frameBorder="0" height="500" title="Gradio app" class="container p-0 flex-grow space-iframe" allow="accelerometer; ambient-light-sensor; autoplay; battery; camera; document-domain; encrypted-media; fullscreen; geolocation; gyroscope; layout-animations; legacy-image-formats; magnetometer; microphone; midi; oversized-images; payment; picture-in-picture; publickey-credentials-get; sync-xhr; usb; vr ; wake-lock; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-downloads"></iframe>
When you click the flag button above, the directory where the interface was launched will include a new flagged subfolder, with a csv file inside it. This csv file includes all the data that was flagged.
```directory
+-- flagged/
| +-- logs.csv
```
_flagged/logs.csv_
```csv
num1,operation,num2,Output,timestamp
5,add,7,12,2022-01-31 11:40:51.093412
6,subtract,1.5,4.5,2022-01-31 03:25:32.023542
```
If the interface involves file data, such as for Image and Audio components, folders will be created to store those flagged data as well. For example an `image` input to `image` output interface will create the following structure.
```directory
+-- flagged/
| +-- logs.csv
| +-- image/
| | +-- 0.png
| | +-- 1.png
| +-- Output/
| | +-- 0.png
| | +-- 1.png
```
_flagged/logs.csv_
```csv
im,Output timestamp
im/0.png,Output/0.png,2022-02-04 19:49:58.026963
im/1.png,Output/1.png,2022-02-02 10:40:51.093412
```
If you wish for the user to provide a reason for flagging, you can pass a list of strings to the `flagging_options` argument of Interface. Users will have to select one of the strings when flagging, which will be saved as an additional column to the CSV.
If we go back to the calculator example, the following code will create the interface embedded below it.
```python
iface = gr.Interface(
calculator,
["number", gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
"number",
allow_flagging="manual",
flagging_options=["wrong sign", "off by one", "other"]
)
iface.launch()
```
<iframe src="https://hf.space/embed/aliabd/calculator-flagging-options/+" frameBorder="0" height="500" title="Gradio app" class="container p-0 flex-grow space-iframe" allow="accelerometer; ambient-light-sensor; autoplay; battery; camera; document-domain; encrypted-media; fullscreen; geolocation; gyroscope; layout-animations; legacy-image-formats; magnetometer; microphone; midi; oversized-images; payment; picture-in-picture; publickey-credentials-get; sync-xhr; usb; vr ; wake-lock; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-downloads"></iframe>
When users click the flag button, the csv file will now include a column indicating the selected option.
_flagged/logs.csv_
```csv
num1,operation,num2,Output,flag,timestamp
5,add,7,-12,wrong sign,2022-02-04 11:40:51.093412
6,subtract,1.5,3.5,off by one,2022-02-04 11:42:32.062512
```
## Doing more with the data
Suppose you want to take some action on the flagged data, instead of just saving it. Perhaps you want to trigger your model to retrain, or even just share it with others in a cloud dataset. We've made this super easy with the `flagging_callback` parameter.
For example, below we're going to pipe flagged data from our calculator example into a crowd-sourced Hugging Face Dataset.
```python
import os
HF_TOKEN = os.getenv('HF_TOKEN')
hf_writer = gr.HuggingFaceDatasetSaver(HF_TOKEN, "crowdsourced-calculator-demo")
iface = gr.Interface(
calculator,
["number", gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
"number",
allow_flagging="manual",
flagging_options=["wrong sign", "off by one", "other"],
flagging_callback=hf_writer
)
iface.launch()
```
<iframe src="https://hf.space/embed/aliabd/calculator-flagging-crowdsourced/+" frameBorder="0" height="500" title="Gradio app" class="container p-0 flex-grow space-iframe" allow="accelerometer; ambient-light-sensor; autoplay; battery; camera; document-domain; encrypted-media; fullscreen; geolocation; gyroscope; layout-animations; legacy-image-formats; magnetometer; microphone; midi; oversized-images; payment; picture-in-picture; publickey-credentials-get; sync-xhr; usb; vr ; wake-lock; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-downloads"></iframe>
You can now see all the examples flagged above in this [public HF dataset](https://huggingface.co/datasets/aliabd/crowdsourced-calculator-demo/blob/main/data.csv).
![flagging callback hf](/assets/guides/flagging-callback-hf.png)
We created the `gr.HuggingFaceDatasetSaver` class, but you can pass your own custom class as long as it inherits from `FLaggingCallback` defined in [this file](https://github.com/gradio-app/gradio/blob/master/gradio/flagging.py). If you create a cool callback, please contribute it to the repo!
## Privacy
Please make sure your users understand when the data they submit is being saved, and what you plan on doing with it. This is especially important when you use `allow_flagging=auto`. We suggest including this info in the description so that it's read before the interface.
### That's all! Happy building :)

View File

@ -37,7 +37,6 @@ def format_name(guide_name):
guide_folders = sorted(os.listdir(GUIDES_DIR))
guide_folders.remove("CONTRIBUTING.md")
guide_folders.remove("etc")
guide_folders.remove("assets")
guides = []

View File

@ -13,12 +13,16 @@
<div class="side-navigation h-screen leading-relaxed sticky top-0 text-md overflow-y-auto overflow-x-hidden hidden lg:block rounded-t-xl bg-gradient-to-r from-white to-gray-50"
style="min-width: 18%">
{% for category_guides in guides_by_category %}
{% set hidden_category = loop.last and category != category_guides["category"] %}
<div class="category-link {% if loop.first %} mb-2 {% else %} my-2 {% endif %} font-semibold px-4 pt-2 text-ellipsis whitespace-nowrap block"
style="max-width: 12rem">
{{ category_guides["category"] }}
{% if hidden_category %}
<button class="block show-guides" onclick="show_all_guides()"> [ show ] </button>
{% endif %}
</div>
{% for guide in category_guides["guides"] %}
<a class="guide-link {% if name == guide['name'] %} current-nav-link pb-1{% endif %} -indent-2 ml-2 thin-link px-4 block overflow-hidden"
<a class="guide-link {% if name == guide['name'] %} current-nav-link pb-1{% endif %} {% if hidden_category %} hidden {% endif %} -indent-2 ml-2 thin-link px-4 block overflow-hidden"
style="max-width: 12rem"
href="{{ guide['url'] }}">{{ guide['pretty_name'] }}</a>
{% if name == guide['name'] %}
@ -88,6 +92,10 @@
const color = COLORS[Math.floor(Math.random() * COLORS.length)]
guide.classList.add(color);
})
const show_all_guides = () => {
document.querySelectorAll(".guide-link").forEach(g => g.classList.remove("hidden"));
document.querySelector(".show-guides").remove();
}
</script>
<script>{% include 'templates/links.js' %}</script>
</body>