@@ -191,6 +191,9 @@ async def forward_data_task(
191
191
while True :
192
192
data = await reader .read (8192 )
193
193
if len (data ) == 0 :
194
+ print (
195
+ f"{ PKG_NAME } : { self .name } { dir_str } : read EOF; shutdown with exit_status={ exit_status } "
196
+ )
194
197
await exit_q .put (exit_status )
195
198
return
196
199
if self .verbose >= 4 :
@@ -210,17 +213,15 @@ async def forward_data_task(
210
213
# exit since Jupyter thinks the kernel has stopped. We sit in the
211
214
# middle of the heartbeat loop so we know when the kernel is stopped.
212
215
#
213
- async def kernel_run (config_filename : str , verbose : int ) -> None :
216
+ async def kernel_run (config : dict , verbose : int ) -> None :
214
217
"""Start a new pyscript kernel."""
215
218
port_names = ["hb_port" , "stdin_port" , "shell_port" , "iopub_port" , "control_port" ]
216
219
hass_host = CONFIG_SETTINGS ["hass_host" ]
217
220
hass_url = CONFIG_SETTINGS ["hass_url" ].rstrip ("/" )
218
221
hass_proxy = CONFIG_SETTINGS ["hass_proxy" ]
219
222
220
223
connector = proxy .ProxyConnector .from_url (hass_proxy ) if hass_proxy else None
221
- headers = {
222
- "Authorization" : f'Bearer { CONFIG_SETTINGS ["hass_token" ]} ' ,
223
- }
224
+ headers = {"Authorization" : f'Bearer { CONFIG_SETTINGS ["hass_token" ]} ' }
224
225
session = aiohttp .ClientSession (connector = connector , headers = headers , raise_for_status = True )
225
226
226
227
async def do_request (
@@ -237,17 +238,13 @@ async def do_request(
237
238
print (
238
239
f"{ PKG_NAME } : request failed with { err .status } : { err .message } (url={ err .request_info .url } )"
239
240
)
241
+ await session .close ()
240
242
sys .exit (1 )
241
243
except Exception as err :
242
244
print (f"{ PKG_NAME } : got error { err } (url={ url } )" )
245
+ await session .close ()
243
246
sys .exit (1 )
244
247
245
- with open (config_filename , "r" ) as fdesc :
246
- config = json .load (fdesc )
247
-
248
- if verbose >= 1 :
249
- print (f"{ PKG_NAME } : got jupyter client config={ config } " )
250
-
251
248
#
252
249
# The kernel generates its own port numbers since it might be on another host,
253
250
# so we delete the client ports. Also, it needs the name of a state variable to
@@ -349,18 +346,74 @@ async def do_request(
349
346
sys .exit (exit_status )
350
347
351
348
349
+ def remove_quotes (string ):
350
+ """Strip leading/trailing quotes from string, which VSCode strangely adds to arguments."""
351
+ if string [0 ] == string [- 1 ] and string [0 ] in ('"' , "'" ):
352
+ return string [1 :- 1 ]
353
+ if len (string ) > 1 and string [0 ] == "b" and string [1 ] == string [- 1 ] and string [1 ] in ('"' , "'" ):
354
+ return string [2 :- 1 ]
355
+ return string
356
+
357
+
352
358
def main () -> None :
353
359
"""Main function: start a new pyscript kernel."""
360
+
354
361
parser = argparse .ArgumentParser (prog = PKG_NAME )
355
- parser .add_argument ("config_file" , type = str , help = "json kernel config file generated by Jupyter" )
356
362
parser .add_argument (
357
- "-v" , "--verbose" , action = "count" , help = "increase output verbosity (repeat up to 4x)" ,
363
+ "-v" , "--verbose" , action = "count" , help = "increase verbosity (repeat up to 4x)" , default = 0
358
364
)
359
365
parser .add_argument (
360
366
"-k" , "--kernel-name" , type = str , help = "kernel name" , default = "pyscript" , dest = "kernel_name"
361
367
)
368
+ parser .add_argument ("-f" , "--f" , type = str , help = "json config file" , dest = "config_file" )
369
+ parser .add_argument ("--ip" , type = str , help = "ip address" )
370
+ parser .add_argument ("--stdin" , type = int , help = "stdin port" )
371
+ parser .add_argument ("--control" , type = int , help = "control port" )
372
+ parser .add_argument ("--hb" , type = int , help = "hb port" )
373
+ parser .add_argument ("--shell" , type = int , help = "shell port" )
374
+ parser .add_argument ("--iopub" , type = int , help = "iopub port" )
375
+ parser .add_argument (
376
+ "--Session.signature_scheme" , dest = "signature_scheme" , type = str , help = "signature scheme"
377
+ )
378
+ parser .add_argument ("--Session.key" , type = str , dest = "key" , help = "session key" )
379
+ parser .add_argument ("--transport" , type = str , help = "transport" )
380
+
362
381
args = parser .parse_args ()
363
382
364
383
load_config (args .kernel_name )
365
384
366
- asyncio .run (kernel_run (args .config_file , args .verbose if args .verbose else 0 ))
385
+ if args .config_file is not None and args .ip is None and args .stdin is None :
386
+ #
387
+ # read the json config file (-f or --f) to get the connection parameters
388
+ #
389
+ with open (args .config_file , "r" ) as fdesc :
390
+ config = json .load (fdesc )
391
+ else :
392
+ #
393
+ # no json config file, so use the command-line arguments instead
394
+ #
395
+ config = {
396
+ "ip" : args .ip ,
397
+ "stdin_port" : args .stdin ,
398
+ "control_port" : args .control ,
399
+ "hb_port" : args .hb ,
400
+ "iopub_port" : args .iopub ,
401
+ "shell_port" : args .shell ,
402
+ "transport" : remove_quotes (args .transport ),
403
+ "signature_scheme" : remove_quotes (args .signature_scheme ),
404
+ "key" : remove_quotes (args .key ),
405
+ }
406
+ missing = []
407
+ for arg , value in sorted (config .items ()):
408
+ if value is None :
409
+ missing .append (arg )
410
+ if missing :
411
+ print (
412
+ f"{ PKG_NAME } : missing arguments: --{ ', --' .join (missing )} , (or specify --f config_file instead)"
413
+ )
414
+ sys .exit (1 )
415
+
416
+ if args .verbose >= 1 :
417
+ print (f"{ PKG_NAME } : got jupyter client config={ config } " )
418
+
419
+ asyncio .run (kernel_run (config , args .verbose ))
0 commit comments