Skip to content

Commit 9d3e484

Browse files
authored
run coroutine under run_sync. Closes #4122 (#4137)
* run coroutine under run_sync. Closes #4122 * update jupyter_core reqs to include run_sync * upgrade requirements
1 parent 2f66b9b commit 9d3e484

File tree

3 files changed

+59
-11
lines changed

3 files changed

+59
-11
lines changed

src/resources/jupyter/log.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
import sys
33
import logging
4+
import os
45

56
TRACE = 25
67

@@ -12,6 +13,7 @@ def log_init(log_file, trace = False):
1213
else:
1314
logger.setLevel(logging.WARNING)
1415

16+
global file_handler
1517
# create handlers
1618
stderr_handler = logging.StreamHandler(sys.stderr)
1719
file_handler = logging.FileHandler(log_file)
@@ -25,8 +27,14 @@ def log_init(log_file, trace = False):
2527
logger.addHandler(stderr_handler)
2628
logger.addHandler(file_handler)
2729

28-
def log(level, msg):
29-
logging.getLogger().log(level, msg)
30+
# force flushing so programs which hang still produce output
31+
if os.getenv("QUARTO_JUPYTER_FLUSH_LOGS"):
32+
def log(level, msg):
33+
logging.getLogger().log(level, msg)
34+
file_handler.flush()
35+
else:
36+
def log(level, msg):
37+
logging.getLogger().log(level, msg)
3038

3139
def log_error(msg, exc_info = False):
3240
logging.getLogger().log(logging.ERROR, msg, exc_info = exc_info, stack_info = not exc_info)

src/resources/jupyter/notebook.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313

1414
from poyo import parse_string
1515

16+
from log import trace
1617
import nbformat
1718
from nbclient import NotebookClient
19+
from jupyter_client import KernelManager
20+
from jupyter_core.utils import run_sync
1821

1922
# optional import of papermill for params support
2023
try:
@@ -37,6 +40,7 @@ class RestartKernel(Exception):
3740
# execute a notebook
3841
def notebook_execute(options, status):
3942

43+
trace('inside notebook_execute')
4044
# if this is a re-execution of a previously loaded kernel,
4145
# make sure the underlying python version hasn't changed
4246
python_cmd = options.get("python_cmd", None)
@@ -97,6 +101,7 @@ def notebook_execute(options, status):
97101
# read the notebook
98102
nb = nbformat.read(input, as_version = NB_FORMAT_VERSION)
99103

104+
trace('read notebook')
100105
# inject parameters if provided
101106
if params:
102107
nb_parameterize(nb, params)
@@ -108,17 +113,21 @@ def notebook_execute(options, status):
108113
# are we using the cache, if so connect to the cache, and then if we aren't in 'refresh'
109114
# (forced re-execution) mode then try to satisfy the execution request from the cache
110115
if cache == True or cache == "refresh":
116+
trace('using cache')
111117
if not get_cache:
112118
raise ImportError('The jupyter-cache package is required for cached execution')
119+
trace('getting cache')
113120
nb_cache = get_cache(".jupyter_cache")
114121
if not cache == "refresh":
115122
cached_nb = nb_from_cache(nb, nb_cache)
116123
if cached_nb:
117124
cached_nb.cells.pop(0)
118125
nb_write(cached_nb, input)
119126
status("(Notebook read from cache)\n\n")
127+
trace('(Notebook read from cache)')
120128
return True # can persist kernel
121129
else:
130+
trace('not using cache')
122131
nb_cache = None
123132

124133
# create resources for execution
@@ -130,8 +139,11 @@ def notebook_execute(options, status):
130139
if run_path:
131140
resources["metadata"]["path"] = run_path
132141

142+
trace("Will attempt to create notebook")
133143
# create NotebookClient
144+
trace("type of notebook: {0}".format(type(nb)))
134145
client, created = notebook_init(nb, resources, allow_errors)
146+
trace("NotebookClient created")
135147

136148
# complete progress if necessary
137149
if (not quiet) and created:
@@ -155,6 +167,7 @@ def notebook_execute(options, status):
155167

156168
# execute cell
157169
if cell.cell_type == 'code':
170+
trace("Executing cell {0}".format(index))
158171
cell = cell_execute(
159172
client,
160173
cell,
@@ -164,6 +177,7 @@ def notebook_execute(options, status):
164177
index > 0 # add_to_history
165178
)
166179
cell.execution_count = current_code_cell
180+
trace("Executed cell {0}".format(index))
167181

168182
# if this was the setup cell, see if we need to exit b/c dependencies are out of date
169183
if index == 0:
@@ -195,6 +209,9 @@ def notebook_execute(options, status):
195209
# end progress
196210
if progress:
197211
status("Done\n")
212+
trace("Done")
213+
214+
trace("Notebook execution complete")
198215

199216
# set widgets metadata
200217
client.set_widgets_metadata()
@@ -236,14 +253,21 @@ def notebook_init(nb, resources, allow_errors):
236253
created = False
237254
if not hasattr(notebook_init, "client"):
238255

256+
trace("Creating NotebookClient")
239257
# create notebook client
240258
client = NotebookClient(nb, resources = resources)
241259
client.allow_errors = allow_errors
242260
client.record_timing = False
243261
client.create_kernel_manager()
244262
client.start_new_kernel()
245263
client.start_new_kernel_client()
246-
info_msg = client.wait_for_reply(client.kc.kernel_info())
264+
info = client.kc.kernel_info()
265+
266+
async def get_info():
267+
return await client.kc.kernel_info()
268+
info = run_sync(get_info)()
269+
270+
info_msg = client.wait_for_reply(info)
247271
client.nb.metadata['language_info'] = info_msg['content']['language_info']
248272
notebook_init.client = client
249273
created = True

tests/requirements.txt

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
anyio==3.6.2
12
appnope==0.1.2
23
argon2-cffi==20.1.0
34
async-generator==1.10
45
attrs==21.2.0
56
backcall==0.2.0
7+
beautifulsoup4==4.11.1
68
bleach==3.3.0
79
bokeh==3.0.3
810
cffi==1.14.5
@@ -11,7 +13,9 @@ cycler==0.10.0
1113
decorator==5.0.9
1214
defusedxml==0.7.1
1315
entrypoints==0.3
16+
fastjsonschema==2.16.2
1417
fonttools==4.38.0
18+
idna==3.4
1519
ipykernel==5.5.5
1620
ipython==7.25.0
1721
ipython-genutils==0.2.0
@@ -20,19 +24,23 @@ jedi==0.18.0
2024
Jinja2==3.0.1
2125
jsonschema==3.2.0
2226
jupyter==1.0.0
23-
jupyter-client==6.1.12
24-
jupyter-console==6.4.0
25-
jupyter-core==4.7.1
27+
jupyter-console==6.4.4
28+
jupyter-events==0.6.3
29+
jupyter_client==8.0.1
30+
jupyter_core==5.1.5
31+
jupyter_server==2.1.0
32+
jupyter_server_terminals==0.4.4
2633
jupyterlab-pygments==0.1.2
2734
jupyterlab-widgets==1.0.0
2835
kiwisolver==1.4.4
36+
lxml==4.9.2
2937
MarkupSafe==2.0.1
3038
matplotlib==3.5.3
3139
matplotlib-inline==0.1.2
3240
mistune==0.8.4
3341
nbclient==0.5.3
34-
nbconvert==6.1.0
35-
nbformat==5.1.3
42+
nbconvert==6.5.4
43+
nbformat==5.7.3
3644
nest-asyncio==1.5.1
3745
notebook==6.4.0
3846
numpy==1.23.2
@@ -43,26 +51,34 @@ parso==0.8.2
4351
pexpect==4.8.0
4452
pickleshare==0.7.5
4553
Pillow==9.2.0
54+
platformdirs==2.6.2
4655
prometheus-client==0.11.0
4756
prompt-toolkit==3.0.19
4857
ptyprocess==0.7.0
4958
pycparser==2.20
5059
Pygments==2.9.0
5160
pyparsing==3.0.9
5261
pyrsistent==0.17.3
53-
python-dateutil==2.8.1
62+
python-dateutil==2.8.2
63+
python-json-logger==2.0.4
5464
pytz==2022.7.1
5565
PyYAML==6.0
5666
pyzmq==24.0.1
5767
qtconsole==5.1.0
5868
QtPy==1.9.0
69+
rfc3339-validator==0.1.4
70+
rfc3986-validator==0.1.1
5971
Send2Trash==1.7.1
6072
six==1.16.0
73+
sniffio==1.3.0
74+
soupsieve==2.3.2.post1
6175
terminado==0.10.1
6276
testpath==0.5.0
63-
tornado==6.1
64-
traitlets==5.0.5
77+
tinycss2==1.2.1
78+
tornado==6.2
79+
traitlets==5.8.1
6580
wcwidth==0.2.5
6681
webencodings==0.5.1
82+
websocket-client==1.5.0
6783
widgetsnbextension==3.5.1
6884
xyzservices==2022.9.0

0 commit comments

Comments
 (0)