2022-01-21 21:44:12 +08:00
|
|
|
import io
|
|
|
|
import sys
|
2020-09-22 02:51:39 +08:00
|
|
|
import unittest
|
2021-10-26 03:29:55 +08:00
|
|
|
import unittest.mock as mock
|
2021-11-05 07:59:29 +08:00
|
|
|
from contextlib import contextmanager
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-12 11:43:27 +08:00
|
|
|
import mlflow
|
2022-01-21 21:44:12 +08:00
|
|
|
import requests
|
2021-11-12 11:43:27 +08:00
|
|
|
import wandb
|
2022-02-10 16:12:26 +08:00
|
|
|
|
2022-04-08 17:13:56 +08:00
|
|
|
from gradio.blocks import Blocks, TabItem, Tabs
|
|
|
|
from gradio.interface import Interface, TabbedInterface, close_all, os
|
|
|
|
from gradio.utils import assert_configs_are_equivalent_besides_ids
|
2021-11-05 07:59:29 +08:00
|
|
|
|
2021-11-10 02:30:59 +08:00
|
|
|
os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
|
2021-10-26 03:29:55 +08:00
|
|
|
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-05 07:59:29 +08:00
|
|
|
@contextmanager
|
|
|
|
def captured_output():
|
|
|
|
new_out, new_err = io.StringIO(), io.StringIO()
|
|
|
|
old_out, old_err = sys.stdout, sys.stderr
|
|
|
|
try:
|
|
|
|
sys.stdout, sys.stderr = new_out, new_err
|
|
|
|
yield sys.stdout, sys.stderr
|
|
|
|
finally:
|
|
|
|
sys.stdout, sys.stderr = old_out, old_err
|
2021-10-26 03:29:55 +08:00
|
|
|
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-04 05:30:36 +08:00
|
|
|
class TestInterface(unittest.TestCase):
|
2021-12-22 01:33:04 +08:00
|
|
|
def test_close(self):
|
|
|
|
io = Interface(lambda input: None, "textbox", "label")
|
2021-12-22 04:20:43 +08:00
|
|
|
_, local_url, _ = io.launch(prevent_thread_lock=True)
|
|
|
|
response = requests.get(local_url)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
2021-12-22 01:33:04 +08:00
|
|
|
io.close()
|
2021-12-22 04:20:43 +08:00
|
|
|
with self.assertRaises(Exception):
|
|
|
|
response = requests.get(local_url)
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-12-22 01:33:04 +08:00
|
|
|
def test_close_all(self):
|
2021-10-26 03:29:55 +08:00
|
|
|
interface = Interface(lambda input: None, "textbox", "label")
|
|
|
|
interface.close = mock.MagicMock()
|
2021-12-22 01:33:04 +08:00
|
|
|
close_all()
|
2021-11-04 05:30:36 +08:00
|
|
|
interface.close.assert_called()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2022-03-26 02:34:55 +08:00
|
|
|
def test_examples_invalid_input(self):
|
|
|
|
with self.assertRaises(ValueError):
|
|
|
|
Interface(lambda x: x, examples=1234)
|
2022-03-24 05:16:53 +08:00
|
|
|
|
2022-03-26 02:34:55 +08:00
|
|
|
def test_examples_valid_path(self):
|
2022-04-06 20:55:51 +08:00
|
|
|
path = os.path.join(
|
|
|
|
os.path.dirname(__file__), "../gradio/test_data/flagged_with_log"
|
|
|
|
)
|
2022-03-26 02:34:55 +08:00
|
|
|
interface = Interface(lambda x: 3 * x, "number", "number", examples=path)
|
|
|
|
dataset_check = any(
|
|
|
|
[c["type"] == "dataset" for c in interface.get_config_file()["components"]]
|
|
|
|
)
|
|
|
|
self.assertTrue(dataset_check)
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-05 07:59:29 +08:00
|
|
|
def test_test_launch(self):
|
|
|
|
with captured_output() as (out, err):
|
|
|
|
prediction_fn = lambda x: x
|
|
|
|
prediction_fn.__name__ = "prediction_fn"
|
|
|
|
interface = Interface(prediction_fn, "textbox", "label")
|
|
|
|
interface.test_launch()
|
|
|
|
output = out.getvalue().strip()
|
2022-01-21 21:44:12 +08:00
|
|
|
self.assertEqual(output, "Test launch: prediction_fn()... PASSED")
|
|
|
|
|
2021-11-05 07:59:29 +08:00
|
|
|
@mock.patch("time.sleep")
|
2022-01-05 01:58:37 +08:00
|
|
|
def test_block_thread(self, mock_sleep):
|
2021-11-05 07:59:29 +08:00
|
|
|
with self.assertRaises(KeyboardInterrupt):
|
2022-01-05 01:58:37 +08:00
|
|
|
with captured_output() as (out, _):
|
2021-11-05 07:59:29 +08:00
|
|
|
mock_sleep.side_effect = KeyboardInterrupt()
|
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
2022-01-05 01:58:37 +08:00
|
|
|
interface.launch(prevent_thread_lock=False)
|
2021-11-05 07:59:29 +08:00
|
|
|
output = out.getvalue().strip()
|
2022-01-21 21:44:12 +08:00
|
|
|
self.assertEqual(
|
|
|
|
output, "Keyboard interruption in main thread... closing server."
|
|
|
|
)
|
2020-09-22 02:51:39 +08:00
|
|
|
|
2022-01-21 21:44:12 +08:00
|
|
|
@mock.patch("gradio.utils.colab_check")
|
2021-11-06 08:10:37 +08:00
|
|
|
def test_launch_colab_share(self, mock_colab_check):
|
|
|
|
mock_colab_check.return_value = True
|
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
|
|
|
_, _, share_url = interface.launch(prevent_thread_lock=True)
|
|
|
|
self.assertIsNotNone(share_url)
|
2021-11-10 11:34:08 +08:00
|
|
|
interface.close()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
|
|
|
@mock.patch("gradio.utils.colab_check")
|
|
|
|
@mock.patch("gradio.networking.setup_tunnel")
|
2021-11-06 08:10:37 +08:00
|
|
|
def test_launch_colab_share_error(self, mock_setup_tunnel, mock_colab_check):
|
|
|
|
mock_setup_tunnel.side_effect = RuntimeError()
|
|
|
|
mock_colab_check.return_value = True
|
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
|
|
|
_, _, share_url = interface.launch(prevent_thread_lock=True)
|
|
|
|
self.assertIsNone(share_url)
|
2021-11-10 11:34:08 +08:00
|
|
|
interface.close()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-06 08:10:37 +08:00
|
|
|
def test_interface_representation(self):
|
|
|
|
prediction_fn = lambda x: x
|
|
|
|
prediction_fn.__name__ = "prediction_fn"
|
2022-01-21 21:44:12 +08:00
|
|
|
repr = str(Interface(prediction_fn, "textbox", "label")).split("\n")
|
2021-11-06 08:10:37 +08:00
|
|
|
self.assertTrue(prediction_fn.__name__ in repr[0])
|
|
|
|
self.assertEqual(len(repr[0]), len(repr[1]))
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-06 08:10:37 +08:00
|
|
|
def test_interface_none_interp(self):
|
2021-11-10 11:34:08 +08:00
|
|
|
interface = Interface(lambda x: x, "textbox", "label", interpretation=[None])
|
2022-04-05 06:47:51 +08:00
|
|
|
scores = interface.interpret(["quickest brown fox"])[0]["interpretation"]
|
|
|
|
self.assertIsNone(scores)
|
2022-01-21 21:44:12 +08:00
|
|
|
|
|
|
|
@mock.patch("webbrowser.open")
|
2021-11-06 08:10:37 +08:00
|
|
|
def test_interface_browser(self, mock_browser):
|
2021-11-10 11:34:08 +08:00
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
|
|
|
interface.launch(inbrowser=True, prevent_thread_lock=True)
|
|
|
|
mock_browser.assert_called_once()
|
|
|
|
interface.close()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-09 13:02:37 +08:00
|
|
|
def test_examples_list(self):
|
2022-01-21 21:44:12 +08:00
|
|
|
examples = ["test1", "test2"]
|
2021-11-09 13:02:37 +08:00
|
|
|
interface = Interface(lambda x: x, "textbox", "label", examples=examples)
|
|
|
|
interface.launch(prevent_thread_lock=True)
|
|
|
|
self.assertEqual(len(interface.examples), 2)
|
|
|
|
self.assertEqual(len(interface.examples[0]), 1)
|
2021-11-10 11:34:08 +08:00
|
|
|
interface.close()
|
|
|
|
|
2022-01-21 21:44:12 +08:00
|
|
|
@mock.patch("IPython.display.display")
|
2021-11-11 11:40:57 +08:00
|
|
|
def test_inline_display(self, mock_display):
|
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
|
|
|
interface.launch(inline=True, prevent_thread_lock=True)
|
|
|
|
mock_display.assert_called_once()
|
|
|
|
interface.launch(inline=True, share=True, prevent_thread_lock=True)
|
|
|
|
self.assertEqual(mock_display.call_count, 2)
|
|
|
|
interface.close()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
|
|
|
@mock.patch("comet_ml.Experiment")
|
2021-11-12 11:43:27 +08:00
|
|
|
def test_integration_comet(self, mock_experiment):
|
|
|
|
experiment = mock_experiment()
|
|
|
|
experiment.log_text = mock.MagicMock()
|
|
|
|
experiment.log_other = mock.MagicMock()
|
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
|
|
|
interface.launch(prevent_thread_lock=True)
|
|
|
|
interface.integrate(comet_ml=experiment)
|
2022-01-21 21:44:12 +08:00
|
|
|
experiment.log_text.assert_called_with("gradio: " + interface.local_url)
|
|
|
|
interface.share_url = "tmp" # used to avoid creating real share links.
|
2021-11-12 11:43:27 +08:00
|
|
|
interface.integrate(comet_ml=experiment)
|
2022-01-21 21:44:12 +08:00
|
|
|
experiment.log_text.assert_called_with("gradio: " + interface.share_url)
|
2021-11-12 11:43:27 +08:00
|
|
|
self.assertEqual(experiment.log_other.call_count, 2)
|
|
|
|
interface.share_url = None
|
|
|
|
interface.close()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-12 11:43:27 +08:00
|
|
|
def test_integration_mlflow(self):
|
|
|
|
mlflow.log_param = mock.MagicMock()
|
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
|
|
|
interface.launch(prevent_thread_lock=True)
|
|
|
|
interface.integrate(mlflow=mlflow)
|
2022-01-21 21:44:12 +08:00
|
|
|
mlflow.log_param.assert_called_with(
|
|
|
|
"Gradio Interface Local Link", interface.local_url
|
|
|
|
)
|
|
|
|
interface.share_url = "tmp" # used to avoid creating real share links.
|
2021-11-12 11:43:27 +08:00
|
|
|
interface.integrate(mlflow=mlflow)
|
2022-01-21 21:44:12 +08:00
|
|
|
mlflow.log_param.assert_called_with(
|
|
|
|
"Gradio Interface Share Link", interface.share_url
|
|
|
|
)
|
2021-11-12 11:43:27 +08:00
|
|
|
interface.share_url = None
|
|
|
|
interface.close()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
2021-11-12 11:43:27 +08:00
|
|
|
def test_integration_wandb(self):
|
|
|
|
with captured_output() as (out, err):
|
|
|
|
wandb.log = mock.MagicMock()
|
|
|
|
wandb.Html = mock.MagicMock()
|
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
|
|
|
interface.integrate(wandb=wandb)
|
2022-01-21 21:44:12 +08:00
|
|
|
self.assertEqual(
|
|
|
|
out.getvalue().strip(),
|
|
|
|
"The WandB integration requires you to `launch(share=True)` first.",
|
|
|
|
)
|
|
|
|
interface.share_url = "tmp"
|
2021-11-12 11:43:27 +08:00
|
|
|
interface.integrate(wandb=wandb)
|
|
|
|
wandb.log.assert_called_once()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
|
|
|
@mock.patch("requests.post")
|
2021-11-12 11:43:27 +08:00
|
|
|
def test_integration_analytics(self, mock_post):
|
|
|
|
mlflow.log_param = mock.MagicMock()
|
|
|
|
interface = Interface(lambda x: x, "textbox", "label")
|
|
|
|
interface.analytics_enabled = True
|
|
|
|
interface.integrate(mlflow=mlflow)
|
|
|
|
mock_post.assert_called_once()
|
2022-01-21 21:44:12 +08:00
|
|
|
|
|
|
|
|
2022-04-08 17:13:56 +08:00
|
|
|
class TestTabbedInterface(unittest.TestCase):
|
|
|
|
def test_tabbed_interface_config_matches_manual_tab(self):
|
|
|
|
interface1 = Interface(lambda x: x, "textbox", "textbox")
|
|
|
|
interface2 = Interface(lambda x: x, "image", "image")
|
|
|
|
|
|
|
|
with Blocks() as demo:
|
|
|
|
with Tabs():
|
|
|
|
with TabItem(label="tab1"):
|
|
|
|
interface1.render_basic_interface()
|
|
|
|
with TabItem(label="tab2"):
|
|
|
|
interface2.render_basic_interface()
|
|
|
|
|
|
|
|
interface3 = Interface(lambda x: x, "textbox", "textbox")
|
|
|
|
interface4 = Interface(lambda x: x, "image", "image")
|
|
|
|
tabbed_interface = TabbedInterface([interface3, interface4], ["tab1", "tab2"])
|
|
|
|
|
|
|
|
self.assertTrue(
|
|
|
|
assert_configs_are_equivalent_besides_ids(
|
|
|
|
demo.get_config_file(), tabbed_interface.get_config_file()
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-01-21 21:44:12 +08:00
|
|
|
if __name__ == "__main__":
|
|
|
|
unittest.main()
|