5
5
from pathlib import Path
6
6
7
7
import click
8
+ import nbformat
8
9
from runbook .cli .lib import nbconvert_launch_instance
9
10
from runbook .cli .validators import validate_plan_params , validate_runbook_file_path
10
11
from runbook .constants import RUNBOOK_METADATA
11
12
12
13
import papermill as pm
13
14
14
15
16
+ def get_notebook_language (notebook_path : str ) -> str :
17
+ """
18
+ Determine the language of the notebook by checking the first code cell's metadata.
19
+ Returns 'python', 'typescript', or 'unknown'
20
+ """
21
+ nb = nbformat .read (notebook_path , as_version = 4 )
22
+ for cell in nb .cells :
23
+ if cell .cell_type == "code" :
24
+ # Check kernel info
25
+ if "kernelspec" in nb .metadata :
26
+ kernel_name = nb .metadata .kernelspec .name .lower ()
27
+ if "python" in kernel_name :
28
+ return "python"
29
+ elif "typescript" in kernel_name or "ts" in kernel_name :
30
+ return "typescript"
31
+ # Check language info
32
+ if "language_info" in nb .metadata :
33
+ language = nb .metadata .language_info .name .lower ()
34
+ if "python" in language :
35
+ return "python"
36
+ elif "typescript" in language or "ts" in language :
37
+ return "typescript"
38
+ return "unknown"
39
+
40
+
41
+ import ast
42
+
43
+
44
+ def get_parser_by_language (language : str ):
45
+ if language == "typescript" :
46
+ return json .loads
47
+ elif language == "python" :
48
+ return ast .literal_eval
49
+ else :
50
+ # Default to json.loads for unknown languages
51
+ return json .loads
52
+
53
+
15
54
@click .command ()
16
55
@click .argument (
17
56
"input" , type = click .Path (file_okay = True ), callback = validate_runbook_file_path
@@ -49,10 +88,13 @@ def plan(ctx, input, embed, identifier="", params={}):
49
88
}
50
89
}
51
90
91
+ # TODO: add test cases for auto-planning
92
+ # As of 2025 Jan it's manual regression testing
52
93
if len (params ) == 0 :
53
94
inferred_params = pm .inspect_notebook (input )
95
+ notebook_language = get_notebook_language (input )
96
+ value_parser = get_parser_by_language (notebook_language )
54
97
# Inferred_type_name is language specific
55
- # we make the simplifying assumption to show user and then treat inputs as potentially json
56
98
for key , value in inferred_params .items ():
57
99
if key != RUNBOOK_METADATA :
58
100
default = value ["default" ].rstrip (";" )
@@ -67,7 +109,7 @@ def plan(ctx, input, embed, identifier="", params={}):
67
109
raw_value = click .prompt (
68
110
f"""Enter value for { key } { type_hint } { help_hint } """ ,
69
111
default = default ,
70
- value_proc = json . loads ,
112
+ value_proc = value_parser ,
71
113
)
72
114
params [key ] = raw_value
73
115
0 commit comments