1
1
import atexit
2
2
import collections
3
3
import datetime
4
+ import enum
4
5
import base64
5
6
import signal
6
7
from textwrap import dedent
@@ -32,6 +33,15 @@ def timestamp():
32
33
return datetime .datetime .utcnow ().isoformat () + 'Z'
33
34
34
35
36
+ class ExecutionState (enum .Enum ):
37
+ NOTHING = 0
38
+ STARTUP = 1
39
+ STARTING_KERNEL_CLIENT = 2
40
+ EXECUTING = 3
41
+ CLEANING_UP = 4
42
+ COMPLETE = 5
43
+
44
+
35
45
class NotebookClient (LoggingConfigurable ):
36
46
"""
37
47
Encompasses a Client for executing cells in a notebook
@@ -310,6 +320,9 @@ def reset_execution_trackers(self):
310
320
self .output_hook_stack = collections .defaultdict (list )
311
321
# our front-end mimicing Output widgets
312
322
self .comm_objects = {}
323
+ self .state = ExecutionState .NOTHING
324
+ self .current_cell = None
325
+ self .current_cell_index = - 1
313
326
314
327
def start_kernel_manager (self ):
315
328
"""Creates a new kernel manager.
@@ -332,6 +345,7 @@ def start_kernel_manager(self):
332
345
return self .km
333
346
334
347
async def _async_cleanup_kernel (self ):
348
+ self .state = ExecutionState .CLEANING_UP
335
349
now = self .shutdown_kernel == "immediate"
336
350
try :
337
351
# Queue the manager to kill the process, and recover gracefully if it's already dead.
@@ -367,6 +381,8 @@ async def async_start_new_kernel_client(self, **kwargs):
367
381
kernel_id : string-ized version 4 uuid
368
382
The id of the started kernel.
369
383
"""
384
+
385
+ self .state = ExecutionState .STARTING_KERNEL_CLIENT
370
386
resource_path = self .resources .get ('metadata' , {}).get ('path' ) or None
371
387
if resource_path and 'cwd' not in kwargs :
372
388
kwargs ["cwd" ] = resource_path
@@ -499,8 +515,10 @@ async def async_execute(self, reset_kc=False, **kwargs):
499
515
if reset_kc and self .km :
500
516
await self ._async_cleanup_kernel ()
501
517
self .reset_execution_trackers ()
518
+ self .state = ExecutionState .STARTUP
502
519
503
520
async with self .async_setup_kernel (** kwargs ):
521
+ self .state = ExecutionState .EXECUTING
504
522
self .log .info ("Executing notebook with kernel: %s" % self .kernel_name )
505
523
for index , cell in enumerate (self .nb .cells ):
506
524
# Ignore `'execution_count' in content` as it's always 1
@@ -512,7 +530,7 @@ async def async_execute(self, reset_kc=False, **kwargs):
512
530
info_msg = await self .async_wait_for_reply (msg_id )
513
531
self .nb .metadata ['language_info' ] = info_msg ['content' ]['language_info' ]
514
532
self .set_widgets_metadata ()
515
-
533
+ self . state = ExecutionState . COMPLETE
516
534
return self .nb
517
535
518
536
execute = run_sync (async_execute )
@@ -711,6 +729,9 @@ async def async_execute_cell(self, cell, cell_index, execution_count=None, store
711
729
if self .record_timing and 'execution' not in cell ['metadata' ]:
712
730
cell ['metadata' ]['execution' ] = {}
713
731
732
+ self .current_cell = cell
733
+ self .current_cell_index = cell_index
734
+
714
735
self .log .debug ("Executing cell:\n %s" , cell .source )
715
736
parent_msg_id = await ensure_async (
716
737
self .kc .execute (
0 commit comments