Skip to content

Conversation

@Titan-C
Copy link
Member

@Titan-C Titan-C commented Sep 24, 2016

This is a command line utility to expose sphinx gallery notebook generator.
I manually tested it on bash and zsh.

calling

sphx_ex2nb.py *.py

will convert all python files into notebooks

@Titan-C Titan-C changed the title Notebook CLI [MRG] Notebook CLI Oct 8, 2016
@Titan-C
Copy link
Member Author

Titan-C commented Oct 10, 2016

@GaelVaroquaux Any comments on this one?

@lesteve
Copy link
Member

lesteve commented Nov 8, 2016

Just curious, are you using the sphx_ex2nb.py script yourself?

setup.py Outdated
package_data={'sphinx_gallery': ['_static/gallery.css', '_static/no_image.png',
'_static/broken_example.png']},
scripts=['bin/copy_sphinxgallery.sh'],
scripts=['bin/copy_sphinxgallery.sh', 'bin/sphx_ex2nb.py'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something less cryptic like sphx_glr_example_to_notebook? Not 100% convinced so better suggestions welcome! My point is that trying to shorten names as much as possible does not make too much sense since you have tab-completion these days ...

args = parser.parse_args()

for src_file in args.file:
file_name = os.path.basename(src_file)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency I think this should be src_filename and filename. I tend to use filename for file names and file for object files (i.e. as returned from open) to make it easier to differentiate between the two.

self.work_notebook = ipy_notebook_skeleton()
self.add_code_cell("%matplotlib inline")
self.fill_notebook(script_blocks)
self.save_file()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's generally considered best practice to have minimal logic in the constructor. In this case I would rather have an API like:

nb = Notebook(source_filename)
nb.to_notebook(target_filename)

The parsing of the blocks from source_filename could happen in the constructor.

@Titan-C
Copy link
Member Author

Titan-C commented Nov 19, 2016

Comments addressed. Notebook generation is simpler now as well. And I have included test for the command line utility

Copy link
Member

@lesteve lesteve left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments:


def __init__(self, file_name, target_dir):
"""Declare the skeleton of the notebook
work_notebook = ipy_notebook_skeleton()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ipy_notebook -> jupyter_notebook here and everywhere else.

"""Test that written ipython notebook file corresponds to python object"""
blocks = sg.split_code_and_text_blocks('tutorials/plot_parse.py')
example_nb = jupyter_notebook(blocks)
nb_filename = "/tmp/testnb.ipynb"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not going to work on Windows. Use tempfile.NamedTemporaryFile

bin/test_cli.py Outdated
FileNotFoundError = IOError


class CommandLineTest(TestCase):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of using a test class with methods rather than just functions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need this class with methods because of unittest. This methods are specific to test exceptions are raised, and come inside unittest.TestCase.
To use functions I need to explicitly rely on nosetest or pytest own functions to test exceptions.

doc/utils.rst Outdated
Convert Python scripts into Jupyter Notebooks
=============================================

Sphinx Gallery exposes its python source to Jupyter notebook convert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

converter

.travis.yml Outdated
script:
- if [ "$DISTRIB" == "ubuntu" ]; then python setup.py nosetests; fi
- if [ "$DISTRIB" == "conda" ]; then nosetests; fi
- nosetests bin # to test jupyter notebook generator CLI
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not very conventional ... maybe it would be great if the scripts in bin, was something super simple like:

from sphinx_gallery.notebook import main

if __name__ == '__main__':
    main()

This way you can still test the parser in sphinx_gallery/tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this line because I could not get nosetest to scan the bin folder. Pytest did not have issues on that. But indeed I'll move everything to the notebook parsing file.

@Titan-C Titan-C force-pushed the notebookcli branch 2 times, most recently from 64276d9 to 5fb17e3 Compare November 27, 2016 13:35
text2string into notebook to avoid circular dependence
- Converter script takes multiple files & wildcards
- Install notebook converter script with setup.py
Includes the script converter and moves the gallery downloader
- Jupyter notebook generator function name is explicit
CLI inside notebook file, this allows for testing directly on the
python module responsible for the rendering of the notebooks.
@Titan-C
Copy link
Member Author

Titan-C commented Nov 27, 2016

Rebased to master and comments addressed. Cleaned the commit history too

class CommandLineTest(TestCase):
"""Test the Sphinx-Gallery python to Jupyter notebook converter CLI"""

def test_with_empty_args(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why still the class methods rather than functions?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I push a change in your branch because apart from this it is good for merging I think.

@lesteve
Copy link
Member

lesteve commented Nov 27, 2016

Merging this one, thanks!

@Titan-C
Copy link
Member Author

Titan-C commented Nov 27, 2016

Thanks for the changes. I'm not sure if you got the comment about using the class methods for test. My idea behind it is that that is how unittest does in the standard library tests for exceptions. And since we plan to move to pytest. I did not wanted to include more use to nosetest.

@lesteve lesteve merged commit f1e089f into sphinx-gallery:master Nov 27, 2016
@lesteve
Copy link
Member

lesteve commented Nov 27, 2016

Oops sorry, I missed your reply somehow. In order not to have camelCase in our tests I would either the same method as in scikit-learn so that we can have from sphinx_gallery.testing import assert_raises_regex or it seems like pytest has its own way of checking exception message (from http://doc.pytest.org/en/latest/assert.html):

def test_match():
    with pytest.raises(ValueError) as excinfo:
        myfunc()
    excinfo.match(r'.* 123 .*')

@lesteve
Copy link
Member

lesteve commented Nov 28, 2016

Cleaned the commit history too

Don't worry about that too much, to be honest I tend to use the "Squash and merge" button these days and edit the commit message if there were too many commits and/or too many useless commit messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants