From 41701da4a4f31aaa5c707d5e5913831f2c5cc27b Mon Sep 17 00:00:00 2001 From: aliabd Date: Wed, 22 Jul 2020 16:32:22 -0700 Subject: [PATCH 1/7] added flagging to frontend, backend working for image to label --- gradio/inputs.py | 15 +++++++++++++++ gradio/networking.py | 12 +----------- gradio/outputs.py | 11 +++++++++++ gradio/static/css/gradio.css | 4 ++++ gradio/static/js/all_io.js | 4 ++-- gradio/static/js/gradio.js | 16 ++++++++++++++-- 6 files changed, 47 insertions(+), 15 deletions(-) diff --git a/gradio/inputs.py b/gradio/inputs.py index a130642f61..62fac86a19 100644 --- a/gradio/inputs.py +++ b/gradio/inputs.py @@ -63,6 +63,11 @@ class AbstractInput(ABC): """ return {} + def rebuild_flagged(self, dir, msg): + """ + All interfaces should define a method that rebuilds the flagged input when it's passed back (i.e. rebuilds image from base64) + """ + pass class Textbox(AbstractInput): """ @@ -290,6 +295,16 @@ class Image(AbstractInput): else: return example + def rebuild_flagged(self, dir, msg): + """ + Default rebuild method to decode a base64 image + """ + im = preprocessing_utils.decode_base64_to_image(msg) + timestamp = datetime.datetime.now() + filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' + im.save(f'{dir}/{filename}', 'PNG') + return filename + class Sketchpad(AbstractInput): """ diff --git a/gradio/networking.py b/gradio/networking.py index ecae3abad3..3a36a4ced1 100644 --- a/gradio/networking.py +++ b/gradio/networking.py @@ -36,7 +36,7 @@ CONFIG_FILE = "static/config.json" ASSOCIATION_PATH_IN_STATIC = "static/apple-app-site-association" ASSOCIATION_PATH_IN_ROOT = "apple-app-site-association" -FLAGGING_DIRECTORY = 'static/flagged/' +FLAGGING_DIRECTORY = 'flagged/' FLAGGING_FILENAME = 'data.txt' analytics.write_key = "uxIFddIEuuUcFLf9VgH2teTEtPlWdkNy" analytics_url = 'https://api.gradio.app/' @@ -175,16 +175,6 @@ def serve_files_in_background(interface, port, directory_to_serve=None, server_n if interface.saliency is not None: saliency = interface.saliency(raw_input, prediction) output['saliency'] = saliency.tolist() - # if interface.always_flag: - # msg = json.loads(data_string) - # flag_dir = os.path.join(FLAGGING_DIRECTORY, str(interface.hash)) - # os.makedirs(flag_dir, exist_ok=True) - # output_flag = {'input': interface.input_interface.rebuild_flagged(flag_dir, msg['data']), - # 'output': interface.output_interface.rebuild_flagged(flag_dir, processed_output), - # } - # with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f: - # f.write(json.dumps(output_flag)) - # f.write("\n") self.wfile.write(json.dumps(output).encode()) diff --git a/gradio/outputs.py b/gradio/outputs.py index df68483ba2..553b93c7b3 100644 --- a/gradio/outputs.py +++ b/gradio/outputs.py @@ -44,6 +44,12 @@ class AbstractOutput(ABC): """ return {} + def rebuild_flagged(self, dir, msg): + """ + All interfaces should define a method that rebuilds the flagged input when it's passed back (i.e. rebuilds image from base64) + """ + pass + class Textbox(AbstractOutput): ''' @@ -130,6 +136,11 @@ class Label(AbstractOutput): "label": {}, } + def rebuild_flagged(self, dir, msg): + """ + Default rebuild method for label + """ + return json.loads(msg) class Image(AbstractOutput): ''' diff --git a/gradio/static/css/gradio.css b/gradio/static/css/gradio.css index be4b7332e9..06293cc3d1 100644 --- a/gradio/static/css/gradio.css +++ b/gradio/static/css/gradio.css @@ -75,6 +75,10 @@ input.submit { input.submit:hover { background-color: #f39c12; } + +.flag.flagged { + background-color: pink; +} /* label:hover { background-color: lightgray; } */ diff --git a/gradio/static/js/all_io.js b/gradio/static/js/all_io.js index 7a7ca9eae7..52ebe0ecc7 100644 --- a/gradio/static/js/all_io.js +++ b/gradio/static/js/all_io.js @@ -56,12 +56,12 @@ var io_master_template = { this.target.find(".output_interfaces").css("opacity", 1); } }, - flag: function(message) { + flag: function() { var post_data = { 'data': { 'input_data' : toStringIfObject(this.last_input) , 'output_data' : toStringIfObject(this.last_output), - 'message' : message + 'message' : "no-message" } } $.ajax({type: "POST", diff --git a/gradio/static/js/gradio.js b/gradio/static/js/gradio.js index e21cfeb93f..eb4061343c 100644 --- a/gradio/static/js/gradio.js +++ b/gradio/static/js/gradio.js @@ -22,7 +22,7 @@ function gradio(config, fn, target) { - + `); let io_master = Object.create(io_master_template); @@ -117,6 +117,7 @@ function gradio(config, fn, target) { output_interface.clear(); } target.find(".flag").removeClass("flagged"); + target.find(".flag").val("FLAG"); target.find(".flag_message").empty(); target.find(".loading").addClass("invisible"); target.find(".loading_time").text(""); @@ -146,11 +147,22 @@ function gradio(config, fn, target) { target.find(".submit").click(function() { io_master.gather(); target.find(".flag").removeClass("flagged"); + target.find(".flag").val("FLAG"); }) } if (!config.show_input) { target.find(".input_panel").hide(); - } + } + + target.find(".flag").click(function() { + if (io_master.last_output) { + target.find(".flag").addClass("flagged"); + target.find(".flag").val("FLAGGED"); + io_master.flag(); + + // io_master.flag($(".flag_message").val()); + } + }) return io_master; } From a7f16bddf324d54c4fd1f99dc6e3454d59a42f05 Mon Sep 17 00:00:00 2001 From: aliabd Date: Mon, 27 Jul 2020 14:21:26 -0700 Subject: [PATCH 2/7] can turn off flagging from interface --- gradio/interface.py | 3 ++- gradio/static/css/gradio.css | 4 +++- gradio/static/js/gradio.js | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/gradio/interface.py b/gradio/interface.py index 783ece5b27..5023cf63c0 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -41,7 +41,7 @@ class Interface: live=False, show_input=True, show_output=True, capture_session=False, title=None, description=None, thumbnail=None, server_port=None, server_name=networking.LOCALHOST_NAME, - allow_screenshot=True): + allow_screenshot=True, allow_flagging=True): """ Parameters: fn (Callable): the function to wrap an interface around. @@ -101,6 +101,7 @@ class Interface: self.server_port = server_port self.simple_server = None self.allow_screenshot = allow_screenshot + self.allow_flagging = allow_flagging Interface.instances.add(self) data = {'fn': fn, diff --git a/gradio/static/css/gradio.css b/gradio/static/css/gradio.css index 06293cc3d1..6ba5e84a7a 100644 --- a/gradio/static/css/gradio.css +++ b/gradio/static/css/gradio.css @@ -75,7 +75,9 @@ input.submit { input.submit:hover { background-color: #f39c12; } - +.flag { + visibility: hidden; +} .flag.flagged { background-color: pink; } diff --git a/gradio/static/js/gradio.js b/gradio/static/js/gradio.js index eb4061343c..7d3f1962ab 100644 --- a/gradio/static/js/gradio.js +++ b/gradio/static/js/gradio.js @@ -128,6 +128,9 @@ function gradio(config, fn, target) { if (config["allow_screenshot"]) { target.find(".screenshot").css("visibility", "visible"); } + if(config["allow_flagging"]){ + target.find(".flag").css("visibility", "visible"); + } target.find(".screenshot").click(function() { $(".screenshot").hide(); $(".screenshot_logo").show(); From 1f7518dc580181ae3d1a79db3f84646ad3d73287 Mon Sep 17 00:00:00 2001 From: aliabd Date: Mon, 27 Jul 2020 15:24:45 -0700 Subject: [PATCH 3/7] flagging dir name --- gradio/interface.py | 19 +++++++++++++++++-- gradio/networking.py | 17 ++++++----------- gradio/static/css/gradio.css | 4 ++-- gradio/static/js/all_io.js | 3 +-- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/gradio/interface.py b/gradio/interface.py index 5023cf63c0..718c21d986 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -20,7 +20,7 @@ from IPython import get_ipython import sys import weakref import analytics - +import os PKG_VERSION_URL = "https://gradio.app/api/pkg-version" analytics.write_key = "uxIFddIEuuUcFLf9VgH2teTEtPlWdkNy" @@ -30,6 +30,8 @@ try: except requests.ConnectionError: ip_address = "No internet connection" +FLAGGING_DIRECTORY = 'flagged/' + class Interface: """ @@ -121,6 +123,18 @@ class Interface: except (ImportError, AttributeError): # If they are using TF >= 2.0 or don't have TF, just ignore this. pass + if self.allow_flagging: + if self.title is not None: + dir_name = "-".join(self.title.split(" ")) + "-1" + else: + dir_name = "-".join(self.input_interfaces) + "-to-" \ + + "-".join(self.output_interfaces) + "-1" + i = 1 + while os.path.exists(FLAGGING_DIRECTORY + dir_name): + i += 1 + dir_name = dir_name[:-2] + "-" + str(i) + self.flagging_dir = FLAGGING_DIRECTORY + dir_name + try: requests.post(analytics_url + 'gradio-initiated-analytics/', data=data) @@ -142,7 +156,8 @@ class Interface: "title": self.title, "description": self.description, "thumbnail": self.thumbnail, - "allow_screenshot": self.allow_screenshot + "allow_screenshot": self.allow_screenshot, + "allow_flagging": self.allow_flagging } try: param_names = inspect.getfullargspec(self.predict[0])[0] diff --git a/gradio/networking.py b/gradio/networking.py index 3a36a4ced1..0a68d89680 100644 --- a/gradio/networking.py +++ b/gradio/networking.py @@ -17,7 +17,6 @@ import requests import sys import analytics - INITIAL_PORT_VALUE = int(os.getenv( 'GRADIO_SERVER_PORT', "7860")) # The http server will try to open on port 7860. If not available, 7861, 7862, etc. TRY_NUM_PORTS = int(os.getenv( @@ -36,8 +35,7 @@ CONFIG_FILE = "static/config.json" ASSOCIATION_PATH_IN_STATIC = "static/apple-app-site-association" ASSOCIATION_PATH_IN_ROOT = "apple-app-site-association" -FLAGGING_DIRECTORY = 'flagged/' -FLAGGING_FILENAME = 'data.txt' +FLAGGING_FILENAME = 'flagged.txt' analytics.write_key = "uxIFddIEuuUcFLf9VgH2teTEtPlWdkNy" analytics_url = 'https://api.gradio.app/' @@ -187,20 +185,17 @@ def serve_files_in_background(interface, port, directory_to_serve=None, server_n data_string = self.rfile.read( int(self.headers["Content-Length"])) msg = json.loads(data_string) - flag_dir = os.path.join(FLAGGING_DIRECTORY, - str(interface.flag_hash)) - os.makedirs(flag_dir, exist_ok=True) + os.makedirs(interface.flagging_dir, exist_ok=True) output = {'inputs': [interface.input_interfaces[ i].rebuild_flagged( - flag_dir, msg['data']['input_data']) for i + interface.flagging_dir, msg['data']['input_data']) for i in range(len(interface.input_interfaces))], 'outputs': [interface.output_interfaces[ i].rebuild_flagged( - flag_dir, msg['data']['output_data']) for i - in range(len(interface.output_interfaces))], - 'message': msg['data']['message']} + interface.flagging_dir, msg['data']['output_data']) for i + in range(len(interface.output_interfaces))]} - with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f: + with open(os.path.join(interface.flagging_dir, FLAGGING_FILENAME), 'a+') as f: f.write(json.dumps(output)) f.write("\n") diff --git a/gradio/static/css/gradio.css b/gradio/static/css/gradio.css index 6ba5e84a7a..f161ad94a5 100644 --- a/gradio/static/css/gradio.css +++ b/gradio/static/css/gradio.css @@ -78,8 +78,8 @@ input.submit:hover { .flag { visibility: hidden; } -.flag.flagged { - background-color: pink; +.flagged { + background-color: pink !important; } /* label:hover { background-color: lightgray; diff --git a/gradio/static/js/all_io.js b/gradio/static/js/all_io.js index 52ebe0ecc7..23978901ce 100644 --- a/gradio/static/js/all_io.js +++ b/gradio/static/js/all_io.js @@ -60,8 +60,7 @@ var io_master_template = { var post_data = { 'data': { 'input_data' : toStringIfObject(this.last_input) , - 'output_data' : toStringIfObject(this.last_output), - 'message' : "no-message" + 'output_data' : toStringIfObject(this.last_output) } } $.ajax({type: "POST", From b9a3b62fc146206252346c29482a9b03af98c8fe Mon Sep 17 00:00:00 2001 From: aliabd Date: Mon, 27 Jul 2020 15:47:52 -0700 Subject: [PATCH 4/7] use input/output label for flag dir name --- gradio/interface.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gradio/interface.py b/gradio/interface.py index 718c21d986..4011dd371e 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -127,8 +127,11 @@ class Interface: if self.title is not None: dir_name = "-".join(self.title.split(" ")) + "-1" else: - dir_name = "-".join(self.input_interfaces) + "-to-" \ - + "-".join(self.output_interfaces) + "-1" + dir_name = "-".join([inp.label for inp in + self.input_interfaces]) + "-to-" \ + + "-".join([out.label for out in + self.output_interfaces])\ + + "-1" i = 1 while os.path.exists(FLAGGING_DIRECTORY + dir_name): i += 1 From 593af4ebf698e597972d1262e50c99301583e4eb Mon Sep 17 00:00:00 2001 From: aliabd Date: Mon, 27 Jul 2020 15:53:53 -0700 Subject: [PATCH 5/7] added rebuild flagged to inputs/outputs --- gradio/inputs.py | 22 +++++++++++++++++++++- gradio/outputs.py | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gradio/inputs.py b/gradio/inputs.py index 62fac86a19..3da585f1ba 100644 --- a/gradio/inputs.py +++ b/gradio/inputs.py @@ -67,7 +67,7 @@ class AbstractInput(ABC): """ All interfaces should define a method that rebuilds the flagged input when it's passed back (i.e. rebuilds image from base64) """ - pass + return msg class Textbox(AbstractInput): """ @@ -356,6 +356,16 @@ class Sketchpad(AbstractInput): def process_example(self, example): return preprocessing_utils.convert_file_to_base64(example) + def rebuild_flagged(self, dir, msg): + """ + Default rebuild method to decode a base64 image + """ + im = preprocessing_utils.decode_base64_to_image(msg) + timestamp = datetime.datetime.now() + filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' + im.save(f'{dir}/{filename}', 'PNG') + return filename + class Webcam(AbstractInput): """ @@ -393,6 +403,16 @@ class Webcam(AbstractInput): im, (self.image_width, self.image_height)) return np.array(im) + def rebuild_flagged(self, dir, msg): + """ + Default rebuild method to decode a base64 image + """ + im = preprocessing_utils.decode_base64_to_image(msg) + timestamp = datetime.datetime.now() + filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' + im.save(f'{dir}/{filename}', 'PNG') + return filename + class Microphone(AbstractInput): """ diff --git a/gradio/outputs.py b/gradio/outputs.py index 553b93c7b3..5e9735991b 100644 --- a/gradio/outputs.py +++ b/gradio/outputs.py @@ -48,7 +48,7 @@ class AbstractOutput(ABC): """ All interfaces should define a method that rebuilds the flagged input when it's passed back (i.e. rebuilds image from base64) """ - pass + return msg class Textbox(AbstractOutput): From 05099e7cf6c6b89617f3b235daaa69dc16a7ef1e Mon Sep 17 00:00:00 2001 From: aliabd Date: Tue, 28 Jul 2020 09:57:49 -0700 Subject: [PATCH 6/7] flagging dir uses function name --- gradio/interface.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/gradio/interface.py b/gradio/interface.py index 4011dd371e..c5f211dd40 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -125,17 +125,14 @@ class Interface: if self.allow_flagging: if self.title is not None: - dir_name = "-".join(self.title.split(" ")) + "-1" + dir_name = "_".join(self.title.split(" ")) + "_1" else: - dir_name = "-".join([inp.label for inp in - self.input_interfaces]) + "-to-" \ - + "-".join([out.label for out in - self.output_interfaces])\ - + "-1" + dir_name = "_".join([fn.__name__ for fn in self.predict]) + \ + "_1" i = 1 while os.path.exists(FLAGGING_DIRECTORY + dir_name): i += 1 - dir_name = dir_name[:-2] + "-" + str(i) + dir_name = dir_name[:-2] + "_" + str(i) self.flagging_dir = FLAGGING_DIRECTORY + dir_name try: From 96543e3ee716525b87366964899b9373223d5858 Mon Sep 17 00:00:00 2001 From: aliabd Date: Wed, 29 Jul 2020 00:00:14 -0700 Subject: [PATCH 7/7] PR review changes --- gradio/inputs.py | 16 ++++++++-------- gradio/interface.py | 23 +++++++++++------------ gradio/networking.py | 8 ++++---- gradio/outputs.py | 12 ++++++------ 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/gradio/inputs.py b/gradio/inputs.py index 3da585f1ba..c143e44bf7 100644 --- a/gradio/inputs.py +++ b/gradio/inputs.py @@ -63,11 +63,11 @@ class AbstractInput(ABC): """ return {} - def rebuild_flagged(self, dir, msg): + def rebuild(self, dir, data): """ All interfaces should define a method that rebuilds the flagged input when it's passed back (i.e. rebuilds image from base64) """ - return msg + return data class Textbox(AbstractInput): """ @@ -295,11 +295,11 @@ class Image(AbstractInput): else: return example - def rebuild_flagged(self, dir, msg): + def rebuild(self, dir, data): """ Default rebuild method to decode a base64 image """ - im = preprocessing_utils.decode_base64_to_image(msg) + im = preprocessing_utils.decode_base64_to_image(data) timestamp = datetime.datetime.now() filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' im.save(f'{dir}/{filename}', 'PNG') @@ -356,11 +356,11 @@ class Sketchpad(AbstractInput): def process_example(self, example): return preprocessing_utils.convert_file_to_base64(example) - def rebuild_flagged(self, dir, msg): + def rebuild(self, dir, data): """ Default rebuild method to decode a base64 image """ - im = preprocessing_utils.decode_base64_to_image(msg) + im = preprocessing_utils.decode_base64_to_image(data) timestamp = datetime.datetime.now() filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' im.save(f'{dir}/{filename}', 'PNG') @@ -403,11 +403,11 @@ class Webcam(AbstractInput): im, (self.image_width, self.image_height)) return np.array(im) - def rebuild_flagged(self, dir, msg): + def rebuild(self, dir, data): """ Default rebuild method to decode a base64 image """ - im = preprocessing_utils.decode_base64_to_image(msg) + im = preprocessing_utils.decode_base64_to_image(data) timestamp = datetime.datetime.now() filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' im.save(f'{dir}/{filename}', 'PNG') diff --git a/gradio/interface.py b/gradio/interface.py index c5f211dd40..8cf3614629 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -30,9 +30,6 @@ try: except requests.ConnectionError: ip_address = "No internet connection" -FLAGGING_DIRECTORY = 'flagged/' - - class Interface: """ Interfaces are created with Gradio using the `gradio.Interface()` function. @@ -43,7 +40,8 @@ class Interface: live=False, show_input=True, show_output=True, capture_session=False, title=None, description=None, thumbnail=None, server_port=None, server_name=networking.LOCALHOST_NAME, - allow_screenshot=True, allow_flagging=True): + allow_screenshot=True, allow_flagging=True, + flagging_dir="flagged"): """ Parameters: fn (Callable): the function to wrap an interface around. @@ -104,6 +102,7 @@ class Interface: self.simple_server = None self.allow_screenshot = allow_screenshot self.allow_flagging = allow_flagging + self.flagging_dir = flagging_dir Interface.instances.add(self) data = {'fn': fn, @@ -125,15 +124,15 @@ class Interface: if self.allow_flagging: if self.title is not None: - dir_name = "_".join(self.title.split(" ")) + "_1" + dir_name = "_".join(self.title.split(" ")) else: - dir_name = "_".join([fn.__name__ for fn in self.predict]) + \ - "_1" - i = 1 - while os.path.exists(FLAGGING_DIRECTORY + dir_name): - i += 1 - dir_name = dir_name[:-2] + "_" + str(i) - self.flagging_dir = FLAGGING_DIRECTORY + dir_name + dir_name = "_".join([fn.__name__ for fn in self.predict]) + index = 1 + while os.path.exists(self.flagging_dir + "/" + dir_name + + "_{}".format(index)): + index += 1 + self.flagging_dir = self.flagging_dir + "/" + dir_name + \ + "_{}".format(index) try: requests.post(analytics_url + 'gradio-initiated-analytics/', diff --git a/gradio/networking.py b/gradio/networking.py index 0a68d89680..685ab79936 100644 --- a/gradio/networking.py +++ b/gradio/networking.py @@ -35,7 +35,6 @@ CONFIG_FILE = "static/config.json" ASSOCIATION_PATH_IN_STATIC = "static/apple-app-site-association" ASSOCIATION_PATH_IN_ROOT = "apple-app-site-association" -FLAGGING_FILENAME = 'flagged.txt' analytics.write_key = "uxIFddIEuuUcFLf9VgH2teTEtPlWdkNy" analytics_url = 'https://api.gradio.app/' @@ -187,15 +186,16 @@ def serve_files_in_background(interface, port, directory_to_serve=None, server_n msg = json.loads(data_string) os.makedirs(interface.flagging_dir, exist_ok=True) output = {'inputs': [interface.input_interfaces[ - i].rebuild_flagged( + i].rebuild( interface.flagging_dir, msg['data']['input_data']) for i in range(len(interface.input_interfaces))], 'outputs': [interface.output_interfaces[ - i].rebuild_flagged( + i].rebuild( interface.flagging_dir, msg['data']['output_data']) for i in range(len(interface.output_interfaces))]} - with open(os.path.join(interface.flagging_dir, FLAGGING_FILENAME), 'a+') as f: + with open("{}/log.txt".format(interface.flagging_dir), + 'a+') as f: f.write(json.dumps(output)) f.write("\n") diff --git a/gradio/outputs.py b/gradio/outputs.py index 5e9735991b..691b177503 100644 --- a/gradio/outputs.py +++ b/gradio/outputs.py @@ -44,11 +44,11 @@ class AbstractOutput(ABC): """ return {} - def rebuild_flagged(self, dir, msg): + def rebuild(self, dir, data): """ All interfaces should define a method that rebuilds the flagged input when it's passed back (i.e. rebuilds image from base64) """ - return msg + return data class Textbox(AbstractOutput): @@ -136,11 +136,11 @@ class Label(AbstractOutput): "label": {}, } - def rebuild_flagged(self, dir, msg): + def rebuild(self, dir, data): """ Default rebuild method for label """ - return json.loads(msg) + return json.loads(data) class Image(AbstractOutput): ''' @@ -180,11 +180,11 @@ class Image(AbstractOutput): raise ValueError( "The `Image` output interface (with plt=False) expects a numpy array.") - def rebuild_flagged(self, dir, msg): + def rebuild(self, dir, data): """ Default rebuild method to decode a base64 image """ - im = preprocessing_utils.decode_base64_to_image(msg) + im = preprocessing_utils.decode_base64_to_image(data) timestamp = datetime.datetime.now() filename = 'output_{}.png'.format(timestamp. strftime("%Y-%m-%d-%H-%M-%S"))