Restore queue in Blocks (#1137)

* first commit

* format

* fix tests

Co-authored-by: Ali Abid <aliabid94@gmail.com>
This commit is contained in:
aliabid94 2022-05-02 16:17:53 -07:00 committed by GitHub
parent 87dcdd7134
commit b0306e716d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 42 deletions

View File

@ -228,6 +228,7 @@ class Blocks(BlockContext):
theme: str = "default",
analytics_enabled: Optional[bool] = None,
mode: str = "blocks",
enable_queue: bool = False,
**kwargs,
):
@ -258,6 +259,10 @@ class Blocks(BlockContext):
self.ip_address = utils.get_local_ip_address()
self.is_space = True if os.getenv("SYSTEM") == "spaces" else False
self.favicon_path = None
if self.is_space and enable_queue is None:
self.enable_queue = True
else:
self.enable_queue = enable_queue or False
def render(self):
if Context.root_block is not None:
@ -328,7 +333,12 @@ class Blocks(BlockContext):
return {"type": "column"}
def get_config_file(self):
config = {"mode": "blocks", "components": [], "theme": self.theme}
config = {
"mode": "blocks",
"components": [],
"theme": self.theme,
"queue": self.enable_queue,
}
for _id, block in self.blocks.items():
config["components"].append(
{
@ -404,7 +414,6 @@ class Blocks(BlockContext):
server_name: Optional[str] = None,
server_port: Optional[int] = None,
show_tips: bool = False,
enable_queue: Optional[bool] = None,
height: int = 500,
width: int = 900,
encrypt: bool = False,
@ -428,10 +437,6 @@ class Blocks(BlockContext):
server_port (int): will start gradio app on this port (if available). Can be set by environment variable GRADIO_SERVER_PORT.
server_name (str): to make app accessible on local network, set this to "0.0.0.0". Can be set by environment variable GRADIO_SERVER_NAME.
show_tips (bool): if True, will occasionally show tips about new Gradio features
enable_queue (Optional[bool]):
if True, inference requests will be served through a queue instead of with parallel threads. Required for longer inference times (> 1min) to prevent timeout.
The default option in HuggingFace Spaces is True.
The default option elsewhere is False.
width (int): The width in pixels of the iframe element containing the interface (used if inline=True)
height (int): The height in pixels of the iframe element containing the interface (used if inline=True)
encrypt (bool): If True, flagged data will be encrypted by key provided by creator at launch
@ -466,11 +471,6 @@ class Blocks(BlockContext):
getpass.getpass("Enter key for encryption: ")
)
if self.is_space and enable_queue is None:
self.enable_queue = True
else:
self.enable_queue = enable_queue or False
config = self.get_config_file()
self.config = config

View File

@ -110,7 +110,7 @@ def pop() -> Tuple[int, str, Dict, str]:
def push(body: QueuePushBody) -> Tuple[str, int]:
action = body.action
input_data = json.dumps({"data": body.data})
input_data = json.dumps(body.__dict__)
hash = generate_hash()
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()

View File

@ -61,7 +61,9 @@ class QueueStatusBody(BaseModel):
class QueuePushBody(BaseModel):
fn_index: int
action: str
session_hash: str
data: Any

View File

@ -16,9 +16,9 @@ XRAY_CONFIG = {
"props": {
"choices": ["Covid", "Malaria", "Lung Cancer"],
"default_value": [],
"name": "checkboxgroup",
"show_label": True,
"label": "Disease to Scan For",
"show_label": True,
"name": "checkboxgroup",
"css": {},
},
},
@ -26,11 +26,7 @@ XRAY_CONFIG = {
{
"id": 4,
"type": "tabitem",
"props": {
"label": "X-ray",
"css": {},
"default_value": True,
},
"props": {"label": "X-ray", "css": {}, "default_value": True},
},
{
"id": 5,
@ -41,10 +37,10 @@ XRAY_CONFIG = {
"id": 6,
"type": "image",
"props": {
"show_label": True,
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"show_label": True,
"name": "image",
"css": {},
},
@ -53,8 +49,8 @@ XRAY_CONFIG = {
"id": 7,
"type": "json",
"props": {
"show_label": True,
"default_value": '""',
"show_label": True,
"name": "json",
"css": {},
},
@ -71,11 +67,7 @@ XRAY_CONFIG = {
{
"id": 9,
"type": "tabitem",
"props": {
"label": "CT Scan",
"css": {},
"default_value": True,
},
"props": {"label": "CT Scan", "css": {}, "default_value": True},
},
{
"id": 10,
@ -86,10 +78,10 @@ XRAY_CONFIG = {
"id": 11,
"type": "image",
"props": {
"show_label": True,
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"show_label": True,
"name": "image",
"css": {},
},
@ -98,8 +90,8 @@ XRAY_CONFIG = {
"id": 12,
"type": "json",
"props": {
"show_label": True,
"default_value": '""',
"show_label": True,
"name": "json",
"css": {},
},
@ -107,26 +99,23 @@ XRAY_CONFIG = {
{
"id": 13,
"type": "button",
"props": {
"default_value": "Run",
"name": "button",
"css": {},
},
"props": {"default_value": "Run", "name": "button", "css": {}},
},
{
"id": 14,
"type": "textbox",
"props": {
"lines": 1,
"show_label": True,
"max_lines": 20,
"default_value": "",
"show_label": True,
"name": "textbox",
"css": {},
},
},
],
"theme": "default",
"queue": False,
"layout": {
"id": 0,
"children": [

View File

@ -31,10 +31,14 @@ class TestQueuingActions(unittest.TestCase):
queueing.close()
def test_push_pop_status(self):
request = QueuePushBody(data="test1", action="predict")
request = QueuePushBody(
data="test1", action="predict", fn_index=0, session_hash="-"
)
hash1, position = queueing.push(request)
self.assertEquals(position, 0)
request = QueuePushBody(data="test2", action="predict")
request = QueuePushBody(
data="test2", action="predict", fn_index=0, session_hash="-"
)
hash2, position = queueing.push(request)
self.assertEquals(position, 1)
status, position = queueing.get_status(hash2)
@ -42,11 +46,16 @@ class TestQueuingActions(unittest.TestCase):
self.assertEquals(position, 1)
_, hash_popped, input_data, action = queueing.pop()
self.assertEquals(hash_popped, hash1)
self.assertEquals(input_data, {"data": "test1"})
self.assertEquals(
input_data,
{"action": "predict", "data": "test1", "fn_index": 0, "session_hash": "-"},
)
self.assertEquals(action, "predict")
def test_jobs(self):
request = QueuePushBody(data="test1", action="predict")
request = QueuePushBody(
data="test1", action="predict", fn_index=0, session_hash="-"
)
hash1, _ = queueing.push(request)
hash2, position = queueing.push(request)
self.assertEquals(position, 1)

View File

@ -71,7 +71,8 @@ class TestRoutes(unittest.TestCase):
def test_queue_push_route(self):
queueing.push = mock.MagicMock(return_value=(None, None))
response = self.client.post(
"/api/queue/push/", json={"data": "test", "action": "test"}
"/api/queue/push/",
json={"data": "test", "action": "test", "fn_index": 0, "session_hash": "-"},
)
self.assertEqual(response.status_code, 200)

View File

@ -28,7 +28,6 @@
targets: Array<number>;
inputs: Array<number>;
outputs: Array<number>;
queue: boolean;
status_tracker: number | null;
status?: string;
}
@ -40,6 +39,7 @@
export let dependencies: Array<Dependency>;
export let theme: string;
export let style: string | null;
export let queue: boolean;
export let static_src: string;
const dynamic_ids = dependencies.reduce((acc, next) => {
@ -126,7 +126,7 @@
async function handle_mount({ detail }) {
await tick();
dependencies.forEach(({ targets, trigger, inputs, outputs, queue }, i) => {
dependencies.forEach(({ targets, trigger, inputs, outputs }, i) => {
const target_instances: [number, Instance][] = targets.map((t) => [
t,
instance_map[t]

View File

@ -54,7 +54,7 @@ interface Config {
space?: string;
detail: string;
dark: boolean;
auth_required: boolean;
enable_queue: boolean;
}
window.launchGradio = (config: Config, element_query: string) => {