Skip to content

Commit

Permalink
Improve discoverability
Browse files Browse the repository at this point in the history
  • Loading branch information
zph committed Jan 21, 2025
1 parent 23119e9 commit d68237e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 46 deletions.
16 changes: 14 additions & 2 deletions runbook/cli/commands/list.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import click
from runbook.cli.commands.show import get_notebook_header


def get_notebook_title(notebook_path):
header = get_notebook_header(notebook_path)
if header:
maybe_title = [line for line in header.split("\n") if line.startswith("# ")]
if maybe_title:
return maybe_title[0][2:].strip()
return None


@click.command()
Expand Down Expand Up @@ -26,8 +36,10 @@ def list(ctx):
# Print found runbooks in a nice format
rprint("\n[bold blue]Templates:[/bold blue]")
for runbook in sorted(templates):
rprint(f"📔 {runbook}")
title = get_notebook_title(runbook)
rprint(f"📔 {title} - {runbook}")

rprint("\n[bold blue]Runs:[/bold blue]")
for runbook in sorted(runs):
rprint(f"📔 {runbook}")
title = get_notebook_title(runbook)
rprint(f"📔 {title} - {runbook}")
32 changes: 30 additions & 2 deletions runbook/cli/commands/show.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
import click
import nbformat
from rich.console import Console
from rich.table import Table
from runbook.cli.commands.plan import get_notebook_language
from runbook.cli.validators import validate_runbook_file_path
from runbook.constants import RUNBOOK_METADATA

import papermill as pm


def get_notebook_header(notebook_path):
"""Get the title (H1) and description (H2) from the notebook's markdown cells.
Args:
notebook_path (str): Path to the notebook file
Returns:
str: The header of the first markdown cell, or None if not found
"""
nb = nbformat.read(notebook_path, as_version=4)
header = None

for cell in nb.cells:
if cell.cell_type == "markdown":
header = cell.source
break

return header


@click.command()
@click.argument(
"runbook", type=click.Path(file_okay=True), callback=validate_runbook_file_path
Expand All @@ -22,8 +44,13 @@ def show(ctx, runbook):
console.print(f"\n[bold blue]Runbook:[/] {runbook}")
console.print(f"[bold blue]Language:[/] {notebook_language}\n")

# Get and print title and description if available
header = get_notebook_header(runbook)
if header:
console.print(f"[bold blue]Header:\n[/]{header}\n")

# Create and populate parameters table
table = Table(show_header=True, header_style="bold magenta")
table = Table(show_header=True, header_style="bold blue")
table.add_column("Parameter")
table.add_column("Default Value")
table.add_column("Type")
Expand All @@ -33,6 +60,7 @@ def show(ctx, runbook):
default = value["default"].rstrip(";")
typing = value["inferred_type_name"] or ""
help_text = value["help"] or ""
table.add_row(param, default, typing, help_text)
if param != RUNBOOK_METADATA:
table.add_row(param, default, typing, help_text)

console.print(table)
4 changes: 3 additions & 1 deletion runbooks/binder/_template-deno.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"source": [
"# TITLE\n",
"\n",
"## DESCRIPTION"
"## DESCRIPTION\n",
"\n",
"Description continues in narrative form"
]
},
{
Expand Down
30 changes: 14 additions & 16 deletions tests/__snapshots__/cli_test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,14 @@ snapshot[`create 1`] = `
}
`;

snapshot[`init 1`] = `
[
"runbooks",
]
`;

snapshot[`list 1`] = `
{
exitCode: 0,
stderr: "",
stdout: "
Templates:
📔 runbooks/binder/_template-deno.ipynb
📔 runbooks/binder/_template-python.ipynb
📔 TITLE - runbooks/binder/_template-deno.ipynb
📔 TITLE - runbooks/binder/_template-python.ipynb
Runs:
",
Expand All @@ -118,14 +112,18 @@ snapshot[`show 1`] = `
Runbook: runbooks/binder/_template-deno.ipynb
Language: typescript
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
ParameterDefault ValueTypeHelp
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
server"main.xargs.io"string │ │
arg1number │ │
anArray │ ["a", "b"] │ string[] │ normally a / b
__RUNBOOK_METADATA__ │ {} │ None │ │
└──────────────────────┴─────────────────┴──────────┴────────────────┘
Header:
# TITLE
## DESCRIPTION
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
ParameterDefault ValueTypeHelp
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
server"main.xargs.io"string │ │
arg1number │ │
anArray │ ["a", "b"] │ string[] │ normally a / b
└───────────┴─────────────────┴──────────┴────────────────┘
',
}
`;
Expand Down
25 changes: 0 additions & 25 deletions tests/cli_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,28 +161,3 @@ def test_cli_lifecycle_to_run():
# TODO: fix multiple singletons of ServerApp
# result = invoker(runner, ["run", deno_template], dir)
# assert result.exit_code == 0


def test_cli_lifecycle_to_show():
runner = CliRunner()
with runner.isolated_filesystem() as dir:
result = invoker(runner, ["init"], dir)
assert result.exit_code == 0
result = invoker(runner, ["show", deno_template], dir)
assert result.exit_code == 0
assert (
result.output
== """
Runbook: ./runbooks/binder/_template-deno.ipynb
Language: typescript
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ Parameter ┃ Default Value ┃ Type ┃ Help ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ server │ "main.xargs.io" │ string │ │
│ arg │ 1 │ number │ │
│ anArray │ ["a", "b"] │ string[] │ normally a / b │
│ __RUNBOOK_METADATA__ │ {} │ None │ │
└──────────────────────┴─────────────────┴──────────┴────────────────┘
"""
)

0 comments on commit d68237e

Please sign in to comment.