Skip to content

Commit fbd0259

Browse files
committed
Fix python auto-planning
1 parent 59b021d commit fbd0259

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

runbook/cli/commands/plan.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,52 @@
55
from pathlib import Path
66

77
import click
8+
import nbformat
89
from runbook.cli.lib import nbconvert_launch_instance
910
from runbook.cli.validators import validate_plan_params, validate_runbook_file_path
1011
from runbook.constants import RUNBOOK_METADATA
1112

1213
import papermill as pm
1314

1415

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+
1554
@click.command()
1655
@click.argument(
1756
"input", type=click.Path(file_okay=True), callback=validate_runbook_file_path
@@ -49,10 +88,13 @@ def plan(ctx, input, embed, identifier="", params={}):
4988
}
5089
}
5190

91+
# TODO: add test cases for auto-planning
92+
# As of 2025 Jan it's manual regression testing
5293
if len(params) == 0:
5394
inferred_params = pm.inspect_notebook(input)
95+
notebook_language = get_notebook_language(input)
96+
value_parser = get_parser_by_language(notebook_language)
5497
# Inferred_type_name is language specific
55-
# we make the simplifying assumption to show user and then treat inputs as potentially json
5698
for key, value in inferred_params.items():
5799
if key != RUNBOOK_METADATA:
58100
default = value["default"].rstrip(";")
@@ -67,7 +109,7 @@ def plan(ctx, input, embed, identifier="", params={}):
67109
raw_value = click.prompt(
68110
f"""Enter value for {key}{type_hint}{help_hint}""",
69111
default=default,
70-
value_proc=json.loads,
112+
value_proc=value_parser,
71113
)
72114
params[key] = raw_value
73115

0 commit comments

Comments
 (0)