merge conflict on auto datatype

This commit is contained in:
Ali Abid 2020-09-02 09:20:24 -07:00
commit 2d869105ca
26 changed files with 272 additions and 108 deletions

View File

@ -15,17 +15,19 @@ import base64
import numpy as np import numpy as np
import PIL import PIL
import scipy.io.wavfile import scipy.io.wavfile
from gradio import processing_utils from gradio import processing_utils, test_data
import pandas as pd import pandas as pd
import math import math
import tempfile import tempfile
class InputComponent(Component): class InputComponent(Component):
""" """
Input Component. All input components subclass this. Input Component. All input components subclass this.
""" """
pass pass
class Textbox(InputComponent): class Textbox(InputComponent):
""" """
Component creates a textbox for user to enter input. Provides a string (or number is `type` is "float") as an argument to the wrapped function. Component creates a textbox for user to enter input. Provides a string (or number is `type` is "float") as an argument to the wrapped function.
@ -33,7 +35,7 @@ class Textbox(InputComponent):
""" """
def __init__(self, lines=1, placeholder=None, default=None, numeric=False, type="str", label=None): def __init__(self, lines=1, placeholder=None, default=None, numeric=False, type="str", label=None):
''' """
Parameters: Parameters:
lines (int): number of line rows to provide in textarea. lines (int): number of line rows to provide in textarea.
placeholder (str): placeholder hint to provide behind textarea. placeholder (str): placeholder hint to provide behind textarea.
@ -41,7 +43,7 @@ class Textbox(InputComponent):
numeric (bool): DEPRECATED. Whether the input should be parsed as a number instead of a string. numeric (bool): DEPRECATED. Whether the input should be parsed as a number instead of a string.
type (str): Type of value to be returned by component. "str" returns a string, "number" returns a float value. type (str): Type of value to be returned by component. "str" returns a string, "number" returns a float value.
label (str): component name in interface. label (str): component name in interface.
''' """
self.lines = lines self.lines = lines
self.placeholder = placeholder self.placeholder = placeholder
self.default = default self.default = default
@ -50,6 +52,13 @@ class Textbox(InputComponent):
self.type = "number" self.type = "number"
else: else:
self.type = type self.type = type
if default is None:
self.test_input = {
"str": "the quick brown fox jumped over the lazy dog",
"number": 786.92,
}[type]
else:
self.test_input = default
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -77,7 +86,6 @@ class Textbox(InputComponent):
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'str', 'number'.") raise ValueError("Unknown type: " + self.type + ". Please choose from: 'str', 'number'.")
class Slider(InputComponent): class Slider(InputComponent):
""" """
Component creates a slider that ranges from `minimum` to `maximum`. Provides a number as an argument to the wrapped function. Component creates a slider that ranges from `minimum` to `maximum`. Provides a number as an argument to the wrapped function.
@ -101,6 +109,7 @@ class Slider(InputComponent):
step = 10 ** power step = 10 ** power
self.step = step self.step = step
self.default = minimum if default is None else default self.default = minimum if default is None else default
self.test_input = self.default
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -126,10 +135,11 @@ class Checkbox(InputComponent):
""" """
def __init__(self, label=None): def __init__(self, label=None):
''' """
Parameters: Parameters:
label (str): component name in interface. label (str): component name in interface.
''' """
self.test_input = True
super().__init__(label) super().__init__(label)
@classmethod @classmethod
@ -154,6 +164,7 @@ class CheckboxGroup(InputComponent):
''' '''
self.choices = choices self.choices = choices
self.type = type self.type = type
self.test_input = self.choices
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -186,6 +197,7 @@ class Radio(InputComponent):
''' '''
self.choices = choices self.choices = choices
self.type = type self.type = type
self.test_input = self.choices[0]
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -202,6 +214,7 @@ class Radio(InputComponent):
else: else:
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'value', 'index'.") raise ValueError("Unknown type: " + self.type + ". Please choose from: 'value', 'index'.")
class Dropdown(InputComponent): class Dropdown(InputComponent):
""" """
Component creates a dropdown of which only one can be selected. Provides string representing selected choice as an argument to the wrapped function. Component creates a dropdown of which only one can be selected. Provides string representing selected choice as an argument to the wrapped function.
@ -217,6 +230,7 @@ class Dropdown(InputComponent):
''' '''
self.choices = choices self.choices = choices
self.type = type self.type = type
self.test_input = self.choices[0]
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -248,7 +262,7 @@ class Image(InputComponent):
invert_colors (bool): whether to invert the image as a preprocessing step. invert_colors (bool): whether to invert the image as a preprocessing step.
source (str): Source of image. "upload" creates a box where user can drop an image file, "webcam" allows user to take snapshot from their webcam, "canvas" defaults to a white image that can be edited and drawn upon with tools. source (str): Source of image. "upload" creates a box where user can drop an image file, "webcam" allows user to take snapshot from their webcam, "canvas" defaults to a white image that can be edited and drawn upon with tools.
tool (str): Tools used for editing. "editor" allows a full screen editor, "select" provides a cropping and zoom tool. tool (str): Tools used for editing. "editor" allows a full screen editor, "select" provides a cropping and zoom tool.
type (str): Type of value to be returned by component. "numpy" returns a numpy array with shape (width, height, 3), "pil" returns a PIL image object, "file" returns a temporary file object whose path can be retrieved by file_obj.name. type (str): Type of value to be returned by component. "numpy" returns a numpy array with shape (width, height, 3) and values from 0 to 255, "pil" returns a PIL image object, "file" returns a temporary file object whose path can be retrieved by file_obj.name.
label (str): component name in interface. label (str): component name in interface.
''' '''
self.shape = shape self.shape = shape
@ -257,6 +271,7 @@ class Image(InputComponent):
self.tool = tool self.tool = tool
self.type = type self.type = type
self.invert_colors = invert_colors self.invert_colors = invert_colors
self.test_input = test_data.BASE64_IMAGE
super().__init__(label) super().__init__(label)
@classmethod @classmethod
@ -293,6 +308,8 @@ class Image(InputComponent):
file_obj = tempfile.NamedTemporaryFile() file_obj = tempfile.NamedTemporaryFile()
im.save(file_obj.name) im.save(file_obj.name)
return file_obj return file_obj
else:
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'numpy', 'pil', 'file'.")
def rebuild(self, dir, data): def rebuild(self, dir, data):
""" """
@ -312,14 +329,15 @@ class Audio(InputComponent):
""" """
def __init__(self, source="upload", type="numpy", label=None): def __init__(self, source="upload", type="numpy", label=None):
''' """
Parameters: Parameters:
source (str): Source of audio. "upload" creates a box where user can drop an audio file, "microphone" creates a microphone input. source (str): Source of audio. "upload" creates a box where user can drop an audio file, "microphone" creates a microphone input.
type (str): Type of value to be returned by component. "numpy" returns a 2-set tuple with an integer sample_rate and the data numpy.array of shape (samples, 2), "file" returns a temporary file object whose path can be retrieved by file_obj.name, "mfcc" returns the mfcc coefficients of the input audio. type (str): Type of value to be returned by component. "numpy" returns a 2-set tuple with an integer sample_rate and the data numpy.array of shape (samples, 2), "file" returns a temporary file object whose path can be retrieved by file_obj.name, "mfcc" returns the mfcc coefficients of the input audio.
label (str): component name in interface. label (str): component name in interface.
''' """
self.source = source self.source = source
self.type = type self.type = type
self.test_input = test_data.BASE64_AUDIO
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -361,6 +379,7 @@ class File(InputComponent):
label (str): component name in interface. label (str): component name in interface.
''' '''
self.type = type self.type = type
self.test_input = None
super().__init__(label) super().__init__(label)
@classmethod @classmethod
@ -385,7 +404,7 @@ class Dataframe(InputComponent):
""" """
def __init__(self, headers=None, row_count=3, col_count=3, datatype="str", type="pandas", label=None): def __init__(self, headers=None, row_count=3, col_count=3, datatype="str", type="pandas", label=None):
''' """
Parameters: Parameters:
headers (List[str]): Header names to dataframe. headers (List[str]): Header names to dataframe.
row_count (int): Limit number of rows for input. row_count (int): Limit number of rows for input.
@ -393,14 +412,17 @@ class Dataframe(InputComponent):
datatype (Union[str, List[str]]): Datatype of values in sheet. Can be provided per column as a list of strings, or for the entire sheet as a single string. Valid datatypes are "str", "number", "bool", and "date". datatype (Union[str, List[str]]): Datatype of values in sheet. Can be provided per column as a list of strings, or for the entire sheet as a single string. Valid datatypes are "str", "number", "bool", and "date".
type (str): Type of value to be returned by component. "pandas" for pandas dataframe, "numpy" for numpy array, or "array" for a Python array. type (str): Type of value to be returned by component. "pandas" for pandas dataframe, "numpy" for numpy array, or "array" for a Python array.
label (str): component name in interface. label (str): component name in interface.
''' """
self.headers = headers self.headers = headers
self.datatype = datatype self.datatype = datatype
self.row_count = row_count self.row_count = row_count
self.col_count = len(headers) if headers else col_count self.col_count = len(headers) if headers else col_count
self.type = type self.type = type
super().__init__(label) sample_values = {"str": "abc", "number": 786, "bool": True, "date": "02/08/1993"}
column_dtypes = [datatype]*self.col_count if isinstance(datatype, str) else datatype
self.test_input = [[sample_values[c] for c in column_dtypes] for _ in range(row_count)]
super().__init__(label)
def get_template_context(self): def get_template_context(self):
return { return {

View File

@ -193,19 +193,19 @@ class Interface:
return config return config
def process(self, raw_input): def process(self, raw_input, predict_fn=None):
""" """
:param raw_input: a list of raw inputs to process and apply the :param raw_input: a list of raw inputs to process and apply the
prediction(s) on. prediction(s) on.
:param predict_fn: which function to process. If not provided, all of the model functions are used.
:return: :return:
processed output: a list of processed outputs to return as the processed output: a list of processed outputs to return as the
prediction(s). prediction(s).
duration: a list of time deltas measuring inference time for each duration: a list of time deltas measuring inference time for each
prediction fn. prediction fn.
""" """
processed_input = [input_interface.preprocess( processed_input = [input_interface.preprocess(raw_input[i])
raw_input[i]) for i, input_interface in for i, input_interface in enumerate(self.input_interfaces)]
enumerate(self.input_interfaces)]
predictions = [] predictions = []
durations = [] durations = []
for predict_fn in self.predict: for predict_fn in self.predict:
@ -253,6 +253,22 @@ class Interface:
thread.keep_running = False thread.keep_running = False
networking.url_ok(path_to_local_server) networking.url_ok(path_to_local_server)
def test_launch(self):
for predict_fn in self.predict:
print("Test launching: {}()...".format(predict_fn.__name__), end=' ')
raw_input = []
for input_interface in self.input_interfaces:
if input_interface.test_input is None: # If no test input is defined for that input interface
print("SKIPPED")
break
else: # If a test input is defined for each interface object
raw_input.append(input_interface.test_input)
else:
self.process(raw_input)
print("PASSED")
continue
def launch(self, inline=None, inbrowser=None, share=False, debug=False): def launch(self, inline=None, inbrowser=None, share=False, debug=False):
""" """
Parameters Parameters
@ -326,6 +342,8 @@ class Interface:
if self.verbose: if self.verbose:
print(strings.en["COLAB_NO_LOCAL"]) print(strings.en["COLAB_NO_LOCAL"])
else: # If it's not a colab notebook and share=False, print a message telling them about the share option. else: # If it's not a colab notebook and share=False, print a message telling them about the share option.
print("To get a public link for a hosted model, "
"set Share=True")
if self.verbose: if self.verbose:
print(strings.en["PUBLIC_SHARE_TRUE"]) print(strings.en["PUBLIC_SHARE_TRUE"])
share_url = None share_url = None
@ -345,10 +363,10 @@ class Interface:
# with the interface. # with the interface.
if inline: if inline:
from IPython.display import IFrame, display from IPython.display import IFrame, display
if (is_colab): # Embed the remote interface page if on google colab;
# Embed the remote interface page if on google colab; # otherwise, embed the local page.
# otherwise, embed the local page. print("Interface loading below...")
print("Interface loading below...") if share:
while not networking.url_ok(share_url): while not networking.url_ok(share_url):
time.sleep(1) time.sleep(1)
display(IFrame(share_url, width=1000, height=500)) display(IFrame(share_url, width=1000, height=500))

View File

@ -32,7 +32,6 @@ def encode_plot_to_base64(plt):
with BytesIO() as output_bytes: with BytesIO() as output_bytes:
plt.savefig(output_bytes, format="png") plt.savefig(output_bytes, format="png")
bytes_data = output_bytes.getvalue() bytes_data = output_bytes.getvalue()
plt.close()
base64_str = str(base64.b64encode(bytes_data), 'utf-8') base64_str = str(base64.b64encode(bytes_data), 'utf-8')
return "data:image/png;base64," + base64_str return "data:image/png;base64," + base64_str

File diff suppressed because one or more lines are too long

View File

@ -3,13 +3,15 @@
import gradio as gr import gradio as gr
from difflib import Differ from difflib import Differ
def diff_texts(text1, text2): def diff_texts(text1, text2):
d = Differ() d = Differ()
return [ return [
(token[2:], token[0]) for token in d.compare(text1, text2) (token[2:], token[0]) for token in d.compare(text1, text2)
] ]
gr.Interface(
io = gr.Interface(
diff_texts, diff_texts,
[ [
gr.inputs.Textbox(lines=3, default="The quick brown fox jumped over the lazy dogs."), gr.inputs.Textbox(lines=3, default="The quick brown fox jumped over the lazy dogs."),
@ -20,4 +22,7 @@ gr.Interface(
"-": "pink", "-": "pink",
" ": "none", " ": "none",
}) })
).launch() )
io.test_launch()
io.launch()

View File

@ -2,24 +2,26 @@
import tensorflow as tf import tensorflow as tf
import gradio import gradio
import os
from tensorflow.keras.layers import *
import gradio as gr import gradio as gr
from urllib.request import urlretrieve from urllib.request import urlretrieve
urlretrieve("https://gr-models.s3-us-west-2.amazonaws.com/mnist-model.h5", "mnist-model.h5") urlretrieve("https://gr-models.s3-us-west-2.amazonaws.com/mnist-model.h5", "mnist-model.h5")
model = tf.keras.models.load_model("mnist-model.h5") model = tf.keras.models.load_model("mnist-model.h5")
def recognize_digit(image): def recognize_digit(image):
image = image.reshape(1, -1) image = image.reshape(1, -1)
prediction = model.predict(image).tolist()[0] prediction = model.predict(image).tolist()[0]
return {str(i): prediction[i] for i in range(10)} return {str(i): prediction[i] for i in range(10)}
gr.Interface( io = gr.Interface(
recognize_digit, recognize_digit,
"sketchpad", "sketchpad",
gradio.outputs.Label(num_top_classes=3), gradio.outputs.Label(num_top_classes=3),
live=True, live=True,
capture_session=True, capture_session=True,
).launch() )
io.test_launch()
io.launch()

View File

@ -7,11 +7,14 @@ import random
def filter_records(records, gender): def filter_records(records, gender):
return records[records['gender'] == gender] return records[records['gender'] == gender]
gr.Interface(filter_records, io = gr.Interface(filter_records,
[ [
gr.inputs.Dataframe(headers=["name", "age", "gender"], datatype=["str", "number", "str"], row_count=5), gr.inputs.Dataframe(headers=["name", "age", "gender"], datatype=["str", "number", "str"], row_count=5),
gr.inputs.Dropdown(["M", "F", "O"]) gr.inputs.Dropdown(["M", "F", "O"])
], ],
"dataframe", "dataframe",
description="Enter gender as 'M', 'F', or 'O' for other." description="Enter gender as 'M', 'F', or 'O' for other."
).launch() )
io.test_launch()
io.launch()

35
demo/form_graph.py Normal file
View File

@ -0,0 +1,35 @@
import gradio as gr
import random
import matplotlib.pyplot as plt
import numpy as np
def plot_forecast(final_year, companies, noise, show_legend, point_style):
start_year = 2020
x = np.arange(start_year, final_year + 1)
year_count = x.shape[0]
plt_format = ({"cross": "X", "line": "-", "circle": "o--"})[point_style]
fig = plt.figure()
ax = fig.add_subplot(1)
for i, company in enumerate(companies):
series = np.arange(0, year_count, dtype=float)
series = series ** 2 * (i + 1)
series += np.random.rand(year_count) * noise
ax.plot(x, series, plt_format)
if show_legend:
plt.legend(companies)
return fig
gr.Interface(plot_forecast,
[
gr.inputs.Radio([2025, 2030, 2035, 2040],
label="Project to:"),
gr.inputs.CheckboxGroup(
["Google", "Microsoft", "Gradio"], label="Company Selection"),
gr.inputs.Slider(1, 100, label="Noise Level"),
gr.inputs.Checkbox(label="Show Legend"),
gr.inputs.Dropdown(["cross", "line", "circle"], label="Style"),
],
gr.outputs.Image(plot=True, label="forecast")
).launch()

View File

@ -2,10 +2,10 @@
import gradio as gr import gradio as gr
import numpy as np import numpy as np
import random
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
def generate_tone(note, octave, duration): def generate_tone(note, octave, duration):
sr = 48000 sr = 48000
a4_freq, tones_from_a4 = 440, 12 * (octave - 4) + (note - 9) a4_freq, tones_from_a4 = 440, 12 * (octave - 4) + (note - 9)
@ -13,13 +13,16 @@ def generate_tone(note, octave, duration):
duration = int(duration) duration = int(duration)
audio = np.linspace(0, duration, duration * sr) audio = np.linspace(0, duration, duration * sr)
audio = (20000 * np.sin(audio * (2 * np.pi * frequency))).astype(np.int16) audio = (20000 * np.sin(audio * (2 * np.pi * frequency))).astype(np.int16)
return (sr, audio) return sr, audio
gr.Interface( io = gr.Interface(
generate_tone, generate_tone,
[ [
gr.inputs.Dropdown(notes, type="index"), gr.inputs.Dropdown(notes, type="index"),
gr.inputs.Slider(4, 6, step=1), gr.inputs.Slider(4, 6, step=1),
gr.inputs.Textbox(type="number", default=1, label="Duration in seconds") gr.inputs.Textbox(type="number", default=1, label="Duration in seconds")
], "audio").launch() ], "audio")
io.test_launch()
io.launch()

View File

@ -1,15 +1,13 @@
# Demo: (Image) -> (Image) # Demo: (Image) -> (Image)
import gradio as gr import gradio as gr
from time import time
from PIL import Image
def image_mod(image): def image_mod(image):
return image.rotate(45) return image.rotate(45)
gr.Interface(image_mod, io = gr.Interface(image_mod,
gr.inputs.Image(type="pil"), gr.inputs.Image(type="pil"),
"image", "image",
examples=[ examples=[
@ -17,4 +15,8 @@ gr.Interface(image_mod,
["images/cheetah2.jpg"], ["images/cheetah2.jpg"],
["images/lion.jpg"], ["images/lion.jpg"],
], ],
).launch(share=True) live=True,
)
io.test_launch()
io.launch()

View File

@ -1,13 +1,17 @@
# Demo: (Dataframe) -> (Dataframe) # Demo: (Dataframe) -> (Dataframe)
import gradio as gr import gradio as gr
import numpy as np
import random
def transpose(matrix): def transpose(matrix):
return matrix.T return matrix.T
gr.Interface(transpose,
gr.inputs.Dataframe(type="numpy", datatype="number", row_count=5, col_count=3), io = gr.Interface(
"numpy" transpose,
).launch() gr.inputs.Dataframe(type="numpy", datatype="number", row_count=5, col_count=3),
"numpy"
)
io.test_launch()
io.launch()

View File

@ -2,10 +2,14 @@
import gradio as gr import gradio as gr
import numpy as np import numpy as np
import random
def reverse_audio(audio): def reverse_audio(audio):
sr, data = audio sr, data = audio
return (sr, np.flipud(data)) return (sr, np.flipud(data))
gr.Interface(reverse_audio, "microphone", "audio").launch()
io = gr.Interface(reverse_audio, "microphone", "audio")
io.test_launch()
io.launch()

View File

@ -1,25 +1,28 @@
# Demo: (Slider, Dropdown, Radio, CheckboxGroup, Checkbox) -> (Textbox) # Demo: (Slider, Dropdown, Radio, CheckboxGroup, Checkbox) -> (Textbox)
import gradio as gr import gradio as gr
import numpy as np
def sentence_builder(quantity, animal, place, activity_list, morning): def sentence_builder(quantity, animal, place, activity_list, morning):
return f"""The {quantity} {animal}s went to the {place} where they {" and ".join(activity_list)} until the {"morning" if morning else "night"}""" return f"""The {quantity} {animal}s went to the {place} where they {" and ".join(activity_list)} until the {"morning" if morning else "night"}"""
gr.Interface(sentence_builder, io = gr.Interface(
[ sentence_builder,
gr.inputs.Slider(2, 20), [
gr.inputs.Dropdown(["cat", "dog", "bird"]), gr.inputs.Slider(2, 20),
gr.inputs.Radio(["park", "zoo", "road"]), gr.inputs.Dropdown(["cat", "dog", "bird"]),
gr.inputs.CheckboxGroup(["ran", "swam", "ate", "slept"]), gr.inputs.Radio(["park", "zoo", "road"]),
gr.inputs.Checkbox(label="Is it the morning?"), gr.inputs.CheckboxGroup(["ran", "swam", "ate", "slept"]),
], gr.inputs.Checkbox(label="Is it the morning?"),
"text", ],
examples=[ "text",
[2, "cat", "park", ["ran", "swam"], True], examples=[
[4, "dog", "zoo", ["ate", "swam"], False], [2, "cat", "park", ["ran", "swam"], True],
[10, "bird", "road", ["ran"], False], [4, "dog", "zoo", ["ate", "swam"], False],
[8, "cat", "zoo", ["ate"], True], [10, "bird", "road", ["ran"], False],
], [8, "cat", "zoo", ["ate"], True],
).launch() ])
io.test_launch()
io.launch()

View File

@ -4,7 +4,6 @@ import gradio as gr
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from scipy import signal from scipy import signal
from scipy.io import wavfile
def spectrogram(audio): def spectrogram(audio):
@ -15,4 +14,7 @@ def spectrogram(audio):
return plt return plt
gr.Interface(spectrogram, "audio", "plot").launch() io = gr.Interface(spectrogram, "audio", "plot
io.test_launch()
io.launch()

View File

@ -1,7 +1,6 @@
# Demo: (Radio, CheckboxGroup, Slider, Checkbox, Dropdown) -> (Image) # Demo: (Radio, CheckboxGroup, Slider, Checkbox, Dropdown) -> (Image)
import gradio as gr import gradio as gr
import random
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
@ -21,15 +20,15 @@ def stock_forecast(final_year, companies, noise, show_legend, point_style):
return plt return plt
gr.Interface(stock_forecast, io = gr.Interface(
[ stock_forecast,
gr.inputs.Radio([2025, 2030, 2035, 2040], [
label="Project to:"), gr.inputs.Radio([2025, 2030, 2035, 2040], label="Project to:"),
gr.inputs.CheckboxGroup( gr.inputs.CheckboxGroup(["Google", "Microsoft", "Gradio"]),
["Google", "Microsoft", "Gradio"]), gr.inputs.Slider(1, 100),
gr.inputs.Slider(1, 100), "checkbox",
"checkbox", gr.inputs.Dropdown(["cross", "line", "circle"], label="Style")],
gr.inputs.Dropdown(["cross", "line", "circle"], label="Style"), gr.outputs.Image(plot=True, label="forecast"))
],
gr.outputs.Image(plot=True, label="forecast") io.test_launch()
).launch() io.launch()

View File

@ -6,6 +6,7 @@ import gradio as gr
nlp = spacy.load("en_core_web_sm") nlp = spacy.load("en_core_web_sm")
def text_analysis(text): def text_analysis(text):
doc = nlp(text) doc = nlp(text)
html = displacy.render(doc, style="dep", page=True) html = displacy.render(doc, style="dep", page=True)
@ -21,10 +22,14 @@ def text_analysis(text):
return pos_tokens, pos_count, html return pos_tokens, pos_count, html
gr.Interface(
io = gr.Interface(
text_analysis, text_analysis,
gr.inputs.Textbox(placeholder="Enter sentence here..."), gr.inputs.Textbox(placeholder="Enter sentence here..."),
[ [
"highlight", "key_values", "html" "highlight", "key_values", "html"
] ]
).launch() )
io.test_launch()
io.launch()

View File

@ -1,9 +1,13 @@
# Demo: (Image) -> (Image) # Demo: (Image) -> (Image)
import gradio as gr import gradio as gr
import numpy as np
def snap(image): def snap(image):
return np.flipud(image) return np.flipud(image)
gr.Interface(snap, gr.inputs.Image(shape=(100,100), image_mode="L", source="webcam"), "image").launch()
io = gr.Interface(snap, gr.inputs.Image(shape=(100,100), image_mode="L", source="webcam"), "image")
io.test_launch()
io.launch()

View File

@ -3,6 +3,7 @@
import gradio as gr import gradio as gr
from zipfile import ZipFile from zipfile import ZipFile
def zip_to_json(file_obj): def zip_to_json(file_obj):
files = [] files = []
with ZipFile(file_obj.name) as zfile: with ZipFile(file_obj.name) as zfile:
@ -14,4 +15,8 @@ def zip_to_json(file_obj):
}) })
return files return files
gr.Interface(zip_to_json, "file", "json").launch()
io = gr.Interface(zip_to_json, "file", "json")
io.test_launch()
io.launch()

View File

@ -3,10 +3,15 @@
import gradio as gr import gradio as gr
from zipfile import ZipFile from zipfile import ZipFile
def zip_two_files(file1, file2): def zip_two_files(file1, file2):
with ZipFile('tmp.zip', 'w') as zipObj: with ZipFile('tmp.zip', 'w') as zipObj:
zipObj.write(file1.name, "file1") zipObj.write(file1.name, "file1")
zipObj.write(file2.name, "file2") zipObj.write(file2.name, "file2")
return "tmp.zip" return "tmp.zip"
gr.Interface(zip_two_files, ["file", "file"], "file").launch()
io = gr.Interface(zip_two_files, ["file", "file"], "file")
io.test_launch()
io.launch()

View File

@ -1,6 +1,6 @@
Metadata-Version: 1.0 Metadata-Version: 1.0
Name: gradio Name: gradio
Version: 1.1.7 Version: 1.1.9
Summary: Python library for easily interacting with trained machine learning models Summary: Python library for easily interacting with trained machine learning models
Home-page: https://github.com/gradio-app/gradio-UI Home-page: https://github.com/gradio-app/gradio-UI
Author: Abubakar Abid Author: Abubakar Abid

View File

@ -9,6 +9,7 @@ gradio/networking.py
gradio/outputs.py gradio/outputs.py
gradio/processing_utils.py gradio/processing_utils.py
gradio/strings.py gradio/strings.py
gradio/test_data.py
gradio/tunneling.py gradio/tunneling.py
gradio/utils.py gradio/utils.py
gradio.egg-info/PKG-INFO gradio.egg-info/PKG-INFO

View File

@ -15,17 +15,19 @@ import base64
import numpy as np import numpy as np
import PIL import PIL
import scipy.io.wavfile import scipy.io.wavfile
from gradio import processing_utils from gradio import processing_utils, test_data
import pandas as pd import pandas as pd
import math import math
import tempfile import tempfile
class InputComponent(Component): class InputComponent(Component):
""" """
Input Component. All input components subclass this. Input Component. All input components subclass this.
""" """
pass pass
class Textbox(InputComponent): class Textbox(InputComponent):
""" """
Component creates a textbox for user to enter input. Provides a string (or number is `type` is "float") as an argument to the wrapped function. Component creates a textbox for user to enter input. Provides a string (or number is `type` is "float") as an argument to the wrapped function.
@ -33,7 +35,7 @@ class Textbox(InputComponent):
""" """
def __init__(self, lines=1, placeholder=None, default=None, numeric=False, type="str", label=None): def __init__(self, lines=1, placeholder=None, default=None, numeric=False, type="str", label=None):
''' """
Parameters: Parameters:
lines (int): number of line rows to provide in textarea. lines (int): number of line rows to provide in textarea.
placeholder (str): placeholder hint to provide behind textarea. placeholder (str): placeholder hint to provide behind textarea.
@ -41,7 +43,7 @@ class Textbox(InputComponent):
numeric (bool): DEPRECATED. Whether the input should be parsed as a number instead of a string. numeric (bool): DEPRECATED. Whether the input should be parsed as a number instead of a string.
type (str): Type of value to be returned by component. "str" returns a string, "number" returns a float value. type (str): Type of value to be returned by component. "str" returns a string, "number" returns a float value.
label (str): component name in interface. label (str): component name in interface.
''' """
self.lines = lines self.lines = lines
self.placeholder = placeholder self.placeholder = placeholder
self.default = default self.default = default
@ -50,6 +52,13 @@ class Textbox(InputComponent):
self.type = "number" self.type = "number"
else: else:
self.type = type self.type = type
if default is None:
self.test_input = {
"str": "the quick brown fox jumped over the lazy dog",
"number": 786.92,
}[type]
else:
self.test_input = default
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -77,7 +86,6 @@ class Textbox(InputComponent):
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'str', 'number'.") raise ValueError("Unknown type: " + self.type + ". Please choose from: 'str', 'number'.")
class Slider(InputComponent): class Slider(InputComponent):
""" """
Component creates a slider that ranges from `minimum` to `maximum`. Provides a number as an argument to the wrapped function. Component creates a slider that ranges from `minimum` to `maximum`. Provides a number as an argument to the wrapped function.
@ -101,6 +109,7 @@ class Slider(InputComponent):
step = 10 ** power step = 10 ** power
self.step = step self.step = step
self.default = minimum if default is None else default self.default = minimum if default is None else default
self.test_input = self.default
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -126,10 +135,11 @@ class Checkbox(InputComponent):
""" """
def __init__(self, label=None): def __init__(self, label=None):
''' """
Parameters: Parameters:
label (str): component name in interface. label (str): component name in interface.
''' """
self.test_input = True
super().__init__(label) super().__init__(label)
@classmethod @classmethod
@ -154,6 +164,7 @@ class CheckboxGroup(InputComponent):
''' '''
self.choices = choices self.choices = choices
self.type = type self.type = type
self.test_input = self.choices
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -186,6 +197,7 @@ class Radio(InputComponent):
''' '''
self.choices = choices self.choices = choices
self.type = type self.type = type
self.test_input = self.choices[0]
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -202,6 +214,7 @@ class Radio(InputComponent):
else: else:
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'value', 'index'.") raise ValueError("Unknown type: " + self.type + ". Please choose from: 'value', 'index'.")
class Dropdown(InputComponent): class Dropdown(InputComponent):
""" """
Component creates a dropdown of which only one can be selected. Provides string representing selected choice as an argument to the wrapped function. Component creates a dropdown of which only one can be selected. Provides string representing selected choice as an argument to the wrapped function.
@ -217,6 +230,7 @@ class Dropdown(InputComponent):
''' '''
self.choices = choices self.choices = choices
self.type = type self.type = type
self.test_input = self.choices[0]
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -248,7 +262,7 @@ class Image(InputComponent):
invert_colors (bool): whether to invert the image as a preprocessing step. invert_colors (bool): whether to invert the image as a preprocessing step.
source (str): Source of image. "upload" creates a box where user can drop an image file, "webcam" allows user to take snapshot from their webcam, "canvas" defaults to a white image that can be edited and drawn upon with tools. source (str): Source of image. "upload" creates a box where user can drop an image file, "webcam" allows user to take snapshot from their webcam, "canvas" defaults to a white image that can be edited and drawn upon with tools.
tool (str): Tools used for editing. "editor" allows a full screen editor, "select" provides a cropping and zoom tool. tool (str): Tools used for editing. "editor" allows a full screen editor, "select" provides a cropping and zoom tool.
type (str): Type of value to be returned by component. "numpy" returns a numpy array with shape (width, height, 3), "pil" returns a PIL image object, "file" returns a temporary file object whose path can be retrieved by file_obj.name. type (str): Type of value to be returned by component. "numpy" returns a numpy array with shape (width, height, 3) and values from 0 to 255, "pil" returns a PIL image object, "file" returns a temporary file object whose path can be retrieved by file_obj.name.
label (str): component name in interface. label (str): component name in interface.
''' '''
self.shape = shape self.shape = shape
@ -257,6 +271,7 @@ class Image(InputComponent):
self.tool = tool self.tool = tool
self.type = type self.type = type
self.invert_colors = invert_colors self.invert_colors = invert_colors
self.test_input = test_data.BASE64_IMAGE
super().__init__(label) super().__init__(label)
@classmethod @classmethod
@ -293,6 +308,8 @@ class Image(InputComponent):
file_obj = tempfile.NamedTemporaryFile() file_obj = tempfile.NamedTemporaryFile()
im.save(file_obj.name) im.save(file_obj.name)
return file_obj return file_obj
else:
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'numpy', 'pil', 'file'.")
def rebuild(self, dir, data): def rebuild(self, dir, data):
""" """
@ -312,14 +329,15 @@ class Audio(InputComponent):
""" """
def __init__(self, source="upload", type="numpy", label=None): def __init__(self, source="upload", type="numpy", label=None):
''' """
Parameters: Parameters:
source (str): Source of audio. "upload" creates a box where user can drop an audio file, "microphone" creates a microphone input. source (str): Source of audio. "upload" creates a box where user can drop an audio file, "microphone" creates a microphone input.
type (str): Type of value to be returned by component. "numpy" returns a 2-set tuple with an integer sample_rate and the data numpy.array of shape (samples, 2), "file" returns a temporary file object whose path can be retrieved by file_obj.name, "mfcc" returns the mfcc coefficients of the input audio. type (str): Type of value to be returned by component. "numpy" returns a 2-set tuple with an integer sample_rate and the data numpy.array of shape (samples, 2), "file" returns a temporary file object whose path can be retrieved by file_obj.name, "mfcc" returns the mfcc coefficients of the input audio.
label (str): component name in interface. label (str): component name in interface.
''' """
self.source = source self.source = source
self.type = type self.type = type
self.test_input = test_data.BASE64_AUDIO
super().__init__(label) super().__init__(label)
def get_template_context(self): def get_template_context(self):
@ -361,6 +379,7 @@ class File(InputComponent):
label (str): component name in interface. label (str): component name in interface.
''' '''
self.type = type self.type = type
self.test_input = None
super().__init__(label) super().__init__(label)
@classmethod @classmethod
@ -385,7 +404,7 @@ class Dataframe(InputComponent):
""" """
def __init__(self, headers=None, row_count=3, col_count=3, datatype="str", type="pandas", label=None): def __init__(self, headers=None, row_count=3, col_count=3, datatype="str", type="pandas", label=None):
''' """
Parameters: Parameters:
headers (List[str]): Header names to dataframe. headers (List[str]): Header names to dataframe.
row_count (int): Limit number of rows for input. row_count (int): Limit number of rows for input.
@ -393,14 +412,17 @@ class Dataframe(InputComponent):
datatype (Union[str, List[str]]): Datatype of values in sheet. Can be provided per column as a list of strings, or for the entire sheet as a single string. Valid datatypes are "str", "number", "bool", and "date". datatype (Union[str, List[str]]): Datatype of values in sheet. Can be provided per column as a list of strings, or for the entire sheet as a single string. Valid datatypes are "str", "number", "bool", and "date".
type (str): Type of value to be returned by component. "pandas" for pandas dataframe, "numpy" for numpy array, or "array" for a Python array. type (str): Type of value to be returned by component. "pandas" for pandas dataframe, "numpy" for numpy array, or "array" for a Python array.
label (str): component name in interface. label (str): component name in interface.
''' """
self.headers = headers self.headers = headers
self.datatype = datatype self.datatype = datatype
self.row_count = row_count self.row_count = row_count
self.col_count = len(headers) if headers else col_count self.col_count = len(headers) if headers else col_count
self.type = type self.type = type
super().__init__(label) sample_values = {"str": "abc", "number": 786, "bool": True, "date": "02/08/1993"}
column_dtypes = [datatype]*self.col_count if isinstance(datatype, str) else datatype
self.test_input = [[sample_values[c] for c in column_dtypes] for _ in range(row_count)]
super().__init__(label)
def get_template_context(self): def get_template_context(self):
return { return {

View File

@ -193,19 +193,19 @@ class Interface:
return config return config
def process(self, raw_input): def process(self, raw_input, predict_fn=None):
""" """
:param raw_input: a list of raw inputs to process and apply the :param raw_input: a list of raw inputs to process and apply the
prediction(s) on. prediction(s) on.
:param predict_fn: which function to process. If not provided, all of the model functions are used.
:return: :return:
processed output: a list of processed outputs to return as the processed output: a list of processed outputs to return as the
prediction(s). prediction(s).
duration: a list of time deltas measuring inference time for each duration: a list of time deltas measuring inference time for each
prediction fn. prediction fn.
""" """
processed_input = [input_interface.preprocess( processed_input = [input_interface.preprocess(raw_input[i])
raw_input[i]) for i, input_interface in for i, input_interface in enumerate(self.input_interfaces)]
enumerate(self.input_interfaces)]
predictions = [] predictions = []
durations = [] durations = []
for predict_fn in self.predict: for predict_fn in self.predict:
@ -253,6 +253,22 @@ class Interface:
thread.keep_running = False thread.keep_running = False
networking.url_ok(path_to_local_server) networking.url_ok(path_to_local_server)
def test_launch(self):
for predict_fn in self.predict:
print("Test launching: {}()...".format(predict_fn.__name__), end=' ')
raw_input = []
for input_interface in self.input_interfaces:
if input_interface.test_input is None: # If no test input is defined for that input interface
print("SKIPPED")
break
else: # If a test input is defined for each interface object
raw_input.append(input_interface.test_input)
else:
self.process(raw_input)
print("PASSED")
continue
def launch(self, inline=None, inbrowser=None, share=False, debug=False): def launch(self, inline=None, inbrowser=None, share=False, debug=False):
""" """
Parameters Parameters
@ -326,6 +342,8 @@ class Interface:
if self.verbose: if self.verbose:
print(strings.en["COLAB_NO_LOCAL"]) print(strings.en["COLAB_NO_LOCAL"])
else: # If it's not a colab notebook and share=False, print a message telling them about the share option. else: # If it's not a colab notebook and share=False, print a message telling them about the share option.
print("To get a public link for a hosted model, "
"set Share=True")
if self.verbose: if self.verbose:
print(strings.en["PUBLIC_SHARE_TRUE"]) print(strings.en["PUBLIC_SHARE_TRUE"])
share_url = None share_url = None
@ -345,10 +363,10 @@ class Interface:
# with the interface. # with the interface.
if inline: if inline:
from IPython.display import IFrame, display from IPython.display import IFrame, display
if (is_colab): # Embed the remote interface page if on google colab;
# Embed the remote interface page if on google colab; # otherwise, embed the local page.
# otherwise, embed the local page. print("Interface loading below...")
print("Interface loading below...") if share:
while not networking.url_ok(share_url): while not networking.url_ok(share_url):
time.sleep(1) time.sleep(1)
display(IFrame(share_url, width=1000, height=500)) display(IFrame(share_url, width=1000, height=500))

View File

@ -32,7 +32,6 @@ def encode_plot_to_base64(plt):
with BytesIO() as output_bytes: with BytesIO() as output_bytes:
plt.savefig(output_bytes, format="png") plt.savefig(output_bytes, format="png")
bytes_data = output_bytes.getvalue() bytes_data = output_bytes.getvalue()
plt.close()
base64_str = str(base64.b64encode(bytes_data), 'utf-8') base64_str = str(base64.b64encode(bytes_data), 'utf-8')
return "data:image/png;base64," + base64_str return "data:image/png;base64," + base64_str

2
gradio/test_data.py Normal file

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@ except ImportError:
setup( setup(
name='gradio', name='gradio',
version='1.1.7', version='1.1.9',
include_package_data=True, include_package_data=True,
description='Python library for easily interacting with trained machine learning models', description='Python library for easily interacting with trained machine learning models',
author='Abubakar Abid', author='Abubakar Abid',