Skip to content

Commit

Permalink
add nbexec test and enable nbconv to infer exporter type
Browse files Browse the repository at this point in the history
  • Loading branch information
marskar committed Jun 13, 2019
1 parent 97b6229 commit 526dc06
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 30 deletions.
6 changes: 3 additions & 3 deletions src/cli/nbconv_click.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ def nbconv_click(in_file: str, exporter: str, out: str) -> None:
:param out_file: The name of the output Jupyter notebook file.
:note: The exporter type must be 'asciidoc', 'pdf', 'html', 'latex',
'markdown', 'python', 'rst', 'script', or 'slides'.
pdf requires latex, 'notebook' does nothing,
slides need to served (not self-contained).
All formats except 'HTML' require pandoc.
Exporting to pdf requires latex.
"""
name, contents = nbconv(in_file, exporter) if exporter else nbconv(in_file)
name, contents = nbconv(in_file, exporter)
if out:
Path(out).write_text(contents)
else:
Expand Down
36 changes: 25 additions & 11 deletions src/nbless/nbconv.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
#!/usr/bin/env python
from pathlib import Path
from typing import List, Union
from typing import Tuple

from nbconvert.exporters.base import get_exporter


def nbconv(in_file: Union[str, Path], exporter: str = "python") -> List[str]:
def nbconv(in_file: str, exporter: str = None) -> Tuple[str, str]:
"""Convert a notebook into various formats using ``nbformat`` exporters.
:param in_file: The name of the input notebook file.
:param exporter: The exporter that determines the output file type.
:return: A 2-tuple of the output file's 1) name and 2) contents.
:note: The exporter type must be 'asciidoc', 'pdf', 'html', 'latex',
'markdown', 'python', 'rst', 'script', or 'slides'.
pdf requires latex, 'notebook' does nothing,
slides need to served (not self-contained).
All formats except 'HTML' require pandoc.
Exporting to pdf requires latex.
"""
if isinstance(in_file, Path):
contents, resources = get_exporter(exporter)().from_file(in_file.open())
elif isinstance(in_file, str):
contents, resources = get_exporter(exporter)().from_filename(in_file)
else:
print("The in_file argument must be a string or pathlib Path object.")
out_name = Path(in_file).stem + resources.get("output_extension", ".txt")
in_file_path = Path(in_file)
if not exporter:
ext_exp_dict = {
'.asciidoc': 'asciidoc',
'.adoc': 'asciidoc',
'.asc': 'asciidoc',
'.pdf': 'pdf',
'.html': 'html',
'.tex': 'latex',
'.md': 'markdown',
'.py': 'python',
'.R': 'script',
'.rst': 'rst'
}
if in_file_path.suffix in ext_exp_dict:
exporter = ext_exp_dict[in_file_path.suffix]
else:
return "Unable to infer exporter type!"
contents, resources = get_exporter(exporter)().from_filename(in_file)
out_name = in_file_path.stem + resources.get("output_extension", ".txt")
return [out_name, contents]
2 changes: 1 addition & 1 deletion src/nbless/nbexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from nbformat.notebooknode import NotebookNode


def nbexec(in_file: str, kernel: str = "python3") -> Tuple[str, NotebookNode]:
def nbexec(in_file: str, kernel: str = "python3") -> NotebookNode:
"""Create an executed notebook without modifying the input notebook.
:param in_file: The name of the Jupyter notebook file to be executed.
Expand Down
37 changes: 22 additions & 15 deletions tests/test_nbless.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
from typing import List

import nbformat
# import pytest
import pytest

from nbless import nbless, nbuild#, nbconv
from nbless import nbless, nbuild, nbexec, nbconv


def make_tempfiles(tmp_path: Path) -> List[str]:
Expand Down Expand Up @@ -40,19 +40,26 @@ def test_nbless(tmp_path: Path) -> None:
for tempfile in make_tempfiles(tmp_path):
assert nbless([tempfile]).cells[0].source == Path(tempfile).read_text()

# Can't get Pandoc to work with Travis

# @pytest.mark.parametrize('not_exporters', ['htm', 'ipython', 'markup'])
# def test_raises(not_exporters, tmp_path: Path) -> None:
# """Make sure a ValueError is raised if nbconv() gets a bad exporter."""
# nb = make_temp_notebook(tmp_path)
# with pytest.raises(ValueError):
# nbconv(in_file=nb, exporter=not_exporters)
def test_nbexec(tmp_path: Path) -> None:
"""Run nbexec() to execute a temporary notebook file."""
for cell in nbexec(make_temp_notebook(tmp_path)).cells:
if cell.cell_type == 'code':
assert cell.execution_count
for output in cell.outputs:
assert output

@pytest.mark.parametrize('not_exporters', ['htm', 'ipython', 'markup'])
def test_raises(not_exporters, tmp_path: Path) -> None:
"""Make sure a ValueError is raised if nbconv() gets a bad exporter."""
nb = make_temp_notebook(tmp_path)
with pytest.raises(ValueError):
nbconv(in_file=nb, exporter=not_exporters)

# @pytest.mark.parametrize('exporters', ['html', 'asciidoc', 'rst'])
# def test_nbconv(exporters, tmp_path: Path) -> None:
# """Convert ``tempfiles`` with each exporter in ``exporters``."""
# nb = make_temp_notebook(tmp_path)
# assert nbconv(in_file=nb,
# exporter=exporters)[0].endswith("." + exporters)

@pytest.mark.parametrize('exporters', ['html', 'asciidoc', 'rst'])
def test_nbconv(exporters, tmp_path: Path) -> None:
"""Convert ``tempfiles`` with each exporter in ``exporters``."""
nb = make_temp_notebook(tmp_path)
assert nbconv(in_file=nb,
exporter=exporters)[0].endswith("." + exporters)

0 comments on commit 526dc06

Please sign in to comment.