2023-07-24 23:55:47 +08:00
|
|
|
import tempfile
|
2023-07-20 19:08:50 +08:00
|
|
|
from concurrent.futures import wait
|
2023-12-19 09:07:38 +08:00
|
|
|
from pathlib import Path
|
|
|
|
from unittest.mock import patch
|
2023-07-18 01:22:47 +08:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
import gradio as gr
|
|
|
|
|
|
|
|
|
|
|
|
def invalid_fn(message):
|
|
|
|
return message
|
|
|
|
|
|
|
|
|
|
|
|
def double(message, history):
|
|
|
|
return message + " " + message
|
|
|
|
|
|
|
|
|
2023-08-09 03:57:55 +08:00
|
|
|
async def async_greet(message, history):
|
|
|
|
return "hi, " + message
|
|
|
|
|
|
|
|
|
2023-07-18 01:22:47 +08:00
|
|
|
def stream(message, history):
|
|
|
|
for i in range(len(message)):
|
|
|
|
yield message[: i + 1]
|
|
|
|
|
|
|
|
|
2023-08-09 03:57:55 +08:00
|
|
|
async def async_stream(message, history):
|
|
|
|
for i in range(len(message)):
|
|
|
|
yield message[: i + 1]
|
|
|
|
|
|
|
|
|
2023-07-18 01:22:47 +08:00
|
|
|
def count(message, history):
|
|
|
|
return str(len(history))
|
|
|
|
|
|
|
|
|
2023-07-24 23:55:47 +08:00
|
|
|
def echo_system_prompt_plus_message(message, history, system_prompt, tokens):
|
|
|
|
response = f"{system_prompt} {message}"
|
|
|
|
for i in range(min(len(response), int(tokens))):
|
|
|
|
yield response[: i + 1]
|
|
|
|
|
|
|
|
|
2023-07-18 01:22:47 +08:00
|
|
|
class TestInit:
|
|
|
|
def test_no_fn(self):
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
gr.ChatInterface()
|
|
|
|
|
|
|
|
def test_configuring_buttons(self):
|
|
|
|
chatbot = gr.ChatInterface(double, submit_btn=None, retry_btn=None)
|
|
|
|
assert chatbot.submit_btn is None
|
|
|
|
assert chatbot.retry_btn is None
|
|
|
|
|
2023-12-05 06:19:53 +08:00
|
|
|
def test_concurrency_limit(self):
|
|
|
|
chat = gr.ChatInterface(double, concurrency_limit=10)
|
|
|
|
assert chat.concurrency_limit == 10
|
|
|
|
fns = [fn for fn in chat.fns if fn.name in {"_submit_fn", "_api_submit_fn"}]
|
|
|
|
assert all(fn.concurrency_limit == 10 for fn in fns)
|
|
|
|
|
2024-03-22 03:22:14 +08:00
|
|
|
def test_custom_textbox(self):
|
|
|
|
def chat():
|
|
|
|
return "Hello"
|
|
|
|
|
|
|
|
gr.ChatInterface(
|
|
|
|
chat,
|
|
|
|
chatbot=gr.Chatbot(height=400),
|
|
|
|
textbox=gr.Textbox(placeholder="Type Message", container=False, scale=7),
|
|
|
|
title="Test",
|
|
|
|
clear_btn="Clear",
|
|
|
|
)
|
|
|
|
gr.ChatInterface(
|
|
|
|
chat,
|
|
|
|
chatbot=gr.Chatbot(height=400),
|
|
|
|
textbox=gr.MultimodalTextbox(container=False, scale=7),
|
|
|
|
title="Test",
|
|
|
|
clear_btn="Clear",
|
|
|
|
)
|
|
|
|
|
2023-07-18 01:22:47 +08:00
|
|
|
def test_events_attached(self):
|
|
|
|
chatbot = gr.ChatInterface(double)
|
|
|
|
dependencies = chatbot.dependencies
|
|
|
|
textbox = chatbot.textbox._id
|
2023-09-26 06:25:16 +08:00
|
|
|
submit_btn = chatbot.submit_btn._id
|
2023-07-18 01:22:47 +08:00
|
|
|
assert next(
|
|
|
|
(
|
|
|
|
d
|
|
|
|
for d in dependencies
|
2023-09-26 06:25:16 +08:00
|
|
|
if d["targets"] == [(textbox, "submit"), (submit_btn, "click")]
|
2023-07-18 01:22:47 +08:00
|
|
|
),
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
for btn_id in [
|
|
|
|
chatbot.retry_btn._id,
|
|
|
|
chatbot.clear_btn._id,
|
|
|
|
chatbot.undo_btn._id,
|
|
|
|
]:
|
|
|
|
assert next(
|
2023-09-26 06:25:16 +08:00
|
|
|
(d for d in dependencies if d["targets"][0] == (btn_id, "click")),
|
2023-07-18 01:22:47 +08:00
|
|
|
None,
|
|
|
|
)
|
|
|
|
|
2024-03-30 07:14:33 +08:00
|
|
|
def test_example_caching(self):
|
2023-12-19 09:07:38 +08:00
|
|
|
with patch(
|
|
|
|
"gradio.utils.get_cache_folder", return_value=Path(tempfile.mkdtemp())
|
|
|
|
):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
double, examples=["hello", "hi"], cache_examples=True
|
|
|
|
)
|
|
|
|
prediction_hello = chatbot.examples_handler.load_from_cache(0)
|
|
|
|
prediction_hi = chatbot.examples_handler.load_from_cache(1)
|
|
|
|
assert prediction_hello[0].root[0] == ("hello", "hello hello")
|
|
|
|
assert prediction_hi[0].root[0] == ("hi", "hi hi")
|
2023-07-18 01:22:47 +08:00
|
|
|
|
2024-03-30 07:14:33 +08:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_example_caching_lazy(self):
|
|
|
|
with patch(
|
|
|
|
"gradio.utils.get_cache_folder", return_value=Path(tempfile.mkdtemp())
|
|
|
|
):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
double, examples=["hello", "hi"], cache_examples="lazy"
|
|
|
|
)
|
|
|
|
async for _ in chatbot.examples_handler.async_lazy_cache(0, "hello"):
|
|
|
|
pass
|
|
|
|
prediction_hello = chatbot.examples_handler.load_from_cache(0)
|
|
|
|
assert prediction_hello[0].root[0] == ("hello", "hello hello")
|
|
|
|
with pytest.raises(IndexError):
|
|
|
|
prediction_hi = chatbot.examples_handler.load_from_cache(1)
|
|
|
|
assert prediction_hi[0].root[0] == ("hi", "hi hi")
|
|
|
|
|
|
|
|
def test_example_caching_async(self):
|
2023-12-19 09:07:38 +08:00
|
|
|
with patch(
|
|
|
|
"gradio.utils.get_cache_folder", return_value=Path(tempfile.mkdtemp())
|
|
|
|
):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
async_greet, examples=["abubakar", "tom"], cache_examples=True
|
|
|
|
)
|
|
|
|
prediction_hello = chatbot.examples_handler.load_from_cache(0)
|
|
|
|
prediction_hi = chatbot.examples_handler.load_from_cache(1)
|
|
|
|
assert prediction_hello[0].root[0] == ("abubakar", "hi, abubakar")
|
|
|
|
assert prediction_hi[0].root[0] == ("tom", "hi, tom")
|
2023-08-09 03:57:55 +08:00
|
|
|
|
2024-03-30 07:14:33 +08:00
|
|
|
def test_example_caching_with_streaming(self):
|
2023-12-19 09:07:38 +08:00
|
|
|
with patch(
|
|
|
|
"gradio.utils.get_cache_folder", return_value=Path(tempfile.mkdtemp())
|
|
|
|
):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
stream, examples=["hello", "hi"], cache_examples=True
|
|
|
|
)
|
|
|
|
prediction_hello = chatbot.examples_handler.load_from_cache(0)
|
|
|
|
prediction_hi = chatbot.examples_handler.load_from_cache(1)
|
|
|
|
assert prediction_hello[0].root[0] == ("hello", "hello")
|
|
|
|
assert prediction_hi[0].root[0] == ("hi", "hi")
|
2023-07-18 01:22:47 +08:00
|
|
|
|
2024-03-30 07:14:33 +08:00
|
|
|
def test_example_caching_with_streaming_async(self):
|
2023-12-19 09:07:38 +08:00
|
|
|
with patch(
|
|
|
|
"gradio.utils.get_cache_folder", return_value=Path(tempfile.mkdtemp())
|
|
|
|
):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
async_stream, examples=["hello", "hi"], cache_examples=True
|
|
|
|
)
|
|
|
|
prediction_hello = chatbot.examples_handler.load_from_cache(0)
|
|
|
|
prediction_hi = chatbot.examples_handler.load_from_cache(1)
|
|
|
|
assert prediction_hello[0].root[0] == ("hello", "hello")
|
|
|
|
assert prediction_hi[0].root[0] == ("hi", "hi")
|
2023-08-09 03:57:55 +08:00
|
|
|
|
2023-11-22 02:58:53 +08:00
|
|
|
def test_default_accordion_params(self):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
echo_system_prompt_plus_message,
|
|
|
|
additional_inputs=["textbox", "slider"],
|
|
|
|
)
|
|
|
|
accordion = [
|
|
|
|
comp
|
|
|
|
for comp in chatbot.blocks.values()
|
|
|
|
if comp.get_config().get("name") == "accordion"
|
|
|
|
][0]
|
|
|
|
assert accordion.get_config().get("open") is False
|
|
|
|
assert accordion.get_config().get("label") == "Additional Inputs"
|
|
|
|
|
|
|
|
def test_setting_accordion_params(self, monkeypatch):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
echo_system_prompt_plus_message,
|
|
|
|
additional_inputs=["textbox", "slider"],
|
|
|
|
additional_inputs_accordion=gr.Accordion(open=True, label="MOAR"),
|
|
|
|
)
|
|
|
|
accordion = [
|
|
|
|
comp
|
|
|
|
for comp in chatbot.blocks.values()
|
|
|
|
if comp.get_config().get("name") == "accordion"
|
|
|
|
][0]
|
|
|
|
assert accordion.get_config().get("open") is True
|
|
|
|
assert accordion.get_config().get("label") == "MOAR"
|
|
|
|
|
2023-10-07 02:05:11 +08:00
|
|
|
def test_example_caching_with_additional_inputs(self, monkeypatch):
|
2023-12-19 09:07:38 +08:00
|
|
|
with patch(
|
|
|
|
"gradio.utils.get_cache_folder", return_value=Path(tempfile.mkdtemp())
|
|
|
|
):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
echo_system_prompt_plus_message,
|
|
|
|
additional_inputs=["textbox", "slider"],
|
|
|
|
examples=[["hello", "robot", 100], ["hi", "robot", 2]],
|
|
|
|
cache_examples=True,
|
|
|
|
)
|
|
|
|
prediction_hello = chatbot.examples_handler.load_from_cache(0)
|
|
|
|
prediction_hi = chatbot.examples_handler.load_from_cache(1)
|
|
|
|
assert prediction_hello[0].root[0] == ("hello", "robot hello")
|
|
|
|
assert prediction_hi[0].root[0] == ("hi", "ro")
|
2023-07-24 23:55:47 +08:00
|
|
|
|
2023-10-07 02:05:11 +08:00
|
|
|
def test_example_caching_with_additional_inputs_already_rendered(self, monkeypatch):
|
2023-12-19 09:07:38 +08:00
|
|
|
with patch(
|
|
|
|
"gradio.utils.get_cache_folder", return_value=Path(tempfile.mkdtemp())
|
|
|
|
):
|
|
|
|
with gr.Blocks():
|
|
|
|
with gr.Accordion("Inputs"):
|
|
|
|
text = gr.Textbox()
|
|
|
|
slider = gr.Slider()
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
echo_system_prompt_plus_message,
|
|
|
|
additional_inputs=[text, slider],
|
|
|
|
examples=[["hello", "robot", 100], ["hi", "robot", 2]],
|
|
|
|
cache_examples=True,
|
|
|
|
)
|
|
|
|
prediction_hello = chatbot.examples_handler.load_from_cache(0)
|
|
|
|
prediction_hi = chatbot.examples_handler.load_from_cache(1)
|
|
|
|
assert prediction_hello[0].root[0] == ("hello", "robot hello")
|
|
|
|
assert prediction_hi[0].root[0] == ("hi", "ro")
|
2023-07-24 23:55:47 +08:00
|
|
|
|
2023-07-18 01:22:47 +08:00
|
|
|
|
|
|
|
class TestAPI:
|
|
|
|
def test_get_api_info(self):
|
|
|
|
chatbot = gr.ChatInterface(double)
|
2023-10-31 12:46:02 +08:00
|
|
|
api_info = chatbot.get_api_info()
|
2023-07-18 01:22:47 +08:00
|
|
|
assert len(api_info["named_endpoints"]) == 1
|
|
|
|
assert len(api_info["unnamed_endpoints"]) == 0
|
|
|
|
assert "/chat" in api_info["named_endpoints"]
|
|
|
|
|
|
|
|
def test_streaming_api(self, connect):
|
|
|
|
chatbot = gr.ChatInterface(stream).queue()
|
|
|
|
with connect(chatbot) as client:
|
|
|
|
job = client.submit("hello")
|
2023-07-20 19:08:50 +08:00
|
|
|
wait([job])
|
2023-07-18 01:22:47 +08:00
|
|
|
assert job.outputs() == ["h", "he", "hel", "hell", "hello"]
|
|
|
|
|
2023-08-09 03:57:55 +08:00
|
|
|
def test_streaming_api_async(self, connect):
|
|
|
|
chatbot = gr.ChatInterface(async_stream).queue()
|
|
|
|
with connect(chatbot) as client:
|
|
|
|
job = client.submit("hello")
|
|
|
|
wait([job])
|
|
|
|
assert job.outputs() == ["h", "he", "hel", "hell", "hello"]
|
|
|
|
|
2023-07-18 01:22:47 +08:00
|
|
|
def test_non_streaming_api(self, connect):
|
|
|
|
chatbot = gr.ChatInterface(double)
|
|
|
|
with connect(chatbot) as client:
|
|
|
|
result = client.predict("hello")
|
|
|
|
assert result == "hello hello"
|
2023-07-24 23:55:47 +08:00
|
|
|
|
2023-08-09 03:57:55 +08:00
|
|
|
def test_non_streaming_api_async(self, connect):
|
|
|
|
chatbot = gr.ChatInterface(async_greet)
|
|
|
|
with connect(chatbot) as client:
|
|
|
|
result = client.predict("gradio")
|
|
|
|
assert result == "hi, gradio"
|
|
|
|
|
2023-07-24 23:55:47 +08:00
|
|
|
def test_streaming_api_with_additional_inputs(self, connect):
|
|
|
|
chatbot = gr.ChatInterface(
|
|
|
|
echo_system_prompt_plus_message,
|
|
|
|
additional_inputs=["textbox", "slider"],
|
|
|
|
).queue()
|
|
|
|
with connect(chatbot) as client:
|
|
|
|
job = client.submit("hello", "robot", 7)
|
|
|
|
wait([job])
|
|
|
|
assert job.outputs() == [
|
|
|
|
"r",
|
|
|
|
"ro",
|
|
|
|
"rob",
|
|
|
|
"robo",
|
|
|
|
"robot",
|
|
|
|
"robot ",
|
|
|
|
"robot h",
|
|
|
|
]
|