|
2 | 2 | import json |
3 | 3 | import os |
4 | 4 | import shutil |
5 | | -import subprocess |
6 | 5 | import sys |
7 | 6 | import tempfile |
8 | 7 |
|
9 | 8 | 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 | 9 |
|
22 | 10 | rootKernelFileContent = ( |
23 | 11 | """{ |
|
32 | 20 | ] |
33 | 21 | } |
34 | 22 | """ |
35 | | - % pythonInterpName |
| 23 | + % sys.executable |
36 | 24 | ) |
37 | 25 |
|
38 | 26 |
|
@@ -149,34 +137,49 @@ def addEtcToEnvironment(inNBDirName): |
149 | 137 | return ipythondir |
150 | 138 |
|
151 | 139 |
|
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 | | - |
160 | 140 | def getKernelName(inNBName): |
161 | 141 | with open(inNBName) as f: |
162 | 142 | nbj = json.load(f) |
163 | 143 | if nbj["metadata"]["kernelspec"]["language"] == "python": |
164 | | - return pythonInterpName |
| 144 | + return "python3" |
165 | 145 | else: # we support only Python and C++ |
166 | 146 | return "root" |
167 | 147 |
|
168 | 148 |
|
169 | | -def canReproduceNotebook(inNBName, kernelName, needsCompare): |
| 149 | +def canReproduceNotebook(inNBName, needsCompare): |
| 150 | + from nbconvert import NotebookExporter |
| 151 | + from nbconvert.preprocessors import ExecutePreprocessor |
| 152 | + import nbformat |
| 153 | + |
170 | 154 | tmpDir = addEtcToEnvironment(os.path.dirname(inNBName)) |
171 | 155 | 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) |
| 156 | + |
| 157 | + # Load input notebook |
| 158 | + with open(inNBName, "r", encoding="utf-8") as f: |
| 159 | + nb = nbformat.read(f, as_version=4) |
| 160 | + |
| 161 | + # Configure execution |
| 162 | + ep = ExecutePreprocessor( |
| 163 | + kernel_name=getKernelName(inNBName), |
| 164 | + timeout=3600, |
| 165 | + startup_timeout=180, |
| 166 | + allow_errors=False, |
| 167 | + ) |
| 168 | + |
| 169 | + # Run the notebook |
| 170 | + ep.preprocess(nb, {"metadata": {"path": os.path.dirname(inNBName)}}) |
| 171 | + |
| 172 | + # Export executed notebook |
| 173 | + with open(outNBName, "w", encoding="utf-8") as f: |
| 174 | + nbformat.write(nb, f) |
| 175 | + |
| 176 | + # Compare or return success |
176 | 177 | if needsCompare: |
177 | 178 | return compareNotebooks(inNBName, outNBName) |
178 | 179 | else: |
179 | | - return exitStatus |
| 180 | + return 0 # success |
| 181 | + |
| 182 | + shutil.rmtree(tmpDir) |
180 | 183 |
|
181 | 184 |
|
182 | 185 | def isInputNotebookFileName(filename): |
@@ -206,7 +209,5 @@ def isInputNotebookFileName(filename): |
206 | 209 | except: |
207 | 210 | raise ImportError("Cannot import jupyter") |
208 | 211 |
|
209 | | - kernelName = getKernelName(nbFileName) |
210 | | - |
211 | | - retCode = canReproduceNotebook(nbFileName, kernelName, needsCompare) |
| 212 | + retCode = canReproduceNotebook(nbFileName, needsCompare) |
212 | 213 | sys.exit(retCode) |
0 commit comments