mirror of
https://github.com/gradio-app/gradio.git
synced 2025-04-06 12:30:29 +08:00
Queue error fix & custom errors (#2047)
* changes * format * changes * changes * custom error * change * change * change * changes * change * fe fix * changes * changes
This commit is contained in:
parent
e9b4584ffb
commit
1510cb73cc
@ -8,6 +8,8 @@ def calculator(num1, operation, num2):
|
||||
elif operation == "multiply":
|
||||
return num1 * num2
|
||||
elif operation == "divide":
|
||||
if num2 == 0:
|
||||
raise gr.Error("Cannot divide by zero!")
|
||||
return num1 / num2
|
||||
|
||||
demo = gr.Interface(
|
||||
@ -28,4 +30,4 @@ demo = gr.Interface(
|
||||
description="Here's a sample toy calculator. Enjoy!",
|
||||
)
|
||||
if __name__ == "__main__":
|
||||
demo.launch(show_error=True)
|
||||
demo.launch()
|
||||
|
@ -7,8 +7,10 @@ import time
|
||||
import gradio as gr
|
||||
|
||||
|
||||
def fake_gan(*args):
|
||||
time.sleep(15)
|
||||
def fake_gan(desc):
|
||||
if desc == "NSFW":
|
||||
raise gr.Error("NSFW - banned content.")
|
||||
time.sleep(5)
|
||||
image = random.choice(
|
||||
[
|
||||
"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387&q=80",
|
||||
@ -23,20 +25,12 @@ def fake_gan(*args):
|
||||
|
||||
demo = gr.Interface(
|
||||
fn=fake_gan,
|
||||
inputs=[
|
||||
gr.Image(label="Initial Image (optional)"),
|
||||
],
|
||||
inputs=gr.Textbox(),
|
||||
outputs=gr.Image(label="Generated Image"),
|
||||
title="FD-GAN",
|
||||
description="This is a fake demo of a GAN. In reality, the images are randomly chosen from Unsplash.",
|
||||
examples=[
|
||||
[os.path.join(os.path.dirname(__file__), "files/cheetah1.jpg")],
|
||||
[os.path.join(os.path.dirname(__file__), "files/elephant.jpg")],
|
||||
[os.path.join(os.path.dirname(__file__), "files/tiger.jpg")],
|
||||
[os.path.join(os.path.dirname(__file__), "files/zebra.jpg")],
|
||||
],
|
||||
)
|
||||
demo.queue(max_size=3)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
||||
demo.launch(show_error=True)
|
||||
|
@ -44,6 +44,7 @@ from gradio.components import (
|
||||
component,
|
||||
)
|
||||
from gradio.examples import create_examples as Examples
|
||||
from gradio.exceptions import Error
|
||||
from gradio.flagging import (
|
||||
CSVLogger,
|
||||
FlaggingCallback,
|
||||
|
@ -33,6 +33,7 @@ from gradio.documentation import (
|
||||
document_component_api,
|
||||
set_documentation_group,
|
||||
)
|
||||
from gradio.exceptions import Error
|
||||
from gradio.utils import component_or_layout_class, delete_none
|
||||
|
||||
set_documentation_group("blocks")
|
||||
@ -813,7 +814,7 @@ class Blocks(BlockContext):
|
||||
auth: Optional[Callable | Tuple[str, str] | List[Tuple[str, str]]] = None,
|
||||
auth_message: Optional[str] = None,
|
||||
prevent_thread_lock: bool = False,
|
||||
show_error: bool = True,
|
||||
show_error: bool = False,
|
||||
server_name: Optional[str] = None,
|
||||
server_port: Optional[int] = None,
|
||||
show_tips: bool = False,
|
||||
@ -839,7 +840,7 @@ class Blocks(BlockContext):
|
||||
auth: If provided, username and password (or list of username-password tuples) required to access interface. Can also provide function that takes username and password and returns True if valid login.
|
||||
auth_message: If provided, HTML message provided on login page.
|
||||
prevent_thread_lock: If True, the interface will block the main thread while the server is running.
|
||||
show_error: If True, any errors in the interface will be printed in the browser console log
|
||||
show_error: If True, any errors in the interface will be displayed in an alert modal and printed in the browser console log
|
||||
server_port: will start gradio app on this port (if available). Can be set by environment variable GRADIO_SERVER_PORT. If None, will search for an available port starting at 7860.
|
||||
server_name: to make app accessible on local network, set this to "0.0.0.0". Can be set by environment variable GRADIO_SERVER_NAME. If None, will use "127.0.0.1".
|
||||
show_tips: if True, will occasionally show tips about new Gradio features
|
||||
@ -886,9 +887,9 @@ class Blocks(BlockContext):
|
||||
DeprecationWarning,
|
||||
)
|
||||
if self.is_space:
|
||||
self.enable_queue = enable_queue is not False
|
||||
self.enable_queue = self.enable_queue is not False
|
||||
else:
|
||||
self.enable_queue = enable_queue is True
|
||||
self.enable_queue = self.enable_queue is True
|
||||
|
||||
self.config = self.get_config_file()
|
||||
self.share = share
|
||||
|
@ -258,9 +258,15 @@ class Queue:
|
||||
json=event.data,
|
||||
)
|
||||
end_time = time.time()
|
||||
cls.update_estimation(end_time - begin_time)
|
||||
success = response.status == 200
|
||||
if success:
|
||||
cls.update_estimation(end_time - begin_time)
|
||||
client_awake = await event.send_message(
|
||||
{"msg": "process_completed", "output": response.json}
|
||||
{
|
||||
"msg": "process_completed",
|
||||
"output": response.json,
|
||||
"success": success,
|
||||
}
|
||||
)
|
||||
if client_awake:
|
||||
run_coro_in_background(cls.wait_in_inactive, event)
|
||||
|
7
gradio/exceptions.py
Normal file
7
gradio/exceptions.py
Normal file
@ -0,0 +1,7 @@
|
||||
class Error(Exception):
|
||||
def __init__(self, message: str):
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
def __str__(self):
|
||||
return repr(self.message)
|
@ -29,6 +29,7 @@ from starlette.websockets import WebSocket, WebSocketState
|
||||
import gradio
|
||||
from gradio import encryptor
|
||||
from gradio.event_queue import Estimation, Event, Queue
|
||||
from gradio.exceptions import Error
|
||||
|
||||
STATIC_TEMPLATE_LIB = pkg_resources.resource_filename("gradio", "templates/")
|
||||
STATIC_PATH_LIB = pkg_resources.resource_filename("gradio", "templates/frontend/static")
|
||||
@ -241,18 +242,21 @@ class App(FastAPI):
|
||||
session_state = app.state_holder[body.session_hash]
|
||||
else:
|
||||
session_state = {}
|
||||
raw_input = body.data
|
||||
fn_index = body.fn_index
|
||||
try:
|
||||
raw_input = body.data
|
||||
fn_index = body.fn_index
|
||||
output = await app.blocks.process_api(
|
||||
fn_index, raw_input, username, session_state
|
||||
)
|
||||
if isinstance(output, Error):
|
||||
raise output
|
||||
except BaseException as error:
|
||||
if app.blocks.show_error:
|
||||
traceback.print_exc()
|
||||
return JSONResponse(content={"error": str(error)}, status_code=500)
|
||||
else:
|
||||
raise error
|
||||
show_error = app.blocks.show_error or isinstance(error, Error)
|
||||
traceback.print_exc()
|
||||
return JSONResponse(
|
||||
content={"error": str(error) if show_error else None},
|
||||
status_code=500,
|
||||
)
|
||||
return output
|
||||
|
||||
@app.post("/api/{api_name}", dependencies=[Depends(login_check)])
|
||||
|
@ -1 +1 @@
|
||||
3.1.6
|
||||
3.1.6b1
|
||||
|
@ -11,6 +11,10 @@ $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`).
|
||||
|
||||
## Errors
|
||||
|
||||
You wish to pass custom error messages to the user. To do so, raise a `gr.Error("custom message")` to display an error message. If you try to divide by zero in the the calculator demo above, a popup modal will display the custom error message.
|
||||
|
||||
## 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.
|
||||
|
@ -35,7 +35,6 @@
|
||||
export let target: HTMLElement;
|
||||
export let id: number = 0;
|
||||
export let autoscroll: boolean = false;
|
||||
export let show_error: boolean = false;
|
||||
let app_mode = window.__gradio_mode__ === "app";
|
||||
let loading_status = create_loading_status_store();
|
||||
|
||||
|
@ -46,7 +46,6 @@ async function post_data(
|
||||
body: JSON.stringify(body),
|
||||
headers: { "Content-Type": "application/json" }
|
||||
});
|
||||
|
||||
const output: PostResponse = await response.json();
|
||||
return [output, response.status];
|
||||
}
|
||||
@ -64,12 +63,7 @@ type Output = {
|
||||
const ws_map = new Map();
|
||||
|
||||
export const fn =
|
||||
(
|
||||
session_hash: string,
|
||||
api_endpoint: string,
|
||||
is_space: boolean,
|
||||
show_error: boolean
|
||||
) =>
|
||||
(session_hash: string, api_endpoint: string, is_space: boolean) =>
|
||||
async ({
|
||||
action,
|
||||
payload,
|
||||
@ -177,14 +171,16 @@ export const fn =
|
||||
case "process_completed":
|
||||
loading_status.update(
|
||||
fn_index,
|
||||
"complete",
|
||||
data.success ? "complete" : "error",
|
||||
queue,
|
||||
null,
|
||||
null,
|
||||
data.output.average_duration,
|
||||
null
|
||||
!data.success ? data.output.error : null
|
||||
);
|
||||
queue_callback(data.output);
|
||||
if (data.success) {
|
||||
queue_callback(data.output);
|
||||
}
|
||||
websocket_data.connection.close();
|
||||
break;
|
||||
case "process_starts":
|
||||
@ -233,8 +229,9 @@ export const fn =
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
show_error ? output.error : null
|
||||
output.error
|
||||
);
|
||||
throw output.error || "API Error";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
@ -64,6 +64,7 @@
|
||||
let timer_start = 0;
|
||||
let timer_diff = 0;
|
||||
let old_eta: number | null = null;
|
||||
let message_visible: boolean = false;
|
||||
|
||||
$: progress =
|
||||
eta === null || eta <= 0 || !timer_diff
|
||||
@ -121,6 +122,19 @@
|
||||
old_eta = eta;
|
||||
}
|
||||
}
|
||||
let show_message_timeout: NodeJS.Timeout | null = null;
|
||||
const close_message = () => {
|
||||
message_visible = false;
|
||||
if (show_message_timeout !== null) {
|
||||
clearTimeout(show_message_timeout);
|
||||
}
|
||||
};
|
||||
$: {
|
||||
if (status === "error" && message) {
|
||||
message_visible = true;
|
||||
show_message_timeout = setTimeout(close_message, 8000);
|
||||
}
|
||||
}
|
||||
$: formatted_timer = timer_diff.toFixed(1);
|
||||
</script>
|
||||
|
||||
@ -151,8 +165,22 @@
|
||||
{/if}
|
||||
{:else if status === "error"}
|
||||
<span class="error">ERROR</span>
|
||||
{#if message}
|
||||
<span class="status-message dark:text-gray-100">{message}</span>
|
||||
{#if message_visible}
|
||||
<div
|
||||
class="flex flex-col items-center fixed z-[100] w-full left-0 top-12 mx-auto font-mono whitespace-pre-wrap pointer-events-auto"
|
||||
>
|
||||
<div
|
||||
class="p-3 w-4/5 text-xl rounded-t bg-red-300 text-red-700 status-title flex justify-between items-center"
|
||||
>
|
||||
<span>Error</span>
|
||||
<button on:click={close_message}>✖</button>
|
||||
</div>
|
||||
<div
|
||||
class="px-3 w-4/5 py-4 rounded-b bg-gray-200 border-gray-100 dark:bg-gray-700 dark:border-gray-800 dark:text-gray-100"
|
||||
>
|
||||
{message}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
@ -181,8 +209,4 @@
|
||||
.error {
|
||||
@apply text-red-400 font-mono font-semibold text-lg;
|
||||
}
|
||||
|
||||
.status-message {
|
||||
@apply font-mono p-2 whitespace-pre;
|
||||
}
|
||||
</style>
|
||||
|
@ -34,7 +34,6 @@ interface Config {
|
||||
title: string;
|
||||
version: string;
|
||||
is_space: boolean;
|
||||
show_error: boolean;
|
||||
// allow_flagging: string;
|
||||
// allow_interpretation: boolean;
|
||||
// article: string;
|
||||
@ -184,12 +183,7 @@ function mount_app(
|
||||
});
|
||||
} else {
|
||||
let session_hash = Math.random().toString(36).substring(2);
|
||||
config.fn = fn(
|
||||
session_hash,
|
||||
config.root + "api/",
|
||||
config.is_space,
|
||||
config.show_error
|
||||
);
|
||||
config.fn = fn(session_hash, config.root + "api/", config.is_space);
|
||||
|
||||
new Blocks({
|
||||
target: wrapper,
|
||||
|
@ -69,7 +69,7 @@
|
||||
}
|
||||
|
||||
.gr-button-primary {
|
||||
@apply from-orange-200/70 to-orange-300/80 hover:from-orange-200/90 text-orange-600 border-orange-200
|
||||
@apply from-orange-200/70 to-orange-300/80 hover:to-orange-200/90 text-orange-600 border-orange-200
|
||||
dark:from-orange-700 dark:to-orange-700 dark:hover:to-orange-500 dark:text-white dark:border-orange-600;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user