Ejemplo n.º 1
0
def test_should_set_docstring_conf_path_relatively_to_top_directory(work_dir):
    """ Test load valid conf file """

    conf_file = join(work_dir, '.mlvtools')
    write_conf(work_dir=work_dir, conf_path=conf_file, docstring_conf='./doc_conf.yml')

    conf = load_conf_or_default(conf_file, working_directory=work_dir)

    assert conf.docstring_conf == join(work_dir, './doc_conf.yml')
def test_should_detect_consistency_for_notebooks(work_dir):
    """
        Test check_all_scripts_consistency exit without error when there is consistency
        between all notebooks and scripts from the provided directory
    """
    notebook_dir = join(CURRENT_DIR, 'data', 'notebooks')
    script_dir = join(CURRENT_DIR, 'data', 'script_dir')
    write_conf(work_dir, conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
               script_dir=script_dir, dvc_cmd_dir=work_dir)
    check_call(['check_all_scripts_consistency', '-n', notebook_dir, '-w', work_dir])
Ejemplo n.º 3
0
def setup_with_conf(work_dir: str,
                    conf_path: str = None,
                    docstring_conf_path: str = None) -> Tuple[str, str]:
    write_conf(work_dir=work_dir,
               conf_path=conf_path,
               ignore_keys=['# Ignore'],
               dvc_cmd_dir='./dvc_cmd',
               docstring_conf=docstring_conf_path)
    script_path = join(work_dir, 'script_path.py')
    docstring = '"""\n:param out:\n:dvc-out out: {{ conf.out_file }}\n"""' if docstring_conf_path else None
    write_min_script(script_path, docstring)
    return conf_path, script_path
def test_should_detect_inconsistency_if_at_least_one_inconsistent_script(work_dir):
    """
        Test check_all_scripts_consistency exit with error if there is at least one inconsistency
    """
    notebook_dir, script_dir = temporary_setup(work_dir)

    # Replace a script content
    with open(join(script_dir, listdir(script_dir)[0]), 'w') as fd:
        fd.write('print("Hello world!")')

    write_conf(work_dir, conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
               script_dir=script_dir, dvc_cmd_dir=work_dir)

    ret_code = call(['check_all_scripts_consistency', '-n', notebook_dir, '-w', work_dir])
    assert ret_code != 0
Ejemplo n.º 5
0
def test_should_generate_python_script_with_conf_auto_detect(work_dir, mocker):
    """
        Convert a Jupyter Notebook to a Python 3 script using conf
    """
    mocked_check_output = mocker.patch('subprocess.check_output',
                                       return_value=work_dir.encode())
    kept_cells, dropped_cells, docstring, notebook_path = generate_test_notebook(
        work_dir=work_dir, notebook_name='test_nb.ipynb')
    # Create conf with knew ignore cell keywords
    conf_data = write_conf(work_dir=work_dir,
                           conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
                           ignore_keys=['# Ignore', 'import'])

    cmd_arguments = ['-n', notebook_path]
    IPynbToPython().run(*cmd_arguments)

    # This path is generated using the conf script_dir and the notebook name
    output_script_path = join(work_dir,
                              conf_data['path']['python_script_root_dir'],
                              'mlvtools_test_nb.py')
    assert exists(output_script_path)

    with open(output_script_path, 'r') as fd:
        file_content = fd.read()

    # With those knew keywords from conf the first code cell must be ignored (due to import)
    # The second no effect cell must remain because "# No effect" is no more a keyword
    assert not is_in(kept_cells.code[0][1], file_content)
    assert is_in(dropped_cells.no_effect[1][1], file_content)

    # Check conf file has been found using git rev-parse command
    assert mocked_check_output.mock_calls == [
        mocker.call(['git', 'rev-parse', '--show-toplevel'], cwd=work_dir)
    ]
Ejemplo n.º 6
0
def test_should_handle_notebook_with_invalid_python_name_with_conf(
        work_dir, mocker):
    """
        Test invalid python filename are converted
    """
    notebook_path = gen_notebook(cells=[('code', 'pass')],
                                 tmp_dir=work_dir,
                                 file_name='01_(test) nb.ipynb')

    # Create conf in working directory
    conf_data = write_conf(work_dir=work_dir,
                           conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
                           ignore_keys=['# Ignore', 'remove='])

    cmd_arguments = ['-n', notebook_path, '-w', work_dir]
    IPynbToPython().run(*cmd_arguments)

    # This path is generated using the conf script_dir and the notebook name
    output_script_path = join(work_dir,
                              conf_data['path']['python_script_root_dir'],
                              'mlvtools_01__test_nb.py')
    assert exists(output_script_path)

    with open(output_script_path, 'r') as fd:
        file_content = fd.read()

    # Ensure generated file syntax is right
    compile(file_content, output_script_path, 'exec')
Ejemplo n.º 7
0
def test_should_handle_notebook_with_invalid_python_name_with_conf(work_dir, mocker):
    """
        Test invalid python filename are converted
    """
    mocked_check_output = mocker.patch('subprocess.check_output', return_value=work_dir.encode())
    notebook_path = gen_notebook(cells=[('code', 'pass')], tmp_dir=work_dir, file_name='01_(test) nb.ipynb')

    # Create conf in a freshly init git repo
    conf_data = write_conf(work_dir=work_dir, conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
                           ignore_keys=['# Ignore', 'remove='])

    cmd_arguments = ['-n', notebook_path]
    IPynbToPython().run(*cmd_arguments)

    # This path is generated using the conf script_dir and the notebook name
    output_script_path = join(work_dir, conf_data['path']['python_script_root_dir'], 'mlvtools_01__test_nb.py')
    assert exists(output_script_path)

    with open(output_script_path, 'r') as fd:
        file_content = fd.read()

    # Ensure generated file syntax is right
    compile(file_content, output_script_path, 'exec')

    assert mocked_check_output.mock_calls == [mocker.call(
        ['git', 'rev-parse', '--show-toplevel'],
        cwd=work_dir)]
Ejemplo n.º 8
0
def test_should_generate_python_script_with_conf_auto_detect(work_dir, mocker):
    """
        Convert a Jupyter Notebook to a Python 3 script using conf
    """
    kept_cells, dropped_cells, docstring, notebook_path = generate_test_notebook(
        work_dir=work_dir, notebook_name='test_nb.ipynb')
    # Create conf with knew ignore cell keywords
    conf_data = write_conf(work_dir=work_dir,
                           conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
                           ignore_keys=['# Ignore', 'import'])

    cmd_arguments = ['-n', notebook_path, '-w', work_dir]
    IPynbToPython().run(*cmd_arguments)

    # This path is generated using the conf script_dir and the notebook name
    output_script_path = join(work_dir,
                              conf_data['path']['python_script_root_dir'],
                              'mlvtools_test_nb.py')
    assert exists(output_script_path)

    with open(output_script_path, 'r') as fd:
        file_content = fd.read()

    # With those knew keywords from conf the first code cell must be ignored (due to import)
    # The second no effect cell must remain because "# No effect" is no more a keyword
    assert not is_in(kept_cells.code[0][1], file_content)
    assert is_in(dropped_cells.no_effect[1][1], file_content)
Ejemplo n.º 9
0
def test_should_check_consistency_and_exit_with_error_if_same_but_diff_from_conf(work_dir, ref_notebook_path,
                                                                                 ref_script_content):
    """
        Test check consistency between a notebook and its script
        with diff only on blank lines and comments.
        Should exit with error.
            Discard a notebook cell changing conf ignore_keys
    """
    conf_path = join(work_dir, 'conf.json')
    write_conf(work_dir, conf_path, ignore_keys=['# A Tag'])

    script_path = join(work_dir, 'script.py')
    with open(script_path, 'w') as fd:
        fd.write(ref_script_content)

    arguments = ['-n', ref_notebook_path, '-s', script_path, '--conf-path', conf_path, '--working-directory', work_dir]
    with pytest.raises(SystemExit) as e:
        IPynbCheckScript().run(*arguments)
    assert e.value.code != 0
def test_should_detect_ignore_notebooks(work_dir):
    """
        Test check_all_scripts_consistency exit with error if there is at least one inconsistency
    """
    notebook_dir, script_dir = temporary_setup(work_dir)

    # Replace the script which correspond to notebook.ipynb
    with open(join(script_dir, 'mlvtools_notebook.py'), 'w') as fd:
        fd.write('print("Hello world!")')

    # Duplicate a notebook with an other name so there is no associated script
    shutil.copy(join(notebook_dir, 'notebook.ipynb'), join(notebook_dir, 'new_nb.ipynb'))

    write_conf(work_dir, conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
               script_dir=script_dir, dvc_cmd_dir=work_dir)

    # Ignore notebook.ipynb and new_nb.ipynb
    check_call(['check_all_scripts_consistency', '-n', notebook_dir, '-w', work_dir,
                '-i', 'notebook.ipynb', '-i', 'new_nb.ipynb'])
Ejemplo n.º 11
0
def test_should_detect_consistency_for_notebook_and_script_with_conf(work_dir):
    """
        Test check_script_consistency exit without error when there is consistency
        between notebook and script with conf.

        Without conf there is inconsistency but with the right ignore cell there is consistency
    """
    notebook_path = join(CURRENT_DIR, 'data', 'notebooks',
                         'notebook_blank_and_comment_diff.ipynb')
    script_path = join(CURRENT_DIR, 'data',
                       'script_no_blank_no_comment_disable_cell.py')

    write_conf(work_dir,
               conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
               ignore_keys=['# A Tag'])

    check_call([
        'check_script_consistency', '-n', notebook_path, '-s', script_path,
        '-w', work_dir
    ])
Ejemplo n.º 12
0
def test_should_check_consistency_for_nb_from_dir_and_exit_with_error_if_dif_from_conf(
        work_dir, notebook_dir, script_dir):
    """
        Test check consistency for all notebooks from a given directory.
        Should exit with error.
            Discard a notebook cell changing conf ignore_keys
    """
    conf_path = join(work_dir, 'conf.json')
    write_conf(work_dir,
               conf_path,
               script_dir=script_dir,
               dvc_cmd_dir=work_dir,
               ignore_keys=['# A Tag'])

    arguments = [
        '-n', notebook_dir, '-c', conf_path, '--working-directory', work_dir
    ]
    with pytest.raises(SystemExit) as e:
        IPynbCheckAllScripts().run(*arguments)
    assert e.value.code != 0
Ejemplo n.º 13
0
def test_exit_with_error_if_a_script_is_missing(work_dir, notebook_dir,
                                                script_dir):
    """
         Test check consistency exits with error if a script is missing.
    """
    conf_path = join(work_dir, 'conf.json')
    write_conf(work_dir,
               conf_path,
               script_dir=script_dir,
               dvc_cmd_dir=work_dir)

    # Remove a valid script
    remove(join(script_dir, 'mlvtools_bye.py'))

    arguments = [
        '-n', notebook_dir, '-c', conf_path, '--working-directory', work_dir
    ]
    with pytest.raises(SystemExit) as e:
        IPynbCheckAllScripts().run(*arguments)
    assert e.value.code != 0
Ejemplo n.º 14
0
def test_exit_without_error_if_a_script_is_inconsistent_but_ignored(
        work_dir, notebook_dir, script_dir):
    """
         Test check consistency exits without error if inconsistent script is ignored
    """
    conf_path = join(work_dir, 'conf.json')
    write_conf(work_dir,
               conf_path,
               script_dir=script_dir,
               dvc_cmd_dir=work_dir)

    # Overwrite one valid script
    write_script(join(script_dir, 'mlvtools_bye.py'),
                 'print("A different thing")')

    arguments = [
        '-n', notebook_dir, '-c', conf_path, '--working-directory', work_dir,
        '-i', 'bye.ipynb'
    ]
    with pytest.raises(SystemExit) as e:
        IPynbCheckAllScripts().run(*arguments)
    assert e.value.code == 0
Ejemplo n.º 15
0
def test_should_check_consistency_for_all_notebooks_from_directory_and_exit_with_error(
        work_dir, notebook_dir, script_dir):
    """
        Test check consistency for all notebooks from a given directory.
        Should exit with error due to one inconsistency.
    """
    conf_path = join(work_dir, 'conf.json')
    write_conf(work_dir,
               conf_path,
               script_dir=script_dir,
               dvc_cmd_dir=work_dir)

    # Overwrite one valid script
    write_script(join(script_dir, 'mlvtools_bye.py'),
                 'print("A different thing")')

    arguments = [
        '-n', notebook_dir, '-c', conf_path, '--working-directory', work_dir
    ]
    with pytest.raises(SystemExit) as e:
        IPynbCheckAllScripts().run(*arguments)
    assert e.value.code != 0
Ejemplo n.º 16
0
def test_should_convert_to_python_script_using_command_line(work_dir):
    """
        Test ipynb_to_python using command line
    """
    dvc_dir = join(work_dir, 'dvc')
    script_dir = join(work_dir, 'scripts')
    write_conf(work_dir,
               conf_path=join(work_dir, DEFAULT_CONF_FILENAME),
               script_dir=script_dir,
               dvc_cmd_dir=dvc_dir)
    notebook_path = join(CURRENT_DIR, 'data', 'notebook.ipynb')
    check_call(['ipynb_to_dvc', '-n', notebook_path, '-w', work_dir])

    assert exists(script_dir)
    script_dir_content = glob.glob(join(script_dir, 'mlvtools*.py'))
    assert len(script_dir_content) == 1
    assert stat.S_IMODE(os_stat(script_dir_content[0]).st_mode) == 0o755

    assert exists(script_dir)
    dvc_dir_content = glob.glob(join(dvc_dir, 'mlvtools*_dvc'))
    assert len(dvc_dir_content) == 1
    assert stat.S_IMODE(os_stat(dvc_dir_content[0]).st_mode) == 0o755
Ejemplo n.º 17
0
def test_should_check_consistency_for_all_notebooks_from_directory_and_exit_without_error(
        work_dir, notebook_dir, script_dir):
    """
        Test check consistency for all notebooks from a given directory.
        Should exit without error.
        Ignore other file from the given directory.
    """
    conf_path = join(work_dir, 'conf.json')
    write_conf(work_dir,
               conf_path,
               script_dir=script_dir,
               dvc_cmd_dir=work_dir)

    # Add noise: a text file in notebook directory
    with open(join(notebook_dir, 'text_file.txt'), 'w') as fd:
        fd.write('some text')

    arguments = [
        '-n', notebook_dir, '-c', conf_path, '--working-directory', work_dir
    ]
    with pytest.raises(SystemExit) as e:
        IPynbCheckAllScripts().run(*arguments)
    assert e.value.code == 0
Ejemplo n.º 18
0
def test_should_load_conf_file(work_dir):
    """ Test load valid conf file """

    conf_file = join(work_dir, '.mlvtools')
    write_conf(work_dir=work_dir, conf_path=conf_file, ignore_keys=['# No effect', "# Ignore"],
               script_dir='./scripts', dvc_cmd_dir='./dvc_cmd',
               dvc_py_cmd_name='VAR_Name', dvc_py_cmd_path='var_PATh3',
               dvc_meta_file_name='mETA_VAR_NaME')

    conf = load_conf_or_default(conf_file, working_directory=work_dir)

    assert conf.path.python_script_root_dir == './scripts'
    assert conf.path.dvc_cmd_root_dir == './dvc_cmd'
    assert '# No effect' in conf.ignore_keys
    assert '# Ignore' in conf.ignore_keys
    assert conf.dvc_var_python_cmd_path == 'var_PATh3'
    assert conf.dvc_var_python_cmd_name == 'VAR_Name'
    assert conf.dvc_var_meta_filename == 'mETA_VAR_NaME'

    script_path = join(conf.path.python_script_root_dir, 'mlvtools_pipeline_part1.py')
    assert get_script_output_path('./data/Pipeline Part1.ipynb', conf) == join(work_dir, script_path)
    dvc_cmd_path = join(conf.path.dvc_cmd_root_dir, 'pipeline_part1_dvc')
    assert get_dvc_cmd_output_path('./data/pipeline_part1.py', conf) == join(work_dir, dvc_cmd_path)
Ejemplo n.º 19
0
def setup_with_conf(work_dir: str, conf_path: str) -> Tuple[str, str]:
    write_conf(work_dir=work_dir,
               conf_path=conf_path,
               script_dir='./test_scripts')
    nb_path = gen_notebook([('markdown', '# test')], work_dir, 'nb_test.ipynb')
    return conf_path, nb_path