22import json
33import os
44import shutil
5- import subprocess
65import sys
76import tempfile
87
9- nbExtension = ".ipynb"
10- convCmdTmpl = (
11- "%s nbconvert "
12- "--to notebook "
13- "--ExecutePreprocessor.kernel_name=%s "
14- "--ExecutePreprocessor.enabled=True "
15- "--ExecutePreprocessor.timeout=3600 "
16- "--ExecutePreprocessor.startup_timeout=180 "
17- "%s "
18- "--output %s"
19- )
20- pythonInterpName = "python3"
21-
22- rootKernelFileContent = (
23- """{
24- "language": "c++",
25- "display_name": "ROOT C++",
26- "argv": [
27- "%s",
28- "-m",
29- "JupyROOT.kernel.rootkernel",
30- "-f",
31- "{connection_file}"
32- ]
33- }
34- """
35- % pythonInterpName
36- )
37-
388
399# Replace the criterion according to which a line shall be skipped
4010def customLineJunkFilter (line ):
@@ -134,7 +104,21 @@ def createKernelSpec():
134104 rootKernelPath = os .path .join (kernelsPath , "root" )
135105 os .mkdir (rootKernelPath )
136106 with open (os .path .join (rootKernelPath , "kernel.json" ), "w" ) as kernel_file :
137- kernel_file .write (rootKernelFileContent )
107+ kernel_file .write (
108+ """{
109+ "language": "c++",
110+ "display_name": "ROOT C++",
111+ "argv": [
112+ "%s",
113+ "-m",
114+ "JupyROOT.kernel.rootkernel",
115+ "-f",
116+ "{connection_file}"
117+ ]
118+ }
119+ """
120+ % sys .executable
121+ )
138122
139123 return tmpd
140124
@@ -149,39 +133,53 @@ def addEtcToEnvironment(inNBDirName):
149133 return ipythondir
150134
151135
152- def getInterpreterName ():
153- """Find if the 'jupyter' executable is available on the platform. If
154- yes, return its name else return 'ipython'
155- """
156- ret = subprocess .call ("type jupyter" , shell = True , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
157- return "jupyter" if ret == 0 else "i%s" % pythonInterpName
158-
159-
160136def getKernelName (inNBName ):
161137 with open (inNBName ) as f :
162138 nbj = json .load (f )
163139 if nbj ["metadata" ]["kernelspec" ]["language" ] == "python" :
164- return pythonInterpName
140+ return "python3"
165141 else : # we support only Python and C++
166142 return "root"
167143
168144
169- def canReproduceNotebook (inNBName , kernelName , needsCompare ):
145+ def canReproduceNotebook (inNBName , needsCompare ):
146+ import nbformat
147+ from nbconvert .preprocessors import ExecutePreprocessor
148+
170149 tmpDir = addEtcToEnvironment (os .path .dirname (inNBName ))
171- outNBName = inNBName .replace (nbExtension , "_out" + nbExtension )
172- interpName = getInterpreterName ()
173- convCmd = convCmdTmpl % (interpName , kernelName , inNBName , outNBName )
174- exitStatus = os .system (convCmd ) # we use system to inherit the environment in os.environ
175- shutil .rmtree (tmpDir )
150+ outNBName = inNBName .replace (".ipynb" , "_out.ipynb" )
151+
152+ # Load input notebook
153+ with open (inNBName , "r" , encoding = "utf-8" ) as f :
154+ nb = nbformat .read (f , as_version = 4 )
155+
156+ # Configure execution
157+ ep = ExecutePreprocessor (
158+ kernel_name = getKernelName (inNBName ),
159+ timeout = 3600 ,
160+ startup_timeout = 180 ,
161+ allow_errors = False ,
162+ )
163+
164+ # Run the notebook
165+ ep .preprocess (nb , {"metadata" : {"path" : os .path .dirname (inNBName )}})
166+
167+ # Export executed notebook
168+ with open (outNBName , "w" , encoding = "utf-8" ) as f :
169+ nbformat .write (nb , f )
170+
171+ # Compare or return success
176172 if needsCompare :
177173 return compareNotebooks (inNBName , outNBName )
178174 else :
179- return exitStatus
175+ return 0 # success
176+
177+ shutil .rmtree (tmpDir )
180178
181179
182180def isInputNotebookFileName (filename ):
183181 if not filename .endswith (".ipynb" ):
184- print ("Notebook files shall have the %s extension" % nbExtension )
182+ print ("Notebook files shall have the .ipynb extension" )
185183 return False
186184 return True
187185
@@ -200,13 +198,5 @@ def isInputNotebookFileName(filename):
200198 if not isInputNotebookFileName (nbFileName ):
201199 sys .exit (1 )
202200
203- try :
204- # If jupyter is there, ipython is too
205- import jupyter
206- except :
207- raise ImportError ("Cannot import jupyter" )
208-
209- kernelName = getKernelName (nbFileName )
210-
211- retCode = canReproduceNotebook (nbFileName , kernelName , needsCompare )
201+ retCode = canReproduceNotebook (nbFileName , needsCompare )
212202 sys .exit (retCode )
0 commit comments