You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
6.1 KiB

4 years ago
  1. """Connection file-related utilities for the kernel
  2. """
  3. # Copyright (c) IPython Development Team.
  4. # Distributed under the terms of the Modified BSD License.
  5. from __future__ import absolute_import
  6. import json
  7. import sys
  8. from subprocess import Popen, PIPE
  9. import warnings
  10. from IPython.core.profiledir import ProfileDir
  11. from IPython.paths import get_ipython_dir
  12. from ipython_genutils.path import filefind
  13. from ipython_genutils.py3compat import str_to_bytes, PY3
  14. import jupyter_client
  15. from jupyter_client import write_connection_file
  16. def get_connection_file(app=None):
  17. """Return the path to the connection file of an app
  18. Parameters
  19. ----------
  20. app : IPKernelApp instance [optional]
  21. If unspecified, the currently running app will be used
  22. """
  23. if app is None:
  24. from ipykernel.kernelapp import IPKernelApp
  25. if not IPKernelApp.initialized():
  26. raise RuntimeError("app not specified, and not in a running Kernel")
  27. app = IPKernelApp.instance()
  28. return filefind(app.connection_file, ['.', app.connection_dir])
  29. def find_connection_file(filename='kernel-*.json', profile=None):
  30. """DEPRECATED: find a connection file, and return its absolute path.
  31. THIS FUNCION IS DEPRECATED. Use juptyer_client.find_connection_file instead.
  32. Parameters
  33. ----------
  34. filename : str
  35. The connection file or fileglob to search for.
  36. profile : str [optional]
  37. The name of the profile to use when searching for the connection file,
  38. if different from the current IPython session or 'default'.
  39. Returns
  40. -------
  41. str : The absolute path of the connection file.
  42. """
  43. import warnings
  44. warnings.warn("""ipykernel.find_connection_file is deprecated, use jupyter_client.find_connection_file""",
  45. DeprecationWarning, stacklevel=2)
  46. from IPython.core.application import BaseIPythonApplication as IPApp
  47. try:
  48. # quick check for absolute path, before going through logic
  49. return filefind(filename)
  50. except IOError:
  51. pass
  52. if profile is None:
  53. # profile unspecified, check if running from an IPython app
  54. if IPApp.initialized():
  55. app = IPApp.instance()
  56. profile_dir = app.profile_dir
  57. else:
  58. # not running in IPython, use default profile
  59. profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), 'default')
  60. else:
  61. # find profiledir by profile name:
  62. profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile)
  63. security_dir = profile_dir.security_dir
  64. return jupyter_client.find_connection_file(filename, path=['.', security_dir])
  65. def _find_connection_file(connection_file, profile=None):
  66. """Return the absolute path for a connection file
  67. - If nothing specified, return current Kernel's connection file
  68. - If profile specified, show deprecation warning about finding connection files in profiles
  69. - Otherwise, call jupyter_client.find_connection_file
  70. """
  71. if connection_file is None:
  72. # get connection file from current kernel
  73. return get_connection_file()
  74. else:
  75. # connection file specified, allow shortnames:
  76. if profile is not None:
  77. warnings.warn(
  78. "Finding connection file by profile is deprecated.",
  79. DeprecationWarning, stacklevel=3,
  80. )
  81. return find_connection_file(connection_file, profile=profile)
  82. else:
  83. return jupyter_client.find_connection_file(connection_file)
  84. def get_connection_info(connection_file=None, unpack=False, profile=None):
  85. """Return the connection information for the current Kernel.
  86. Parameters
  87. ----------
  88. connection_file : str [optional]
  89. The connection file to be used. Can be given by absolute path, or
  90. IPython will search in the security directory of a given profile.
  91. If run from IPython,
  92. If unspecified, the connection file for the currently running
  93. IPython Kernel will be used, which is only allowed from inside a kernel.
  94. unpack : bool [default: False]
  95. if True, return the unpacked dict, otherwise just the string contents
  96. of the file.
  97. profile : DEPRECATED
  98. Returns
  99. -------
  100. The connection dictionary of the current kernel, as string or dict,
  101. depending on `unpack`.
  102. """
  103. cf = _find_connection_file(connection_file, profile)
  104. with open(cf) as f:
  105. info = f.read()
  106. if unpack:
  107. info = json.loads(info)
  108. # ensure key is bytes:
  109. info['key'] = str_to_bytes(info.get('key', ''))
  110. return info
  111. def connect_qtconsole(connection_file=None, argv=None, profile=None):
  112. """Connect a qtconsole to the current kernel.
  113. This is useful for connecting a second qtconsole to a kernel, or to a
  114. local notebook.
  115. Parameters
  116. ----------
  117. connection_file : str [optional]
  118. The connection file to be used. Can be given by absolute path, or
  119. IPython will search in the security directory of a given profile.
  120. If run from IPython,
  121. If unspecified, the connection file for the currently running
  122. IPython Kernel will be used, which is only allowed from inside a kernel.
  123. argv : list [optional]
  124. Any extra args to be passed to the console.
  125. profile : DEPRECATED
  126. Returns
  127. -------
  128. :class:`subprocess.Popen` instance running the qtconsole frontend
  129. """
  130. argv = [] if argv is None else argv
  131. cf = _find_connection_file(connection_file, profile)
  132. cmd = ';'.join([
  133. "from IPython.qt.console import qtconsoleapp",
  134. "qtconsoleapp.main()"
  135. ])
  136. kwargs = {}
  137. if PY3:
  138. # Launch the Qt console in a separate session & process group, so
  139. # interrupting the kernel doesn't kill it. This kwarg is not on Py2.
  140. kwargs['start_new_session'] = True
  141. return Popen([sys.executable, '-c', cmd, '--existing', cf] + argv,
  142. stdout=PIPE, stderr=PIPE, close_fds=(sys.platform != 'win32'),
  143. **kwargs
  144. )
  145. __all__ = [
  146. 'write_connection_file',
  147. 'get_connection_file',
  148. 'find_connection_file',
  149. 'get_connection_info',
  150. 'connect_qtconsole',
  151. ]