Skip to content

Commit

Permalink
add auto port detection as in jupyter notebook
Browse files Browse the repository at this point in the history
Add missing import in app.py

Update app.py - fix e128 indentation flake8 rule

Update app.py - flake8 e124 compatibility

rename notebook to voila in the critical message
  • Loading branch information
katsar0v committed Oct 13, 2019
1 parent 24df2cc commit 1c7fc54
Showing 1 changed file with 40 additions and 2 deletions.
42 changes: 40 additions & 2 deletions voila/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import signal
import socket
import webbrowser
import errno
import random

try:
from urllib.parse import urljoin
Expand Down Expand Up @@ -193,6 +195,10 @@ class Voila(Application):
)
)

port_retries = Integer(50, config=True,
help=_("The number of additional ports to try if the specified port is not available.")
)

ip = Unicode('localhost', config=True,
help=_("The IP address the notebook server will listen on."))

Expand Down Expand Up @@ -488,9 +494,41 @@ def stop(self):
shutil.rmtree(self.connection_dir)
self.kernel_manager.shutdown_all()

def random_ports(self, port, n):
"""Generate a list of n random ports near the given port.
The first 5 ports will be sequential, and the remaining n-5 will be
randomly selected in the range [port-2*n, port+2*n].
"""
for i in range(min(5, n)):
yield port + i
for i in range(n-5):
yield max(1, port + random.randint(-2*n, 2*n))

def listen(self):
self.app.listen(self.port)
self.log.info('Voila is running at:\n%s' % self.display_url)
for port in self.random_ports(self.port, self.port_retries+1):
try:
self.app.listen(port)
self.port = port
self.log.info('Voila is running at:\n%s' % self.display_url)
except socket.error as e:
if e.errno == errno.EADDRINUSE:
self.log.info(_('The port %i is already in use, trying another port.') % port)
continue
elif e.errno in (errno.EACCES, getattr(errno, 'WSAEACCES', errno.EACCES)):
self.log.warning(_("Permission to listen on port %i denied") % port)
continue
else:
raise
else:
self.port = port
success = True
break

if not success:
self.log.critical(_('ERROR: the voila server could not be started because '
'no available port could be found.'))
self.exit(1)

if self.open_browser:
self.launch_browser()
Expand Down

0 comments on commit 1c7fc54

Please sign in to comment.