yangwang825 commited on
Commit
d3b96ce
·
verified ·
1 Parent(s): d84dbda

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -1
app.py CHANGED
@@ -1,6 +1,131 @@
 
 
 
 
 
 
1
  import evaluate
2
- from evaluate.utils import launch_gradio_widget
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
 
4
 
 
5
  module = evaluate.load("yangwang825/datastats")
6
  launch_gradio_widget(module)
 
1
+ import os
2
+ import re
3
+ import sys
4
+ import json
5
+ from pathlib import Path
6
+
7
  import evaluate
8
+ import numpy as np
9
+ from datasets import Value
10
+
11
+ REGEX_YAML_BLOCK = re.compile(r"---[\n\r]+([\S\s]*?)[\n\r]+---[\n\r]")
12
+
13
+
14
+ def infer_gradio_input_types(feature_types):
15
+ """
16
+ Maps metric feature types to input types for gradio Dataframes:
17
+ - float/int -> numbers
18
+ - string -> strings
19
+ - any other -> json
20
+ Note that json is not a native gradio type but will be treated as string that
21
+ is then parsed as a json.
22
+ """
23
+ input_types = []
24
+ for feature_type in feature_types:
25
+ input_type = "json"
26
+ if isinstance(feature_type, Value):
27
+ if feature_type.dtype.startswith("int") or feature_type.dtype.startswith("float"):
28
+ input_type = "number"
29
+ elif feature_type.dtype == "string":
30
+ input_type = "str"
31
+ input_types.append(input_type)
32
+ return input_types
33
+
34
+
35
+ def json_to_string_type(input_types):
36
+ """Maps json input type to str."""
37
+ return ["str" if i == "json" else i for i in input_types]
38
+
39
+
40
+ def parse_readme(filepath):
41
+ """Parses a repositories README and removes"""
42
+ if not os.path.exists(filepath):
43
+ return "No README.md found."
44
+ with open(filepath, "r") as f:
45
+ text = f.read()
46
+ match = REGEX_YAML_BLOCK.search(text)
47
+ if match:
48
+ text = text[match.end() :]
49
+ return text
50
+
51
+
52
+ def parse_gradio_data(data, input_types):
53
+ """Parses data from gradio Dataframe for use in metric."""
54
+ metric_inputs = {}
55
+ data.replace("", np.nan, inplace=True)
56
+ data.dropna(inplace=True)
57
+ for feature_name, input_type in zip(data, input_types):
58
+ if input_type == "json":
59
+ metric_inputs[feature_name] = [json.loads(d) for d in data[feature_name].to_list()]
60
+ elif input_type == "str":
61
+ metric_inputs[feature_name] = [d.strip('"') for d in data[feature_name].to_list()]
62
+ else:
63
+ metric_inputs[feature_name] = data[feature_name]
64
+ return metric_inputs
65
+
66
+
67
+ def parse_test_cases(test_cases, feature_names, input_types):
68
+ """
69
+ Parses test cases to be used in gradio Dataframe. Note that an apostrophe is added
70
+ to strings to follow the format in json.
71
+ """
72
+ if len(test_cases) == 0:
73
+ return None
74
+ examples = []
75
+ for test_case in test_cases:
76
+ parsed_cases = []
77
+ for feat, input_type in zip(feature_names, input_types):
78
+ if input_type == "json":
79
+ parsed_cases.append([str(element) for element in test_case[feat]])
80
+ elif input_type == "str":
81
+ parsed_cases.append(['"' + element + '"' for element in test_case[feat]])
82
+ else:
83
+ parsed_cases.append(test_case[feat])
84
+ examples.append([list(i) for i in zip(*parsed_cases)])
85
+ return examples
86
+
87
+
88
+ def launch_gradio_widget(metric):
89
+ """Launches `metric` widget with Gradio."""
90
+
91
+ try:
92
+ import gradio as gr
93
+ except ImportError as error:
94
+ print("To create a metric widget with Gradio make sure gradio is installed.")
95
+ raise error
96
+
97
+ local_path = Path(sys.path[0])
98
+ # if there are several input types, use first as default.
99
+ if isinstance(metric.features, list):
100
+ (feature_names, feature_types) = zip(*metric.features[0].items())
101
+ else:
102
+ (feature_names, feature_types) = zip(*metric.features.items())
103
+ gradio_input_types = infer_gradio_input_types(feature_types)
104
+
105
+ def compute(data):
106
+ return metric.compute(**parse_gradio_data(data, gradio_input_types))
107
+
108
+ iface = gr.Interface(
109
+ fn=compute,
110
+ inputs=gr.components.Dataframe(
111
+ headers=feature_names,
112
+ col_count=len(feature_names),
113
+ row_count=1,
114
+ datatype=json_to_string_type(gradio_input_types),
115
+ ),
116
+ outputs=gr.components.Textbox(label=metric.name),
117
+ description=(
118
+ metric.info.description + "\nIf this is a text-based metric, make sure to wrap you input in double quotes."
119
+ " Alternatively you can use a JSON-formatted list as input."
120
+ ),
121
+ title=f"Metric: {metric.name}",
122
+ article=parse_readme(local_path / "README.md"),
123
+ # TODO: load test cases and use them to populate examples
124
+ # examples=[parse_test_cases(test_cases, feature_names, gradio_input_types)]
125
+ )
126
 
127
+ iface.launch()
128
 
129
+
130
  module = evaluate.load("yangwang825/datastats")
131
  launch_gradio_widget(module)