2
2
# Licensed under the MIT License.
3
3
4
4
import json
5
- import sys
6
5
import logging
7
6
import os
7
+ import subprocess
8
+ import sys
8
9
from datascience .daemon .daemon_python import (
9
10
error_decorator ,
10
11
PythonDaemon as BasePythonDaemon ,
@@ -26,18 +27,47 @@ def m_exec_module(self, module_name, args=[], cwd=None, env=None):
26
27
self .log .info ("Exec in DS Daemon %s with args %s" , module_name , args )
27
28
args = [] if args is None else args
28
29
29
- if module_name == "jupyter" and args == ["kernelspec" , "list" , "--json" ]:
30
- return self ._execute_and_capture_output (self ._print_kernel_list_json )
31
- elif module_name == "jupyter" and args == ["kernelspec" , "list" ]:
32
- return self ._execute_and_capture_output (self ._print_kernel_list )
33
- elif module_name == "jupyter" and args == ["kernelspec" , "--version" ]:
34
- return self ._execute_and_capture_output (self ._print_kernelspec_version )
35
- elif module_name == "jupyter" and args [0 ] == "nbconvert" and args [- 1 ] != "--version" :
36
- return self ._execute_and_capture_output (lambda : self ._convert (args ))
30
+ if module_name == "jupyter" :
31
+ if args [0 ] == "kernelspec" and self ._is_module_installed ("jupyter_client.kernelspec" ):
32
+ if args == ["kernelspec" , "list" , "--json" ]:
33
+ return self ._execute_and_capture_output (self ._print_kernel_list_json )
34
+ elif args == ["kernelspec" , "list" ]:
35
+ return self ._execute_and_capture_output (self ._print_kernel_list )
36
+ elif args == ["kernelspec" , "--version" ]:
37
+ return self ._execute_and_capture_output (self ._print_kernelspec_version )
38
+ if args [0 ] == "nbconvert" and self ._is_module_installed ("nbconvert" ) and args [- 1 ] != "--version" :
39
+ return self ._execute_and_capture_output (lambda : self ._convert (args ))
40
+ if args [0 ] == "notebook" and args [1 ] == "--version" :
41
+ try :
42
+ from notebook import notebookapp as app
43
+ return {"stdout" : '.' .join (list (str (v ) for v in app .version_info ))}
44
+ except Exception :
45
+ pass
46
+ # kernelspec, nbconvert are subcommands of jupyter.
47
+ # python -m jupyter kernelspec, python -m jupyter nbconvert,
48
+ # In such cases, even if the modules kernelspec or nbconvert are not installed in the current
49
+ # environment, jupyter will find them in current path.
50
+ # So if we cannot find the corresponding subcommands, lets revert to subprocess.
51
+ self .log .info ("Exec in DS Daemon with as subprocess, %s with args %s" , module_name , args )
52
+ return self ._exec_with_subprocess (module_name , args , cwd , env )
37
53
else :
38
54
self .log .info ("check base class stuff" )
39
55
return super ().m_exec_module (module_name , args , cwd , env )
40
56
57
+ def _exec_with_subprocess (self , module_name , args = [], cwd = None , env = None ):
58
+ # # result = subprocess.run([sys.executable, "-m"] + args, stdout=sys.stdout, stderr=sys.stderr)
59
+ # return self._execute_and_capture_output(lambda: subprocess.run([sys.executable, "-m", module_name] + args, stdout=sys.stdout, stderr=sys.stderr))
60
+ result = subprocess .run ([sys .executable , "-m" , module_name ] + args , capture_output = True )
61
+ encoding = os .getenv ('PYTHONIOENCODING' , 'utf-8' )
62
+ stdout = result .stdout .decode (encoding )
63
+ stderr = result .stderr .decode (encoding )
64
+ self .log .info ("subprocess output for, %s with args %s, \n stdout is %s, \n stderr is %s" ,
65
+ module_name , args , stdout , stderr )
66
+ return {
67
+ "stdout" : stdout ,
68
+ "stderr" : stderr
69
+ }
70
+
41
71
@error_decorator
42
72
def m_exec_module_observable (self , module_name , args = None , cwd = None , env = None ):
43
73
self .log .info ("Exec in DS Daemon (observable) %s with args %s" , module_name , args )
@@ -50,13 +80,7 @@ def m_exec_module_observable(self, module_name, args=None, cwd=None, env=None):
50
80
if (module_name == "jupyter" and args [0 ] == "notebook" ) or (
51
81
module_name == "notebook"
52
82
):
53
- # Args must not have ['notebook'] in the begining. Drop the `notebook` subcommand when using `jupyter`
54
- args = args [1 :] if args [0 ] == "notebook" else args
55
- self .log .info ("Starting notebook with args %s" , args )
56
-
57
- # When launching notebook always ensure the first argument is `notebook`.
58
- with change_exec_context (args , cwd , env ):
59
- self ._start_notebook (args )
83
+ self ._start_notebook (args , cwd , env )
60
84
else :
61
85
return super ().m_exec_module_observable (module_name , args , cwd , env )
62
86
@@ -107,8 +131,13 @@ def _convert(self, args):
107
131
sys .argv = ["" ] + args
108
132
app .main ()
109
133
110
- def _start_notebook (self , args ):
134
+ def _start_notebook (self , args , cwd , env ):
111
135
from notebook import notebookapp as app
112
136
113
- sys .argv = ["" ] + args
114
- app .launch_new_instance ()
137
+ # Args must not have ['notebook'] in the begining. Drop the `notebook` subcommand when using `jupyter`
138
+ args = args [1 :] if args [0 ] == "notebook" else args
139
+ self .log .info ("Starting notebook with args %s" , args )
140
+
141
+ # When launching notebook always ensure the first argument is `notebook`.
142
+ with change_exec_context (args , cwd , env ):
143
+ app .launch_new_instance ()
0 commit comments