Skip to content

Commit

Permalink
Merge pull request #6 from ayasyrev/dev
Browse files Browse the repository at this point in the history
0.0.5 remove dependencies
  • Loading branch information
ayasyrev authored Oct 28, 2023
2 parents fb9869d + 253e1ec commit ae57a4e
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 57 deletions.
4 changes: 1 addition & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
nbformat
rich
argparsecfg
nbformat
1 change: 0 additions & 1 deletion requirements_test.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
pytest
flake8
pytest-cov
1 change: 1 addition & 0 deletions requirements_test_extra.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
coverage[toml]
nox
black
flake8
58 changes: 28 additions & 30 deletions src/nbmetaclean/app.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,53 @@
from dataclasses import dataclass
import argparse
from pathlib import Path

import nbformat
from argparsecfg.app import App
from argparsecfg.core import field_argument
from rich import print as rprint

from .clean import clean_nb_file
from .core import get_nb_names


@dataclass
class AppCfg:
path: str = field_argument("path", default=".", nargs="*")
as_version: int = field_argument(
default=nbformat.NO_CONVERT, help="Save as version, default - no convert"
)
silent: bool = field_argument("-s", default=False, action="store_true")
not_pt: bool = field_argument(
default=False,
help="Do not preserve timestamp, default - preserve timestamp",
action="store_true")


app = App(
parser = argparse.ArgumentParser(
prog="nbclean",
description="Clean metadata and execution_count from Jupyter notebooks.",
)
parser.add_argument(
"path",
default=".",
nargs="*",
help="Path for nb or folder with notebooks.",
)
parser.add_argument(
"-s",
"--silent",
action="store_true",
help="Silent mode.",
)
parser.add_argument(
"--not-pt",
action="store_true",
help="Do not preserve timestamp.",
)


@app.main
def clean(
cfg: AppCfg,
) -> None:
def app() -> None:
"""Clean metadata and execution_count from Jupyter notebook."""
cfg = parser.parse_args()
path_list = cfg.path if isinstance(cfg.path, list) else [cfg.path]
nb_files: list[Path] = []
print(cfg)
if not cfg.silent:
print(f"Path: {', '.join(cfg.path)}, preserve timestamp: {not cfg.not_pt}")
for path in path_list:
try:
nb_files.extend(get_nb_names(path))
except FileNotFoundError:
rprint(f"{path} not exists!")
rprint(f"find notebooks: {len(nb_files)} ")
print(f"{path} not exists!")
if not cfg.silent:
print(f"notebooks to check: {len(nb_files)} ")
cleaned = clean_nb_file(
nb_files,
as_version=cfg.as_version,
silent=cfg.silent,
preserve_timestamp=not cfg.not_pt,
)
rprint(f"cleaned nbs: {len(cleaned)}")
if not cfg.silent:
print(f"cleaned nbs: {len(cleaned)}")


if __name__ == "__main__":
Expand Down
14 changes: 5 additions & 9 deletions src/nbmetaclean/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
from pathlib import Path
from typing import Optional, Union

import nbformat

from nbformat.notebooknode import NotebookNode
from rich.progress import track
from rich import print as rprint

from .core import read_nb, write_nb, PathOrStr

Expand Down Expand Up @@ -93,7 +89,7 @@ def clean_nb(
clear_cell_metadata: bool = True,
clear_execution_count: bool = True,
clear_outputs: bool = False,
preserve_nb_metadata_masks: Optional[list[tuple[str, str]],] = None,
preserve_nb_metadata_masks: Optional[list[tuple[str, ...]],] = None,
preserve_cell_metadata_mask: Optional[str] = None,
) -> tuple[NotebookNode, bool]:
"""Clean notebook - metadata, execution_count, outputs.
Expand Down Expand Up @@ -134,7 +130,6 @@ def clean_nb_file(
clear_execution_count: bool = True,
clear_outputs: bool = False,
preserve_timestamp: bool = True,
as_version: nbformat.Sentinel = nbformat.NO_CONVERT,
silent: bool = False,
) -> list[Path]:
"""Clean metadata and execution count from notebook.
Expand All @@ -155,7 +150,8 @@ def clean_nb_file(
if not isinstance(path, list):
path = [path]
cleaned: list[Path] = []
for filename in track(path, transient=True):
to_clean = len(path)
for num, filename in enumerate(path):
nb = read_nb(filename)
nb, result = clean_nb(
nb,
Expand All @@ -168,9 +164,9 @@ def clean_nb_file(
cleaned.append(filename)
if preserve_timestamp:
stat = filename.stat()
write_nb(nb, filename, as_version)
write_nb(nb, filename)
if preserve_timestamp:
os.utime(filename, (stat.st_atime, stat.st_mtime))
if not silent:
rprint(f"done: {filename}")
print(f"done {num + 1} of {to_clean}: {filename}")
return cleaned
3 changes: 1 addition & 2 deletions src/nbmetaclean/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def read_nb(path: PathOrStr) -> NotebookNode:
def write_nb(
nb: NotebookNode,
path: PathOrStr,
as_version: nbformat.Sentinel = nbformat.NO_CONVERT,
) -> Path:
"""Write notebook to file
Expand All @@ -41,7 +40,7 @@ def write_nb(
if filename.suffix != ".ipynb":
filename = filename.with_suffix(".ipynb")
with filename.open("w", encoding="utf-8") as fh:
nbformat.write(nb, fh, version=as_version) # type: ignore
nbformat.write(nb, fh) # type: ignore
return filename


Expand Down
2 changes: 1 addition & 1 deletion src/nbmetaclean/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.0.4" # pragma: no cover
__version__ = "0.0.5_dev" # pragma: no cover
20 changes: 10 additions & 10 deletions tests/test_clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

def test_get_meta_by_mask():
"""test get_meta_by_mask"""
nb = read_nb(Path("tests/test_nbs/test_nb_2.ipynb"))
nb = read_nb(Path("tests/test_nbs/.test_nb_2_meta.ipynb"))
nb_meta = nb.metadata

# string as nb_meta
Expand All @@ -43,7 +43,7 @@ def test_get_meta_by_mask():

def test_new_metadata():
"""test new_metadata"""
nb_meta = read_nb("tests/test_nbs/test_nb_2.ipynb").metadata
nb_meta = read_nb("tests/test_nbs/.test_nb_2_meta.ipynb").metadata
new_meta = new_metadata(nb_meta)
assert isinstance(new_meta, NotebookNode)
assert not new_meta
Expand All @@ -53,7 +53,7 @@ def test_new_metadata():

def test_clean_cell_metadata():
"""test clean_cell_metadata"""
test_nb = read_nb("tests/test_nbs/test_nb_2.ipynb")
test_nb = read_nb("tests/test_nbs/.test_nb_2_meta.ipynb")

# clear outputs
cell = copy.deepcopy(test_nb.cells[1])
Expand Down Expand Up @@ -101,7 +101,7 @@ def test_clean_cell_metadata():

def test_clean_cell_metadata_markdown():
"""test clean_cell_metadata with markdown cell"""
test_nb = read_nb("tests/test_nbs/test_nb_2.ipynb")
test_nb = read_nb("tests/test_nbs/.test_nb_2_meta.ipynb")
cell = copy.deepcopy(test_nb.cells[0])
cell.metadata = {"some key": "some value"}
changed = clean_cell_metadata(cell)
Expand All @@ -112,7 +112,7 @@ def test_clean_cell_metadata_markdown():
def test_clean_nb():
"""test clean nb"""
path = Path("tests/test_nbs")
nb_path = path / "test_nb_2.ipynb"
nb_path = path / ".test_nb_2_meta.ipynb"
nb_clean = path / "test_nb_2_clean.ipynb"
nb = read_nb(nb_path)
assert nb.cells[1].execution_count == 1
Expand Down Expand Up @@ -158,7 +158,7 @@ def test_clean_nb():
def test_clean_nb_file(tmp_path: Path, capsys: CaptureFixture[str]):
"""test clean nb file"""
path = Path("tests/test_nbs")
nb_name = "test_nb_2.ipynb"
nb_name = ".test_nb_2_meta.ipynb"
nb_clean = read_nb(path / "test_nb_2_clean.ipynb")

# prepare temp test notebook
Expand All @@ -177,8 +177,8 @@ def test_clean_nb_file(tmp_path: Path, capsys: CaptureFixture[str]):
cleaned = clean_nb_file([test_nb_path])
captured = capsys.readouterr()
out = captured.out
assert out.startswith("done:")
assert "test_clean_nb_file0/test_nb_2.ipynb" in out
assert out.startswith("done")
assert "test_clean_nb_file0/.test_nb_2_meta.ipynb" in out
assert len(cleaned) == 1
nb = read_nb(cleaned[0])
assert nb == nb_clean
Expand All @@ -198,10 +198,10 @@ def test_clean_nb_file(tmp_path: Path, capsys: CaptureFixture[str]):
assert not captured.out.strip()


def test_clean_nb_file_timestamp(tmp_path: Path, capsys: CaptureFixture[str]):
def test_clean_nb_file_timestamp(tmp_path: Path):
"""test clean_nb_file, timestamp"""
path = Path("tests/test_nbs")
nb_name = "test_nb_2.ipynb"
nb_name = ".test_nb_2_meta.ipynb"
nb_stat = (path / nb_name).stat()

# prepare temp test notebook, set timestamp
Expand Down
File renamed without changes.
4 changes: 3 additions & 1 deletion tests/test_read_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ def test_get_nb_names():
names.sort(key=lambda x: x.name)
assert names[0] == file
names = get_nb_names(path)
assert len(names) == 3
assert len(names) == 2
names.sort(key=lambda x: x.name)
assert names[0] == file
names = get_nb_names(path, filter_hidden=False)
assert len(names) == 3
try:
get_nb_names("wrong_name")
assert False
Expand Down

0 comments on commit ae57a4e

Please sign in to comment.