From 04a076439477081683e6f87c73b6672798d4f7f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20=C3=96zdemir?= Date: Tue, 14 Jun 2022 22:18:59 +0300 Subject: [PATCH] Handle async funcs within sync scopes (#1547) * handle_async_funcs - save temporary work * handle_async_funcs - handle async functions in sync domain both in background or sync * handle_async_funcs - tweaks * handle_async_funcs - format * handle_async_funcs - tweaks * handle_async_funcs - fixes * revert gradio.egg files * added to requires Co-authored-by: Abubakar Abid --- gradio.egg-info/requires.txt | 1 + gradio/blocks.py | 7 +++---- gradio/utils.py | 36 +++++++++++++++++++++++++++++++++--- setup.py | 3 ++- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/gradio.egg-info/requires.txt b/gradio.egg-info/requires.txt index 22332f075c..20089b7116 100644 --- a/gradio.egg-info/requires.txt +++ b/gradio.egg-info/requires.txt @@ -2,6 +2,7 @@ analytics-python aiohttp fastapi ffmpy +fsspec markdown-it-py[linkify,plugins] matplotlib numpy diff --git a/gradio/blocks.py b/gradio/blocks.py index 41cebbf00f..bf6fe34c1f 100644 --- a/gradio/blocks.py +++ b/gradio/blocks.py @@ -1,5 +1,6 @@ from __future__ import annotations +import asyncio import copy import getpass import inspect @@ -375,9 +376,7 @@ class Blocks(BlockContext): processed_input = self.preprocess_data(fn_index, serialized_params, None) if inspect.iscoroutinefunction(block_fn.fn): - raise ValueError( - "Cannot call Blocks object as a function if the function is a coroutine" - ) + predictions = utils.synchronize_async(block_fn.fn, *processed_input) else: predictions = block_fn.fn(*processed_input) @@ -745,7 +744,7 @@ class Blocks(BlockContext): self.enable_queue = True else: self.enable_queue = enable_queue or False - utils.synchronize_async(self.create_limiter, max_threads) + utils.run_coro_in_background(self.create_limiter, max_threads) self.config = self.get_config_file() self.share = share self.encrypt = encrypt diff --git a/gradio/utils.py b/gradio/utils.py index a695a7e05d..21ca8e6710 100644 --- a/gradio/utils.py +++ b/gradio/utils.py @@ -16,6 +16,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, List import aiohttp import analytics +import fsspec.asyn import pkg_resources import requests @@ -312,7 +313,36 @@ def component_or_layout_class(cls_name: str) -> Component | BlockContext: raise ValueError(f"No such component or layout: {cls_name}") -def synchronize_async(func: Callable, *args: object, callback_func: Callable = None): +def synchronize_async(func: Callable, *args, **kwargs): + """ + Runs async functions in sync scopes. + + Example: + if inspect.iscoroutinefunction(block_fn.fn): + predictions = utils.synchronize_async(block_fn.fn, *processed_input) + + Args: + func: + *args: + **kwargs: + """ + return fsspec.asyn.sync(fsspec.asyn.get_loop(), func, *args, **kwargs) + + +def run_coro_in_background(func: Callable, *args, **kwargs): + """ + Runs coroutines in background. + + Example: + utils.run_coro_in_background(fn, *args, **kwargs) + + Args: + func: + *args: + **kwargs: + + Returns: + + """ event_loop = asyncio.get_event_loop() - task = event_loop.create_task(func(*args)) - task.add_done_callback(callback_func) + _ = event_loop.create_task(func(*args, **kwargs)) diff --git a/setup.py b/setup.py index 9e4cc95999..02fa917592 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,8 @@ setup( "pydub", "requests", "uvicorn", - "Jinja2" + "Jinja2", + "fsspec", ], entry_points={ 'console_scripts': ['gradio=gradio.reload:run_in_reload_mode']