2022-05-12 04:10:50 +08:00
|
|
|
import asyncio
|
2022-07-19 13:47:40 +08:00
|
|
|
import io
|
2022-03-29 23:45:24 +08:00
|
|
|
import random
|
2022-07-19 13:47:40 +08:00
|
|
|
import sys
|
2022-05-12 04:10:50 +08:00
|
|
|
import time
|
2022-03-30 00:12:01 +08:00
|
|
|
import unittest
|
2022-07-19 13:47:40 +08:00
|
|
|
import unittest.mock as mock
|
|
|
|
from contextlib import contextmanager
|
2022-06-04 02:59:50 +08:00
|
|
|
from unittest.mock import patch
|
2022-03-30 20:34:08 +08:00
|
|
|
|
2022-07-19 13:47:40 +08:00
|
|
|
import mlflow
|
2022-05-12 04:10:50 +08:00
|
|
|
import pytest
|
2022-07-19 13:47:40 +08:00
|
|
|
import wandb
|
2022-05-12 04:10:50 +08:00
|
|
|
|
2022-03-30 01:38:49 +08:00
|
|
|
import gradio as gr
|
2022-05-12 04:10:50 +08:00
|
|
|
from gradio.routes import PredictBody
|
2022-04-06 20:55:51 +08:00
|
|
|
from gradio.test_data.blocks_configs import XRAY_CONFIG
|
2022-06-04 02:59:50 +08:00
|
|
|
from gradio.utils import assert_configs_are_equivalent_besides_ids
|
2022-03-30 01:38:49 +08:00
|
|
|
|
2022-05-12 04:10:50 +08:00
|
|
|
pytest_plugins = ("pytest_asyncio",)
|
|
|
|
|
2022-03-29 23:45:24 +08:00
|
|
|
|
2022-07-19 13:47:40 +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
|
|
|
|
|
|
|
|
|
2022-03-30 00:12:01 +08:00
|
|
|
class TestBlocks(unittest.TestCase):
|
2022-05-21 08:53:27 +08:00
|
|
|
maxDiff = None
|
|
|
|
|
2022-06-04 02:59:50 +08:00
|
|
|
def test_set_share(self):
|
|
|
|
with gr.Blocks() as demo:
|
|
|
|
# self.share is False when instantiating the class
|
|
|
|
self.assertFalse(demo.share)
|
|
|
|
# default is False, if share is None
|
|
|
|
demo.share = None
|
|
|
|
self.assertFalse(demo.share)
|
|
|
|
# if set to True, it doesn't change
|
|
|
|
demo.share = True
|
|
|
|
self.assertTrue(demo.share)
|
|
|
|
|
|
|
|
@patch("gradio.utils.colab_check")
|
|
|
|
def test_set_share_in_colab(self, mock_colab_check):
|
|
|
|
mock_colab_check.return_value = True
|
|
|
|
with gr.Blocks() as demo:
|
|
|
|
# self.share is False when instantiating the class
|
|
|
|
self.assertFalse(demo.share)
|
|
|
|
# default is True, if share is None and colab_check is true
|
|
|
|
demo.share = None
|
|
|
|
self.assertTrue(demo.share)
|
|
|
|
# if set to True, it doesn't change
|
|
|
|
demo.share = True
|
|
|
|
self.assertTrue(demo.share)
|
|
|
|
|
2022-03-29 23:45:24 +08:00
|
|
|
def test_xray(self):
|
2022-04-09 01:54:59 +08:00
|
|
|
def fake_func():
|
|
|
|
return "Hello There"
|
|
|
|
|
2022-03-29 23:46:42 +08:00
|
|
|
xray_model = lambda diseases, img: {
|
|
|
|
disease: random.random() for disease in diseases
|
|
|
|
}
|
2022-03-29 23:45:24 +08:00
|
|
|
ct_model = lambda diseases, img: {disease: 0.1 for disease in diseases}
|
|
|
|
|
2022-04-09 01:54:59 +08:00
|
|
|
with gr.Blocks() as demo:
|
2022-05-24 05:38:53 +08:00
|
|
|
gr.Markdown(
|
2022-03-29 23:45:24 +08:00
|
|
|
"""
|
|
|
|
# Detect Disease From Scan
|
|
|
|
With this model you can lorem ipsum
|
|
|
|
- ipsum 1
|
|
|
|
- ipsum 2
|
|
|
|
"""
|
|
|
|
)
|
2022-05-24 05:38:53 +08:00
|
|
|
disease = gr.CheckboxGroup(
|
2022-03-29 23:45:24 +08:00
|
|
|
choices=["Covid", "Malaria", "Lung Cancer"], label="Disease to Scan For"
|
|
|
|
)
|
|
|
|
|
|
|
|
with gr.Tabs():
|
|
|
|
with gr.TabItem("X-ray"):
|
|
|
|
with gr.Row():
|
2022-05-24 05:38:53 +08:00
|
|
|
xray_scan = gr.Image()
|
|
|
|
xray_results = gr.JSON()
|
2022-05-19 06:14:53 +08:00
|
|
|
xray_run = gr.Button("Run")
|
2022-03-29 23:45:24 +08:00
|
|
|
xray_run.click(
|
|
|
|
xray_model, inputs=[disease, xray_scan], outputs=xray_results
|
|
|
|
)
|
|
|
|
|
|
|
|
with gr.TabItem("CT Scan"):
|
|
|
|
with gr.Row():
|
2022-05-24 05:38:53 +08:00
|
|
|
ct_scan = gr.Image()
|
|
|
|
ct_results = gr.JSON()
|
2022-03-29 23:45:24 +08:00
|
|
|
ct_run = gr.Button("Run")
|
2022-03-29 23:46:42 +08:00
|
|
|
ct_run.click(
|
|
|
|
ct_model, inputs=[disease, ct_scan], outputs=ct_results
|
|
|
|
)
|
2022-05-24 05:38:53 +08:00
|
|
|
textbox = gr.Textbox()
|
2022-04-09 01:54:59 +08:00
|
|
|
demo.load(fake_func, [], [textbox])
|
2022-05-27 05:33:28 +08:00
|
|
|
|
|
|
|
config = demo.get_config_file()
|
2022-06-04 02:59:50 +08:00
|
|
|
self.assertTrue(assert_configs_are_equivalent_besides_ids(XRAY_CONFIG, config))
|
2022-03-30 00:12:01 +08:00
|
|
|
|
2022-07-02 11:21:54 +08:00
|
|
|
def test_load_from_config(self):
|
|
|
|
def update(name):
|
|
|
|
return f"Welcome to Gradio, {name}!"
|
|
|
|
|
|
|
|
with gr.Blocks() as demo1:
|
|
|
|
inp = gr.Textbox(placeholder="What is your name?")
|
|
|
|
out = gr.Textbox()
|
|
|
|
|
|
|
|
inp.submit(fn=update, inputs=inp, outputs=out, api_name="greet")
|
|
|
|
|
|
|
|
gr.Image().style(height=54, width=240)
|
|
|
|
|
|
|
|
config1 = demo1.get_config_file()
|
|
|
|
demo2 = gr.Blocks.from_config(config1, [update])
|
|
|
|
config2 = demo2.get_config_file()
|
|
|
|
self.assertTrue(assert_configs_are_equivalent_besides_ids(config1, config2))
|
|
|
|
|
2022-05-12 04:10:50 +08:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_async_function(self):
|
|
|
|
async def wait():
|
|
|
|
await asyncio.sleep(0.01)
|
|
|
|
return True
|
|
|
|
|
|
|
|
with gr.Blocks() as demo:
|
2022-05-24 05:38:53 +08:00
|
|
|
text = gr.Textbox()
|
|
|
|
button = gr.Button()
|
2022-05-12 04:10:50 +08:00
|
|
|
button.click(wait, [text], [text])
|
|
|
|
|
|
|
|
body = PredictBody(data=1, fn_index=0)
|
|
|
|
start = time.time()
|
|
|
|
result = await demo.process_api(body)
|
|
|
|
end = time.time()
|
|
|
|
difference = end - start
|
|
|
|
assert difference >= 0.01
|
|
|
|
assert result
|
|
|
|
|
2022-07-19 13:47:40 +08:00
|
|
|
def test_integration_wandb(self):
|
|
|
|
with captured_output() as (out, err):
|
|
|
|
wandb.log = mock.MagicMock()
|
|
|
|
wandb.Html = mock.MagicMock()
|
|
|
|
demo = gr.Blocks()
|
|
|
|
with demo:
|
|
|
|
gr.Textbox("Hi there!")
|
|
|
|
demo.integrate(wandb=wandb)
|
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
out.getvalue().strip(),
|
|
|
|
"The WandB integration requires you to `launch(share=True)` first.",
|
|
|
|
)
|
|
|
|
demo.share_url = "tmp"
|
|
|
|
demo.integrate(wandb=wandb)
|
|
|
|
wandb.log.assert_called_once()
|
|
|
|
|
|
|
|
@mock.patch("comet_ml.Experiment")
|
|
|
|
def test_integration_comet(self, mock_experiment):
|
|
|
|
experiment = mock_experiment()
|
|
|
|
experiment.log_text = mock.MagicMock()
|
|
|
|
experiment.log_other = mock.MagicMock()
|
|
|
|
|
|
|
|
demo = gr.Blocks()
|
|
|
|
with demo:
|
|
|
|
gr.Textbox("Hi there!")
|
|
|
|
|
|
|
|
demo.launch(prevent_thread_lock=True)
|
|
|
|
demo.integrate(comet_ml=experiment)
|
|
|
|
experiment.log_text.assert_called_with("gradio: " + demo.local_url)
|
|
|
|
demo.share_url = "tmp" # used to avoid creating real share links.
|
|
|
|
demo.integrate(comet_ml=experiment)
|
|
|
|
experiment.log_text.assert_called_with("gradio: " + demo.share_url)
|
|
|
|
self.assertEqual(experiment.log_other.call_count, 2)
|
|
|
|
demo.share_url = None
|
|
|
|
demo.close()
|
|
|
|
|
|
|
|
def test_integration_mlflow(self):
|
|
|
|
mlflow.log_param = mock.MagicMock()
|
|
|
|
demo = gr.Blocks()
|
|
|
|
with demo:
|
|
|
|
gr.Textbox("Hi there!")
|
|
|
|
|
|
|
|
demo.launch(prevent_thread_lock=True)
|
|
|
|
demo.integrate(mlflow=mlflow)
|
|
|
|
mlflow.log_param.assert_called_with(
|
|
|
|
"Gradio Interface Local Link", demo.local_url
|
|
|
|
)
|
|
|
|
demo.share_url = "tmp" # used to avoid creating real share links.
|
|
|
|
demo.integrate(mlflow=mlflow)
|
|
|
|
mlflow.log_param.assert_called_with(
|
|
|
|
"Gradio Interface Share Link", demo.share_url
|
|
|
|
)
|
|
|
|
demo.share_url = None
|
|
|
|
demo.close()
|
|
|
|
|
2022-03-30 00:12:01 +08:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
unittest.main()
|