77
88from traitlets .config import LoggingConfigurable
99from traitlets import (
10- Any ,
11- Bool ,
1210 Dict ,
1311 Instance ,
14- List ,
15- TraitError ,
16- Type ,
17- Unicode ,
1812 Int ,
19- default ,
20- validate ,
13+ default
2114)
2215
2316from jupyter_core .paths import jupyter_runtime_dir
@@ -36,7 +29,6 @@ def _default_outputs_path(self):
3629
3730 def _ensure_path (self , file_id , cell_id ):
3831 nested_dir = self .outputs_path / file_id / cell_id
39- self .log .info (f"Creating directory: { nested_dir } " )
4032 nested_dir .mkdir (parents = True , exist_ok = True )
4133
4234 def _build_path (self , file_id , cell_id = None , output_index = None ):
@@ -49,7 +41,6 @@ def _build_path(self, file_id, cell_id=None, output_index=None):
4941
5042 def get_output (self , file_id , cell_id , output_index ):
5143 """Get an outputs by file_id, cell_id, and output_index."""
52- self .log .info (f"OutputsManager.get: { file_id } { cell_id } { output_index } " )
5344 path = self ._build_path (file_id , cell_id , output_index )
5445 if not os .path .isfile (path ):
5546 raise FileNotFoundError (f"The output file doesn't exist: { path } " )
@@ -67,12 +58,15 @@ def get_stream(self, file_id, cell_id):
6758 return output
6859
6960 def write (self , file_id , cell_id , output ):
70- """Write a new output for file_id and cell_id."""
71- self .log .info (f"OutputsManager.write: { file_id } { cell_id } { output } " )
72- result = self .write_output (file_id , cell_id , output )
61+ """Write a new output for file_id and cell_id.
62+
63+ Returns a placeholder output (pycrdt.Map) or None if no placeholder
64+ output should be written to the ydoc.
65+ """
66+ placeholder = self .write_output (file_id , cell_id , output )
7367 if output ["output_type" ] == "stream" and self .stream_limit is not None :
74- result = self .write_stream (file_id , cell_id , output )
75- return result
68+ placeholder = self .write_stream (file_id , cell_id , output , placeholder )
69+ return placeholder
7670
7771 def write_output (self , file_id , cell_id , output ):
7872 self ._ensure_path (file_id , cell_id )
@@ -84,9 +78,10 @@ def write_output(self, file_id, cell_id, output):
8478 with open (path , "w" , encoding = "utf-8" ) as f :
8579 f .write (data )
8680 url = f"/api/outputs/{ file_id } /{ cell_id } /{ index } .output"
87- return Map ({})
81+ self .log .info (f"Wrote output: { url } " )
82+ return create_placeholder_output (output ["output_type" ], url )
8883
89- def write_stream (self , file_id , cell_id , output ) -> Map :
84+ def write_stream (self , file_id , cell_id , output , placeholder ) -> Map :
9085 # How many stream outputs have been written for this cell previously
9186 count = self ._stream_count .get (cell_id , 0 )
9287
@@ -98,15 +93,16 @@ def write_stream(self, file_id, cell_id, output) -> Map:
9893 with open (path , "a" , encoding = "utf-8" ) as f :
9994 f .write (text )
10095 url = f"/api/outputs/{ file_id } /{ cell_id } /stream"
96+ self .log .info (f"Wrote stream: { url } " )
10197
10298 # Increment the count
10399 count = count + 1
104100 self ._stream_count [cell_id ] = count
105101
106102 # Now create the placeholder output
107103 if count < self .stream_limit :
108- # Return the original if we haven't reached the limit
109- placeholder = Map ( output )
104+ # Return the original placeholder if we haven't reached the limit
105+ placeholder = placeholder
110106 elif count == self .stream_limit :
111107 # Return a link to the full stream output
112108 placeholder = Map ({
@@ -116,6 +112,7 @@ def write_stream(self, file_id, cell_id, output) -> Map:
116112 }
117113 })
118114 elif count > self .stream_limit :
115+ # Return None to indicate that no placeholder should be written to the ydoc
119116 placeholder = None
120117 return placeholder
121118
@@ -130,4 +127,33 @@ def clear(self, file_id, cell_id=None):
130127 except KeyError :
131128 pass
132129 path = self ._build_path (file_id , cell_id )
133- shutil .rmtree (path )
130+ try :
131+ shutil .rmtree (path )
132+ except FileNotFoundError :
133+ pass
134+
135+
136+ def create_placeholder_output (output_type : str , url : str ):
137+ metadata = dict (url = url )
138+ if output_type == "stream" :
139+ output = Map ({
140+ "output_type" : "stream" ,
141+ "text" : "" ,
142+ "metadata" : metadata
143+ })
144+ elif output_type == "display_data" :
145+ output = Map ({
146+ "output_type" : "display_data" ,
147+ "metadata" : metadata
148+ })
149+ elif output_type == "execute_result" :
150+ output = Map ({
151+ "output_type" : "execute_result" ,
152+ "metadata" : metadata
153+ })
154+ elif output_type == "error" :
155+ output = Map ({
156+ "output_type" : "error" ,
157+ "metadata" : metadata
158+ })
159+ return output
0 commit comments