sharing is caring and image bigfix

This commit is contained in:
Ali Abid 2020-06-25 12:31:48 -07:00
parent 73d62375cf
commit bb7a2ea079
17 changed files with 77 additions and 273 deletions

View File

@ -332,9 +332,9 @@ class ImageIn(AbstractInput):
im = np.array(im).flatten()
im = im * self.scale + self.shift
if self.num_channels is None:
array = im.reshape(1, self.image_width, self.image_height)
array = im.reshape(self.image_width, self.image_height)
else:
array = im.reshape(1, self.image_width, self.image_height, \
array = im.reshape(self.image_width, self.image_height, \
self.num_channels)
return array

View File

@ -180,7 +180,7 @@ class Interface:
return
raise RuntimeError("Validation did not pass")
def launch(self, inline=None, inbrowser=None, share=True, validate=True):
def launch(self, inline=None, inbrowser=None, share=False, validate=True):
"""
Standard method shared by interfaces that creates the interface and sets up a websocket to communicate with it.
:param inline: boolean. If True, then a gradio interface is created inline (e.g. in jupyter or colab notebook)
@ -212,7 +212,6 @@ class Interface:
server_port, httpd = networking.start_simple_server(self, output_directory, self.server_name)
path_to_local_server = "http://{}:{}/".format(self.server_name, server_port)
networking.build_template(output_directory)
networking.set_config(self.get_config_file(), output_directory)
self.status = "RUNNING"
self.simple_server = httpd
@ -243,6 +242,7 @@ class Interface:
if share:
try:
share_url = networking.setup_tunnel(server_port)
print(share_url)
except RuntimeError:
share_url = None
if self.verbose:
@ -288,5 +288,8 @@ class Interface:
else:
display(IFrame(path_to_local_server, width=1000, height=500))
config = self.get_config_file()
config["share_url"] = share_url
networking.set_config(config, output_directory)
return httpd, path_to_local_server, share_url

View File

@ -179,81 +179,6 @@ def serve_files_in_background(interface, port, directory_to_serve=None, server_n
f.write(json.dumps(output))
f.write("\n")
# TODO(abidlabs): clean this up
elif self.path == "/api/auto/rotation":
from gradio import validation_data, preprocessing_utils
import numpy as np
self._set_headers()
data_string = self.rfile.read(
int(self.headers["Content-Length"]))
msg = json.loads(data_string)
img_orig = preprocessing_utils.decode_base64_to_image(
msg["data"])
img_orig = img_orig.convert('RGB')
img_orig = img_orig.resize((224, 224))
flag_dir = os.path.join(directory_to_serve, FLAGGING_DIRECTORY)
os.makedirs(flag_dir, exist_ok=True)
for deg in range(-180, 180+45, 45):
img = img_orig.rotate(deg)
img_array = np.array(img) / 127.5 - 1
prediction = interface.predict(
np.expand_dims(img_array, axis=0))
processed_output = interface.output_interface.postprocess(
prediction)
output = {'input': interface.input_interface.save_to_file(flag_dir, img),
'output': interface.output_interface.rebuild_flagged(
flag_dir, {'data': {'output': processed_output}}),
'message': 'rotation by {} degrees'.format(
deg)}
with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f:
f.write(json.dumps(output))
f.write("\n")
# Prepare return json dictionary.
self.wfile.write(json.dumps({}).encode())
elif self.path == "/api/auto/lighting":
from gradio import validation_data, preprocessing_utils
import numpy as np
from PIL import ImageEnhance
self._set_headers()
data_string = self.rfile.read(
int(self.headers["Content-Length"]))
msg = json.loads(data_string)
img_orig = preprocessing_utils.decode_base64_to_image(
msg["data"])
img_orig = img_orig.convert('RGB')
img_orig = img_orig.resize((224, 224))
enhancer = ImageEnhance.Brightness(img_orig)
flag_dir = os.path.join(directory_to_serve, FLAGGING_DIRECTORY)
os.makedirs(flag_dir, exist_ok=True)
for i in range(9):
img = enhancer.enhance(i/4)
img_array = np.array(img) / 127.5 - 1
prediction = interface.predict(
np.expand_dims(img_array, axis=0))
processed_output = interface.output_interface.postprocess(
prediction)
output = {'input': interface.input_interface.save_to_file(flag_dir, img),
'output': interface.output_interface.rebuild_flagged(
flag_dir, {'data': {'output': processed_output}}),
'message': 'brighting adjustment by a factor '
'of {}'.format(i)}
with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f:
f.write(json.dumps(output))
f.write("\n")
# Prepare return json dictionary.
self.wfile.write(json.dumps({}).encode())
else:
self.send_error(404, 'Path not found: {}'.format(self.path))

View File

@ -141,6 +141,7 @@ class Image(AbstractOutput):
if self.plot:
return preprocessing_utils.encode_plot_to_base64(prediction)
else:
print(prediction.shape)
return preprocessing_utils.encode_array_to_base64(prediction)
def rebuild_flagged(self, dir, msg):

View File

@ -21,28 +21,15 @@ nav img {
margin-right: auto;
height: 32px;
}
#share_row {
justify-content: center;
#share {
text-align: center;
margin-bottom: 10px;
font-size: 14px;
}
#share_form {
flex-grow: 1;
justify-content: center;
align-items: center;
}
#share_row button, #share_row input[type=text] {
padding: 6px 4px;
margin-left: 5px;
}
#share_row input[type=text] {
background-color: #F6F6F6;
}
#share_email {
flex-grow: 1;
max-width: 400px;
}
#share_row, #share_complete, #share_form {
display: none;
#share-copy {
background-color: whitesmoke;
padding: 4px;
border-radius: 2px;
}
.panels {
display: flex;

View File

@ -92,7 +92,7 @@ const image_input = {
var io = this;
if (this.state == "IMAGE_LOADED") {
resizeImage.call(this, this.image_data, 300, 300, function(image_data) {
this.io_master.input(io.id, image_data);
io.io_master.input(io.id, image_data);
})
}
},

View File

@ -29,17 +29,9 @@
<nav>
<a href="https://gradio.app"><img src="../static/img/logo_inline.png" /></a>
</nav>
<div id="share_row">
<button id="share" class="primary">Share this Interface</button>
<div id="share_form">
<input type="text" id="share_name" placeholder="sender name (you)"></input>
<input type="text" id="share_email" placeholder="emails (comma-separated if multiple)"></input>
<button class="primary" id="send_link">Send Link</button>
</div>
<div id="share_complete">
<span id="share_message"></span>
<button class="secondary" id="share_more"></button>
</div>
<div id="share" class="invisible">
Live at <a id="share-link"></a>.
<button id="share-copy">Copy Link</button>
</div>
<div id="interface_target"></div>
<script src="../static/js/vendor/jquery.min.js"></script>
@ -75,7 +67,6 @@
<script src="../static/js/interfaces/output/image.js"></script>
<script src="../static/js/interfaces/output/label.js"></script>
<script src="../static/js/interfaces/output/textbox.js"></script>
<script src="../static/js/share.js"></script>
<script src="../static/js/gradio.js"></script>
<script>
$.getJSON("static/config.json", function(config) {
@ -89,7 +80,23 @@
});
});
}, "#interface_target");
if (config["share_url"]) {
let share_url = config["share_url"];
$("#share").removeClass("invisible");
$("#share-link").text(share_url).attr("href", share_url);
$("#share-copy").click(function() {
copyToClipboard(share_url);
})
}
});
const copyToClipboard = str => {
const el = document.createElement('textarea');
el.value = str;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
};
</script>
</body>
</html>

View File

@ -13,4 +13,4 @@ gr.Interface(answer_question,
], [
gr.outputs.Textbox(label="out", lines=8),
]
).launch()
).launch(share=True)

View File

@ -4,16 +4,17 @@ from time import time
def flip(image):
start = time()
return np.flipud(image), time() - start
return image, {
"1": 0.2,
"2": 0.8
}
def flip2(image):
start = time()
return np.fliplr(image), time() - start
gr.Interface([flip, flip2],
"imagein",
[
"image",
gr.outputs.Textbox(lines=1)
gr.Interface(flip,
"image",
["image", "label"
]).launch()

View File

@ -51,7 +51,6 @@ gradio/static/img/vendor/icon-c.svg
gradio/static/img/vendor/icon-d.svg
gradio/static/js/all_io.js
gradio/static/js/gradio.js
gradio/static/js/share.js
gradio/static/js/utils.js
gradio/static/js/interfaces/input/checkbox.js
gradio/static/js/interfaces/input/checkbox_group.js

View File

@ -332,9 +332,9 @@ class ImageIn(AbstractInput):
im = np.array(im).flatten()
im = im * self.scale + self.shift
if self.num_channels is None:
array = im.reshape(1, self.image_width, self.image_height)
array = im.reshape(self.image_width, self.image_height)
else:
array = im.reshape(1, self.image_width, self.image_height, \
array = im.reshape(self.image_width, self.image_height, \
self.num_channels)
return array

View File

@ -180,7 +180,7 @@ class Interface:
return
raise RuntimeError("Validation did not pass")
def launch(self, inline=None, inbrowser=None, share=True, validate=True):
def launch(self, inline=None, inbrowser=None, share=False, validate=True):
"""
Standard method shared by interfaces that creates the interface and sets up a websocket to communicate with it.
:param inline: boolean. If True, then a gradio interface is created inline (e.g. in jupyter or colab notebook)
@ -212,7 +212,6 @@ class Interface:
server_port, httpd = networking.start_simple_server(self, output_directory, self.server_name)
path_to_local_server = "http://{}:{}/".format(self.server_name, server_port)
networking.build_template(output_directory)
networking.set_config(self.get_config_file(), output_directory)
self.status = "RUNNING"
self.simple_server = httpd
@ -243,6 +242,7 @@ class Interface:
if share:
try:
share_url = networking.setup_tunnel(server_port)
print(share_url)
except RuntimeError:
share_url = None
if self.verbose:
@ -288,5 +288,8 @@ class Interface:
else:
display(IFrame(path_to_local_server, width=1000, height=500))
config = self.get_config_file()
config["share_url"] = share_url
networking.set_config(config, output_directory)
return httpd, path_to_local_server, share_url

View File

@ -179,81 +179,6 @@ def serve_files_in_background(interface, port, directory_to_serve=None, server_n
f.write(json.dumps(output))
f.write("\n")
# TODO(abidlabs): clean this up
elif self.path == "/api/auto/rotation":
from gradio import validation_data, preprocessing_utils
import numpy as np
self._set_headers()
data_string = self.rfile.read(
int(self.headers["Content-Length"]))
msg = json.loads(data_string)
img_orig = preprocessing_utils.decode_base64_to_image(
msg["data"])
img_orig = img_orig.convert('RGB')
img_orig = img_orig.resize((224, 224))
flag_dir = os.path.join(directory_to_serve, FLAGGING_DIRECTORY)
os.makedirs(flag_dir, exist_ok=True)
for deg in range(-180, 180+45, 45):
img = img_orig.rotate(deg)
img_array = np.array(img) / 127.5 - 1
prediction = interface.predict(
np.expand_dims(img_array, axis=0))
processed_output = interface.output_interface.postprocess(
prediction)
output = {'input': interface.input_interface.save_to_file(flag_dir, img),
'output': interface.output_interface.rebuild_flagged(
flag_dir, {'data': {'output': processed_output}}),
'message': 'rotation by {} degrees'.format(
deg)}
with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f:
f.write(json.dumps(output))
f.write("\n")
# Prepare return json dictionary.
self.wfile.write(json.dumps({}).encode())
elif self.path == "/api/auto/lighting":
from gradio import validation_data, preprocessing_utils
import numpy as np
from PIL import ImageEnhance
self._set_headers()
data_string = self.rfile.read(
int(self.headers["Content-Length"]))
msg = json.loads(data_string)
img_orig = preprocessing_utils.decode_base64_to_image(
msg["data"])
img_orig = img_orig.convert('RGB')
img_orig = img_orig.resize((224, 224))
enhancer = ImageEnhance.Brightness(img_orig)
flag_dir = os.path.join(directory_to_serve, FLAGGING_DIRECTORY)
os.makedirs(flag_dir, exist_ok=True)
for i in range(9):
img = enhancer.enhance(i/4)
img_array = np.array(img) / 127.5 - 1
prediction = interface.predict(
np.expand_dims(img_array, axis=0))
processed_output = interface.output_interface.postprocess(
prediction)
output = {'input': interface.input_interface.save_to_file(flag_dir, img),
'output': interface.output_interface.rebuild_flagged(
flag_dir, {'data': {'output': processed_output}}),
'message': 'brighting adjustment by a factor '
'of {}'.format(i)}
with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f:
f.write(json.dumps(output))
f.write("\n")
# Prepare return json dictionary.
self.wfile.write(json.dumps({}).encode())
else:
self.send_error(404, 'Path not found: {}'.format(self.path))

View File

@ -21,28 +21,15 @@ nav img {
margin-right: auto;
height: 32px;
}
#share_row {
justify-content: center;
#share {
text-align: center;
margin-bottom: 10px;
font-size: 14px;
}
#share_form {
flex-grow: 1;
justify-content: center;
align-items: center;
}
#share_row button, #share_row input[type=text] {
padding: 6px 4px;
margin-left: 5px;
}
#share_row input[type=text] {
background-color: #F6F6F6;
}
#share_email {
flex-grow: 1;
max-width: 400px;
}
#share_row, #share_complete, #share_form {
display: none;
#share-copy {
background-color: whitesmoke;
padding: 4px;
border-radius: 2px;
}
.panels {
display: flex;

View File

@ -92,7 +92,7 @@ const image_input = {
var io = this;
if (this.state == "IMAGE_LOADED") {
resizeImage.call(this, this.image_data, 300, 300, function(image_data) {
this.io_master.input(io.id, image_data);
io.io_master.input(io.id, image_data);
})
}
},

View File

@ -1,41 +0,0 @@
$("#share").click(function() {
$("#share").hide()
$("#share_form").css('display', 'flex')
})
$("#send_link").click(function(evt) {
let name = $("#share_name").val()
let email = $("#share_email").val()
if (name && email) {
$("#send_link").attr('disabled', true);
$.ajax({
"url" : "https://gradio.app/api/send-email/",
"type": "POST",
"crossDomain": true,
"data": {
"url": config["share_url"],
"name": name,
"email": email
},
"success": function() {
$("#share_message").text("Shared successfully.");
$("#share_more").text("Share more");
},
"error": function() {
$("#share_message").text("Failed to share.");
$("#share_more").text("Try again");
},
"complete": function() {
$("#share_form").hide();
$("#share_complete").show();
$("#send_link").attr('disabled', false);
}
})
}
})
$("#share_more").click(function (evt) {
$("#share_email").val("");
$("#share_form").show();
$("#share_complete").hide();
})

View File

@ -29,17 +29,9 @@
<nav>
<a href="https://gradio.app"><img src="../static/img/logo_inline.png" /></a>
</nav>
<div id="share_row">
<button id="share" class="primary">Share this Interface</button>
<div id="share_form">
<input type="text" id="share_name" placeholder="sender name (you)"></input>
<input type="text" id="share_email" placeholder="emails (comma-separated if multiple)"></input>
<button class="primary" id="send_link">Send Link</button>
</div>
<div id="share_complete">
<span id="share_message"></span>
<button class="secondary" id="share_more"></button>
</div>
<div id="share" class="invisible">
Live at <a id="share-link"></a>.
<button id="share-copy">Copy Link</button>
</div>
<div id="interface_target"></div>
<script src="../static/js/vendor/jquery.min.js"></script>
@ -75,7 +67,6 @@
<script src="../static/js/interfaces/output/image.js"></script>
<script src="../static/js/interfaces/output/label.js"></script>
<script src="../static/js/interfaces/output/textbox.js"></script>
<script src="../static/js/share.js"></script>
<script src="../static/js/gradio.js"></script>
<script>
$.getJSON("static/config.json", function(config) {
@ -89,7 +80,23 @@
});
});
}, "#interface_target");
if (config["share_url"]) {
let share_url = config["share_url"];
$("#share").removeClass("invisible");
$("#share-link").text(share_url).attr("href", share_url);
$("#share-copy").click(function() {
copyToClipboard(share_url);
})
}
});
const copyToClipboard = str => {
const el = document.createElement('textarea');
el.value = str;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
};
</script>
</body>
</html>