mirror of
https://github.com/gradio-app/gradio.git
synced 2025-02-11 11:19:58 +08:00
replaced http.server with python version and used sockets instead of psutil
This commit is contained in:
parent
6c1c9bbc31
commit
eb2f141326
@ -2,18 +2,9 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The autoreload extension is already loaded. To reload it, use:\n",
|
||||
" %reload_ext autoreload\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%load_ext autoreload\n",
|
||||
"%autoreload 2\n",
|
||||
@ -23,7 +14,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -33,7 +24,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
@ -52,7 +43,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -60,14 +51,167 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"NOTE: Gradio is in beta stage, please report all bugs to: a12d@stanford.edu\n",
|
||||
"Model available locally at: http://localhost:7871/interface.html\n",
|
||||
"Model available locally at: http://localhost:7861/interface.html\n",
|
||||
"To create a public link, set `share_link=True` in the argument to `launch()`\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:01] \"GET /interface.html HTTP/1.1\" 200 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:01] \"GET /js/all-io.js HTTP/1.1\" 200 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:01] \"GET /css/bootstrap.min.css HTTP/1.1\" 200 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:01] \"GET /css/draw-a-digit.css HTTP/1.1\" 200 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:01] \"GET /js/bootstrap.min.js HTTP/1.1\" 200 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:01] \"GET /js/bootstrap-notify.min.js HTTP/1.1\" 200 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:01] \"GET /js/textbox-input.js HTTP/1.1\" 200 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:01] \"GET /js/textbox-output.js HTTP/1.1\" 200 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:35] \"GET /interface.html HTTP/1.1\" 304 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:35] \"GET /js/all-io.js HTTP/1.1\" 304 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:35] \"GET /css/bootstrap.min.css HTTP/1.1\" 304 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:35] \"GET /css/draw-a-digit.css HTTP/1.1\" 304 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:35] \"GET /js/bootstrap.min.js HTTP/1.1\" 304 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:35] \"GET /js/bootstrap-notify.min.js HTTP/1.1\" 304 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:35] \"GET /js/textbox-input.js HTTP/1.1\" 304 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 22:06:35] \"GET /js/textbox-output.js HTTP/1.1\" 304 -\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"iface.launch()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Model type not explicitly identified, inferred to be: python function\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"iface2 = gradio.Interface(input=\"textbox\", output=\"textbox\", model=test)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Model type not explicitly identified, inferred to be: python function\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"iface = gradio.Interface(input=\"textbox\", output=\"textbox\", model=test)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] code 404, message File not found\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] \"GET /css/bootstrap.min.css HTTP/1.1\" 404 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] code 404, message File not found\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] \"GET /css/index.css HTTP/1.1\" 404 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] code 404, message File not found\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] \"GET /js/bootstrap.min.js HTTP/1.1\" 404 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] code 404, message File not found\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] \"GET /img/draw-a-digit.png HTTP/1.1\" 404 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] code 404, message File not found\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] \"GET /js/bootstrap.min.js HTTP/1.1\" 404 -\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] code 404, message File not found\n",
|
||||
"127.0.0.1 - - [24/Feb/2019 21:50:49] \"GET /img/placeholder.png HTTP/1.1\" 404 -\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"#!/bin/env python\n",
|
||||
"import sys, signal\n",
|
||||
"import http.server\n",
|
||||
"import socketserver\n",
|
||||
"import threading\n",
|
||||
"\n",
|
||||
"port = 7865\n",
|
||||
"\n",
|
||||
"# Note ForkingTCPServer does not work on Windows as the os.fork() \n",
|
||||
"# function is not available on that OS. Instead we must use the \n",
|
||||
"# subprocess server to handle multiple requests\n",
|
||||
"server = socketserver.ThreadingTCPServer(('localhost',port), http.server.SimpleHTTPRequestHandler )\n",
|
||||
"\n",
|
||||
"#Ensures that Ctrl-C cleanly kills all spawned threads\n",
|
||||
"server.daemon_threads = True \n",
|
||||
"#Quicker rebinding\n",
|
||||
"server.allow_reuse_address = True \n",
|
||||
"\n",
|
||||
"# A custom signal handle to allow us to Ctrl-C out of the process\n",
|
||||
"def signal_handler(signal, frame):\n",
|
||||
" print( 'Exiting http server (Ctrl+C pressed)')\n",
|
||||
" try:\n",
|
||||
" if(server):\n",
|
||||
" server.server_close()\n",
|
||||
" finally:\n",
|
||||
" sys.exit(0)\n",
|
||||
"\n",
|
||||
"# Install the keyboard interrupt handler\n",
|
||||
"signal.signal(signal.SIGINT, signal_handler)\n",
|
||||
"\n",
|
||||
"# Now loop forever\n",
|
||||
"def serve_forever():\n",
|
||||
" try:\n",
|
||||
" while True:\n",
|
||||
" sys.stdout.flush()\n",
|
||||
" server.serve_forever()\n",
|
||||
" except KeyboardInterrupt:\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"thread = threading.Thread(target=serve_forever)\n",
|
||||
"thread.start()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import socket\n",
|
||||
"\n",
|
||||
"s = socket.socket() \n",
|
||||
"s.bind(('localhost', 7866))\n",
|
||||
"s.close()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"1+1"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
@ -167,7 +167,7 @@ class Interface():
|
||||
path_to_server = 'http://localhost:{}/'.format(server_port)
|
||||
self._build_template(output_directory)
|
||||
|
||||
ports_in_use = networking.get_ports_in_use()
|
||||
ports_in_use = networking.get_ports_in_use(INITIAL_WEBSOCKET_PORT, INITIAL_WEBSOCKET_PORT + TRY_NUM_PORTS)
|
||||
for i in range(TRY_NUM_PORTS):
|
||||
if not ((INITIAL_WEBSOCKET_PORT + i) in ports_in_use):
|
||||
break
|
||||
@ -191,6 +191,7 @@ class Interface():
|
||||
else:
|
||||
if verbose:
|
||||
print("To create a public link, set `share_link=True` in the argument to `launch()`")
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
try:
|
||||
asyncio.get_event_loop().run_forever()
|
||||
|
@ -4,11 +4,17 @@ import zipfile
|
||||
import io
|
||||
import sys
|
||||
import os
|
||||
import socket
|
||||
from psutil import process_iter, AccessDenied
|
||||
from signal import SIGTERM # or SIGKILL
|
||||
import signal
|
||||
import http.server
|
||||
import socketserver
|
||||
import threading
|
||||
|
||||
INITIAL_PORT_VALUE = 7860
|
||||
TRY_NUM_PORTS = 100
|
||||
LOCALHOST_NAME = 'localhost'
|
||||
LOCALHOST_PREFIX = 'localhost:'
|
||||
NGROK_TUNNELS_API_URL = "http://localhost:4040/api/tunnels" # TODO(this should be captured from output)
|
||||
NGROK_TUNNELS_API_URL2 = "http://localhost:4041/api/tunnels" # TODO(this should be captured from output)
|
||||
@ -20,31 +26,76 @@ NGROK_ZIP_URLS = {
|
||||
}
|
||||
|
||||
|
||||
def get_ports_in_use():
|
||||
def get_ports_in_use(start, stop):
|
||||
ports_in_use = []
|
||||
try:
|
||||
for proc in process_iter():
|
||||
for conns in proc.connections(kind='inet'):
|
||||
ports_in_use.append(conns.laddr.port)
|
||||
except AccessDenied:
|
||||
pass # TODO(abidlabs): somehow find a way to handle this issue?
|
||||
for port in range(start, stop):
|
||||
try:
|
||||
s = socket.socket() # create a socket object
|
||||
s.bind((LOCALHOST_NAME, port)) # Bind to the port
|
||||
s.close()
|
||||
except OSError:
|
||||
ports_in_use.append(port)
|
||||
return ports_in_use
|
||||
# ports_in_use = []
|
||||
# try:
|
||||
# for proc in process_iter():
|
||||
# for conns in proc.connections(kind='inet'):
|
||||
# ports_in_use.append(conns.laddr.port)
|
||||
# except AccessDenied:
|
||||
# pass # TODO(abidlabs): somehow find a way to handle this issue?
|
||||
# return ports_in_use
|
||||
|
||||
|
||||
def serve_files_in_background(port, directory_to_serve=None):
|
||||
def handler(*args):
|
||||
return http.server.SimpleHTTPRequestHandler(*args, directory=directory_to_serve)
|
||||
|
||||
server = socketserver.ThreadingTCPServer(('localhost', port), handler)
|
||||
# Ensures that Ctrl-C cleanly kills all spawned threads
|
||||
server.daemon_threads = True
|
||||
# Quicker rebinding
|
||||
server.allow_reuse_address = True
|
||||
|
||||
# A custom signal handle to allow us to Ctrl-C out of the process
|
||||
def signal_handler(signal, frame):
|
||||
print('Exiting http server (Ctrl+C pressed)')
|
||||
try:
|
||||
if (server):
|
||||
server.server_close()
|
||||
finally:
|
||||
sys.exit(0)
|
||||
|
||||
# Install the keyboard interrupt handler
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
# Now loop forever
|
||||
def serve_forever():
|
||||
try:
|
||||
while True:
|
||||
sys.stdout.flush()
|
||||
server.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
thread = threading.Thread(target=serve_forever)
|
||||
thread.start()
|
||||
|
||||
|
||||
def start_simple_server(directory_to_serve=None):
|
||||
# TODO(abidlabs): increment port number until free port is found
|
||||
ports_in_use = get_ports_in_use()
|
||||
ports_in_use = get_ports_in_use(start=INITIAL_PORT_VALUE, stop=INITIAL_PORT_VALUE + TRY_NUM_PORTS)
|
||||
for i in range(TRY_NUM_PORTS):
|
||||
if not((INITIAL_PORT_VALUE + i) in ports_in_use):
|
||||
break
|
||||
else:
|
||||
raise OSError("All ports from {} to {} are in use. Please close a port.".format(
|
||||
INITIAL_PORT_VALUE, INITIAL_PORT_VALUE + TRY_NUM_PORTS))
|
||||
if directory_to_serve is None:
|
||||
subprocess.Popen(['python', '-m', 'http.server', str(INITIAL_PORT_VALUE + i)])
|
||||
else:
|
||||
cmd = ' '.join(['python', '-m', 'http.server', '-d', directory_to_serve, str(INITIAL_PORT_VALUE + i)])
|
||||
subprocess.Popen(cmd, shell=True) # Doesn't seem to work if list is passed for some reason.
|
||||
serve_files_in_background(INITIAL_PORT_VALUE + i, directory_to_serve)
|
||||
# if directory_to_serve is None:
|
||||
# subprocess.Popen(['python', '-m', 'http.server', str(INITIAL_PORT_VALUE + i)])
|
||||
# else:
|
||||
# cmd = ' '.join(['python', '-m', 'http.server', '-d', directory_to_serve, str(INITIAL_PORT_VALUE + i)])
|
||||
# subprocess.Popen(cmd, shell=True) # Doesn't seem to work if list is passed for some reason.
|
||||
return INITIAL_PORT_VALUE + i
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user