Block-Components

- adopt inputs.Number
- format backend
This commit is contained in:
Ömer Faruk Özdemir 2022-03-09 11:47:30 +03:00
parent fb068d4598
commit 00b846e7e6
3 changed files with 50 additions and 105 deletions

View File

@ -17,11 +17,13 @@ class Component(Block):
"""
def __init__(
self, *,
label: str, requires_permissions: bool = False,
self,
*,
label: str,
requires_permissions: bool = False,
**kwargs,
):
if 'optional' in kwargs:
if "optional" in kwargs:
warnings.warn("Usage of optional is deprecated, and it has no effect")
self.label = label
self.requires_permissions = requires_permissions
@ -215,12 +217,12 @@ class Textbox(Component):
numeric (bool): DEPRECATED.
type (str): DEPRECATED.
"""
if numeric in kwargs:
if "numeric" in kwargs:
warnings.warn(
"The 'numeric' type has been deprecated. Use the Number component instead.",
DeprecationWarning,
)
if type in kwargs:
if "type" in kwargs:
warnings.warn(
"The 'type' parameter has been deprecated. Use the Number component instead if you need it.",
DeprecationWarning,
@ -366,6 +368,7 @@ class Number(Component):
default: Optional[float] = None,
*,
label: Optional[str] = None,
**kwargs,
):
"""
Parameters:
@ -458,7 +461,7 @@ class Number(Component):
else:
return float(y)
def deserialize(self, x):
def deserialize(self, y):
"""
Convert from serialized output (e.g. base64 representation) from a call() to the interface to a human-readable version of the output (path of an image, etc.)
"""

View File

@ -19,7 +19,7 @@ import PIL
from ffmpy import FFmpeg
from gradio import processing_utils, test_data
from gradio.components import Component, Textbox
from gradio.components import Component, Number, Textbox
if TYPE_CHECKING: # Only import for type checking (is False at runtime).
from gradio import Interface
@ -27,7 +27,6 @@ if TYPE_CHECKING: # Only import for type checking (is False at runtime).
# TODO: (faruk) Remove this file in version 3.0
class Textbox(Textbox):
def __init__(
self,
lines: int = 1,
@ -38,7 +37,10 @@ class Textbox(Textbox):
label: Optional[str] = None,
optional: bool = False,
):
warnings.warn("Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components", DeprecationWarning)
warnings.warn(
"Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components",
DeprecationWarning,
)
super().__init__(
lines=lines,
placeholder=placeholder,
@ -50,6 +52,32 @@ class Textbox(Textbox):
)
class Number(Number):
"""
Component creates a field for user to enter numeric input. Provides a number as an argument to the wrapped function.
Input type: float
Demos: tax_calculator, titanic_survival
"""
def __init__(
self,
default: Optional[float] = None,
label: Optional[str] = None,
optional: bool = False,
):
"""
Parameters:
default (float): default value.
label (str): component name in interface.
optional (bool): If True, the interface can be submitted with no value for this component.
"""
warnings.warn(
"Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components",
DeprecationWarning,
)
super().__init__(default=default, label=label, optional=optional)
class InputComponent(Component):
"""
Input Component. All input components subclass this.
@ -133,97 +161,6 @@ class InputComponent(Component):
}
class Number(InputComponent):
"""
Component creates a field for user to enter numeric input. Provides a number as an argument to the wrapped function.
Input type: float
Demos: tax_calculator, titanic_survival
"""
def __init__(
self,
default: Optional[float] = None,
label: Optional[str] = None,
optional: bool = False,
):
"""
Parameters:
default (float): default value.
label (str): component name in interface.
optional (bool): If True, the interface can be submitted with no value for this component.
"""
self.default = default
self.test_input = default if default is not None else 1
self.interpret_by_tokens = False
super().__init__(label, optional=optional)
def get_template_context(self):
return {"default": self.default, **super().get_template_context()}
@classmethod
def get_shortcut_implementations(cls):
return {
"number": {},
}
def preprocess(self, x: Optional[Number]) -> Optional[float]:
"""
Parameters:
x (string): numeric input as a string
Returns:
(float): number representing function input
"""
if self.optional and x is None:
return None
return float(x)
def preprocess_example(self, x: float) -> float:
"""
Returns:
(float): Number representing function input
"""
return x
def set_interpret_parameters(
self, steps: int = 3, delta: float = 1, delta_type: str = "percent"
):
"""
Calculates interpretation scores of numeric values close to the input number.
Parameters:
steps (int): Number of nearby values to measure in each direction (above and below the input number).
delta (float): Size of step in each direction between nearby values.
delta_type (str): "percent" if delta step between nearby values should be a calculated as a percent, or "absolute" if delta should be a constant step change.
"""
self.interpretation_steps = steps
self.interpretation_delta = delta
self.interpretation_delta_type = delta_type
return self
def get_interpretation_neighbors(self, x: Number) -> Tuple[List[float], Dict]:
x = float(x)
if self.interpretation_delta_type == "percent":
delta = 1.0 * self.interpretation_delta * x / 100
elif self.interpretation_delta_type == "absolute":
delta = self.interpretation_delta
negatives = (x + np.arange(-self.interpretation_steps, 0) * delta).tolist()
positives = (x + np.arange(1, self.interpretation_steps + 1) * delta).tolist()
return negatives + positives, {}
def get_interpretation_scores(
self, x: Number, neighbors: List[float], scores: List[float]
) -> List[Tuple[float, float]]:
"""
Returns:
(List[Tuple[float, float]]): Each tuple set represents a numeric value near the input and its corresponding interpretation score.
"""
interpretation = list(zip(neighbors, scores))
interpretation.insert(int(len(interpretation) / 2), [x, None])
return interpretation
def generate_sample(self) -> float:
return 1.0
class Slider(InputComponent):
"""
Component creates a slider that ranges from `minimum` to `maximum`. Provides a number as an argument to the wrapped function.
@ -254,7 +191,7 @@ class Slider(InputComponent):
if step is None:
difference = maximum - minimum
power = math.floor(math.log10(difference) - 2)
step = 10 ** power
step = 10**power
self.step = step
self.default = minimum if default is None else default
self.test_input = self.default
@ -947,7 +884,7 @@ class Video(InputComponent):
file_name = file.name
uploaded_format = file_name.split(".")[-1].lower()
if self.type is not None and uploaded_format != self.type:
output_file_name = file_name[0: file_name.rindex(".") + 1] + self.type
output_file_name = file_name[0 : file_name.rindex(".") + 1] + self.type
ff = FFmpeg(inputs={file_name: None}, outputs={output_file_name: None})
ff.run()
return output_file_name

View File

@ -29,10 +29,15 @@ if TYPE_CHECKING: # Only import for type checking (is False at runtime).
class Textbox(Textbox):
def __init__(
self, type: str = "auto", label: Optional[str] = None,
self,
type: str = "auto",
label: Optional[str] = None,
):
# TODO: (faruk) Remove this file in version 3.0
warnings.warn("Usage of gradio.outputs is deprecated, and will not be supported in the future, please import your components from gradio.components", DeprecationWarning)
warnings.warn(
"Usage of gradio.outputs is deprecated, and will not be supported in the future, please import your components from gradio.components",
DeprecationWarning,
)
super().__init__(type=type, label=label)
@ -270,7 +275,7 @@ class Video(OutputComponent):
"""
returned_format = y.split(".")[-1].lower()
if self.type is not None and returned_format != self.type:
output_file_name = y[0: y.rindex(".") + 1] + self.type
output_file_name = y[0 : y.rindex(".") + 1] + self.type
ff = FFmpeg(inputs={y: None}, outputs={output_file_name: None})
ff.run()
y = output_file_name