##// END OF EJS Templates
Write notebook server info file in security directory
Thomas Kluyver -
Show More
@@ -19,6 +19,8 b' from __future__ import print_function'
19
19
20 # stdlib
20 # stdlib
21 import errno
21 import errno
22 import io
23 import json
22 import logging
24 import logging
23 import os
25 import os
24 import random
26 import random
@@ -72,6 +74,7 b' from .base.handlers import AuthenticatedFileHandler, FileFindHandler'
72
74
73 from IPython.config.application import catch_config_error, boolean_flag
75 from IPython.config.application import catch_config_error, boolean_flag
74 from IPython.core.application import BaseIPythonApplication
76 from IPython.core.application import BaseIPythonApplication
77 from IPython.core.profiledir import ProfileDir
75 from IPython.consoleapp import IPythonConsoleApp
78 from IPython.consoleapp import IPythonConsoleApp
76 from IPython.kernel import swallow_argv
79 from IPython.kernel import swallow_argv
77 from IPython.kernel.zmq.session import default_secure
80 from IPython.kernel.zmq.session import default_secure
@@ -499,6 +502,12 b' class NotebookApp(BaseIPythonApplication):'
499 "sent by the upstream reverse proxy. Neccesary if the proxy handles SSL")
502 "sent by the upstream reverse proxy. Neccesary if the proxy handles SSL")
500 )
503 )
501
504
505 info_file = Unicode()
506
507 def _info_file_default(self):
508 info_file = "nbserver-%s.json"%os.getpid()
509 return os.path.join(self.profile_dir.security_dir, info_file)
510
502 def parse_command_line(self, argv=None):
511 def parse_command_line(self, argv=None):
503 super(NotebookApp, self).parse_command_line(argv)
512 super(NotebookApp, self).parse_command_line(argv)
504
513
@@ -594,6 +603,20 b' class NotebookApp(BaseIPythonApplication):'
594 'no available port could be found.')
603 'no available port could be found.')
595 self.exit(1)
604 self.exit(1)
596
605
606 @property
607 def display_url(self):
608 ip = self.ip if self.ip else '[all ip addresses on your system]'
609 return self._url(ip)
610
611 @property
612 def connection_url(self):
613 ip = self.ip if self.ip else localhost()
614 return self._url(ip)
615
616 def _url(self, ip):
617 proto = 'https' if self.certfile else 'http'
618 return "%s://%s:%i%s" % (proto, ip, self.port, self.base_project_url)
619
597 def init_signal(self):
620 def init_signal(self):
598 if not sys.platform.startswith('win'):
621 if not sys.platform.startswith('win'):
599 signal.signal(signal.SIGINT, self._handle_sigint)
622 signal.signal(signal.SIGINT, self._handle_sigint)
@@ -666,7 +689,6 b' class NotebookApp(BaseIPythonApplication):'
666 elif status == 'unclean':
689 elif status == 'unclean':
667 self.log.warn("components submodule unclean, you may see 404s on static/components")
690 self.log.warn("components submodule unclean, you may see 404s on static/components")
668 self.log.warn("run `setup.py submodule` or `git submodule update` to update")
691 self.log.warn("run `setup.py submodule` or `git submodule update` to update")
669
670
692
671 @catch_config_error
693 @catch_config_error
672 def initialize(self, argv=None):
694 def initialize(self, argv=None):
@@ -691,33 +713,56 b' class NotebookApp(BaseIPythonApplication):'
691 "Return the current working directory and the server url information"
713 "Return the current working directory and the server url information"
692 info = self.notebook_manager.info_string() + "\n"
714 info = self.notebook_manager.info_string() + "\n"
693 info += "%d active kernels \n" % len(self.kernel_manager._kernels)
715 info += "%d active kernels \n" % len(self.kernel_manager._kernels)
694 return info + "The IPython Notebook is running at: %s" % self._url
716 return info + "The IPython Notebook is running at: %s" % self.display_url
717
718 def server_info(self):
719 """Return a JSONable dict of information about this server."""
720 return {'url': self.connection_url,
721 'hostname': self.ip if self.ip else 'localhost',
722 'port': self.port,
723 'secure': bool(self.certfile),
724 'baseurlpath': self.base_project_url,
725 'notebookdir': os.path.abspath(self.notebook_manager.notebook_dir),
726 }
727
728 def write_server_info_file(self):
729 """Write the result of server_info() to the JSON file info_file."""
730 with io.open(self.info_file, 'w', encoding='utf-8') as f:
731 json.dump(self.server_info(), f)
732
733 def remove_server_info_file(self):
734 """Remove the nbserver-<pid>.json file created for this server.
735
736 Ignores the error raised when the file has already been removed.
737 """
738 try:
739 os.unlink(self.info_file)
740 except OSError as e:
741 if e.errno != errno.ENOENT:
742 raise
695
743
696 def start(self):
744 def start(self):
697 """ Start the IPython Notebook server app, after initialization
745 """ Start the IPython Notebook server app, after initialization
698
746
699 This method takes no arguments so all configuration and initialization
747 This method takes no arguments so all configuration and initialization
700 must be done prior to calling this method."""
748 must be done prior to calling this method."""
701 ip = self.ip if self.ip else '[all ip addresses on your system]'
702 proto = 'https' if self.certfile else 'http'
703 info = self.log.info
749 info = self.log.info
704 self._url = "%s://%s:%i%s" % (proto, ip, self.port,
705 self.base_project_url)
706 for line in self.notebook_info().split("\n"):
750 for line in self.notebook_info().split("\n"):
707 info(line)
751 info(line)
708 info("Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).")
752 info("Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).")
709
753
754 self.write_server_info_file()
755
710 if self.open_browser or self.file_to_run:
756 if self.open_browser or self.file_to_run:
711 ip = self.ip or localhost()
712 try:
757 try:
713 browser = webbrowser.get(self.browser or None)
758 browser = webbrowser.get(self.browser or None)
714 except webbrowser.Error as e:
759 except webbrowser.Error as e:
715 self.log.warn('No web browser found: %s.' % e)
760 self.log.warn('No web browser found: %s.' % e)
716 browser = None
761 browser = None
717
762
718 nbdir = os.path.abspath(self.notebook_manager.notebook_dir)
719 f = self.file_to_run
763 f = self.file_to_run
720 if f:
764 if f:
765 nbdir = os.path.abspath(self.notebook_manager.notebook_dir)
721 if f.startswith(nbdir):
766 if f.startswith(nbdir):
722 f = f[len(nbdir):]
767 f = f[len(nbdir):]
723 else:
768 else:
@@ -732,8 +777,8 b' class NotebookApp(BaseIPythonApplication):'
732 else:
777 else:
733 url = url_path_join('tree', f)
778 url = url_path_join('tree', f)
734 if browser:
779 if browser:
735 b = lambda : browser.open("%s://%s:%i%s%s" % (proto, ip,
780 b = lambda : browser.open("%s%s" % (self.connection_url, url),
736 self.port, self.base_project_url, url), new=2)
781 new=2)
737 threading.Thread(target=b).start()
782 threading.Thread(target=b).start()
738 try:
783 try:
739 ioloop.IOLoop.instance().start()
784 ioloop.IOLoop.instance().start()
@@ -741,7 +786,21 b' class NotebookApp(BaseIPythonApplication):'
741 info("Interrupted...")
786 info("Interrupted...")
742 finally:
787 finally:
743 self.cleanup_kernels()
788 self.cleanup_kernels()
789 self.remove_server_info_file()
790
791
792 def discover_running_servers(profile='default'):
793 """Iterate over the server info files of running notebook servers.
744
794
795 Given a profile name, find nbserver-* files in the security directory of
796 that profile, and yield dicts of their information, each one pertaining to
797 a currently running notebook server instance.
798 """
799 pd = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), name=profile)
800 for file in os.listdir(pd.security_dir):
801 if file.startswith('nbserver-'):
802 with io.open(os.path.join(pd.security_dir, file), encoding='utf-8') as f:
803 yield json.load(f)
745
804
746 #-----------------------------------------------------------------------------
805 #-----------------------------------------------------------------------------
747 # Main entry point
806 # Main entry point
General Comments 0
You need to be logged in to leave comments. Login now