pax_global_header00006660000000000000000000000064136121405770014520gustar00rootroot0000000000000052 comment=d38f143c6eaabc77aadaa171bde6e49c16411c94 nbformat-5.0.4/000077500000000000000000000000001361214057700133365ustar00rootroot00000000000000nbformat-5.0.4/.bumpversion.cfg000066400000000000000000000013711361214057700164500ustar00rootroot00000000000000[bumpversion] current_version = 5.0.4 parse = (?P\d+)\.(?P\d+)\.(?P\d+)(.(?P.+))? serialize = {major}.{minor}.{patch}.{suffix} {major}.{minor}.{patch} [bumpversion:part:suffix] optional_value = final values = dev final [bumpversion:file:nbformat/_version.py] parse = (?P\d+),\s*(?P\d+),\s*(?P\d+)(,\s*['"](?P\w+)['"])? serialize = {major}, {minor}, {patch}, '{suffix}' {major}, {minor}, {patch} [bumpversion:file:docs/conf.py] parse = (?P\d+).(?P\d+) serialize = {major}.{minor} search = version = '{current_version}' replace = version = '{new_version}' [bumpversion:file:package.json] parse = (?P\d+).(?P\d+).(?P\d+) serialize = {major}.{minor}.{patch} nbformat-5.0.4/.gitignore000066400000000000000000000002251361214057700153250ustar00rootroot00000000000000MANIFEST build dist _build docs/man/*.gz .cache *.py[co] __pycache__ *.egg-info *~ *.bak .ipynb_checkpoints .tox .DS_Store \#*# .#* .coverage .cache nbformat-5.0.4/.mailmap000066400000000000000000000250671361214057700147710ustar00rootroot00000000000000A. J. Holyoake ajholyoake Aaron Culich Aaron Culich Aron Ahmadia ahmadia Benjamin Ragan-Kelley Benjamin Ragan-Kelley Min RK Benjamin Ragan-Kelley MinRK Barry Wark Barry Wark Ben Edwards Ben Edwards Bradley M. Froehle Bradley M. Froehle Bradley M. Froehle Bradley Froehle Brandon Parsons Brandon Parsons Brian E. Granger Brian Granger Brian E. Granger Brian Granger <> Brian E. Granger bgranger <> Brian E. Granger bgranger Christoph Gohlke cgohlke Cyrille Rossant rossant Damián Avila damianavila Damián Avila damianavila Damon Allen damontallen Darren Dale darren.dale <> Darren Dale Darren Dale <> Dav Clark Dav Clark <> Dav Clark Dav Clark David Hirschfeld dhirschfeld David P. Sanders David P. Sanders David Warde-Farley David Warde-Farley <> Doug Blank Doug Blank Eugene Van den Bulke Eugene Van den Bulke Evan Patterson Evan Patterson Evan Patterson Evan Patterson Evan Patterson epatters Evan Patterson epatters Ernie French Ernie French Ernie French ernie french Ernie French ernop Fernando Perez Fernando Perez Fernando Perez Fernando Perez fperez <> Fernando Perez fptest <> Fernando Perez fptest1 <> Fernando Perez Fernando Perez Fernando Perez Fernando Perez <> Fernando Perez Fernando Perez Frank Murphy Frank Murphy Gabriel Becker gmbecker Gael Varoquaux gael.varoquaux <> Gael Varoquaux gvaroquaux Gael Varoquaux Gael Varoquaux <> Ingolf Becker watercrossing Jake Vanderplas Jake Vanderplas Jakob Gager jakobgager Jakob Gager jakobgager Jakob Gager jakobgager Jason Grout Jason Grout Jason Gors jason gors Jason Gors jgors Jens Hedegaard Nielsen Jens Hedegaard Nielsen Jens Hedegaard Nielsen Jens H Nielsen Jens Hedegaard Nielsen Jens H. Nielsen Jez Ng Jez Ng Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic jon Jonathan Frederic U-Jon-PC\Jon Jonathan March Jonathan March Jonathan March jdmarch Jörgen Stenarson Jörgen Stenarson Jörgen Stenarson Jorgen Stenarson Jörgen Stenarson Jorgen Stenarson <> Jörgen Stenarson jstenar Jörgen Stenarson jstenar <> Jörgen Stenarson Jörgen Stenarson Juergen Hasch juhasch Juergen Hasch juhasch Julia Evans Julia Evans Kester Tong KesterTong Kyle Kelley Kyle Kelley Kyle Kelley rgbkrk Laurent Dufréchou Laurent Dufréchou Laurent Dufréchou laurent dufrechou <> Laurent Dufréchou laurent.dufrechou <> Laurent Dufréchou Laurent Dufrechou <> Laurent Dufréchou laurent.dufrechou@gmail.com <> Laurent Dufréchou ldufrechou Lorena Pantano Lorena Luis Pedro Coelho Luis Pedro Coelho Marc Molla marcmolla Martín Gaitán Martín Gaitán Matthias Bussonnier Matthias BUSSONNIER Matthias Bussonnier Bussonnier Matthias Matthias Bussonnier Matthias BUSSONNIER Matthias Bussonnier Matthias Bussonnier Michael Droettboom Michael Droettboom Nicholas Bollweg Nicholas Bollweg (Nick) Nicolas Rougier Nikolay Koldunov Nikolay Koldunov Omar Andrés Zapata Mesa Omar Andres Zapata Mesa Omar Andrés Zapata Mesa Omar Andres Zapata Mesa Pankaj Pandey Pankaj Pandey Pascal Schetelat pascal-schetelat Paul Ivanov Paul Ivanov Pauli Virtanen Pauli Virtanen <> Pauli Virtanen Pauli Virtanen Pierre Gerold Pierre Gerold Pietro Berkes Pietro Berkes Piti Ongmongkolkul piti118 Prabhu Ramachandran Prabhu Ramachandran <> Puneeth Chaganti Puneeth Chaganti Robert Kern rkern <> Robert Kern Robert Kern Robert Kern Robert Kern Robert Kern Robert Kern <> Robert Marchman Robert Marchman Satrajit Ghosh Satrajit Ghosh Satrajit Ghosh Satrajit Ghosh Scott Sanderson Scott Sanderson smithj1 smithj1 smithj1 smithj1 Steven Johnson stevenJohnson Steven Silvester blink1073 S. Weber s8weber Stefan van der Walt Stefan van der Walt Silvia Vinyes Silvia Silvia Vinyes silviav12 Sylvain Corlay Sylvain Corlay sylvain.corlay Ted Drain TD22057 Théophile Studer Théophile Studer Thomas Kluyver Thomas Thomas Spura Thomas Spura Timo Paulssen timo vds vds2212 vds vds Ville M. Vainio Ville M. Vainio ville Ville M. Vainio ville Ville M. Vainio vivainio <> Ville M. Vainio Ville M. Vainio Ville M. Vainio Ville M. Vainio Walter Doerwald walter.doerwald <> Walter Doerwald Walter Doerwald <> W. Trevor King W. Trevor King Yoval P. y-p nbformat-5.0.4/.travis.yml000066400000000000000000000006151361214057700154510ustar00rootroot00000000000000language: python dist: xenial python: - nightly - 3.8 - 3.7 - 3.6 - 3.5 sudo: false install: - pip install --upgrade setuptools pip - pip install --upgrade pytest - pip install . codecov - pip install nbformat[test] - pip freeze script: - py.test -v --cov nbformat nbformat after_success: - codecov matrix: allow_failures: - python: "nightly" nbformat-5.0.4/CONTRIBUTING.md000066400000000000000000000030641361214057700155720ustar00rootroot00000000000000# Contributing We follow the [IPython Contributing Guide](https://github.com/ipython/ipython/blob/master/CONTRIBUTING.md). ## Release guidelines The nbformat version will change in a package release only when there are material changes in the specification itself. This Python package can be released with no spec changes. For example, the package version may be bumped to 5.0 to drop Python 2 support with no changes in the nbformat spec number. When this package is released, if there are material changes in the specification, update the appropriate schema file to reflect the new version (both in its top-level description and in its minimum minor/major version numbers in the spec) and copy the file to an archived schema for that particular version. Update the minor format for tests as well. For example, for nbformat package version 4.5, if we see that there are material changes in the spec, so do the following: * Update `nbformat/v4/nbformat.v4.schema.json` so that its top-level description says spec version 4.4 (which is the next spec version), and its minimum minor version number is 4 in the schema. * Copy `nbformat/v4/nbformat.v4.schema.json` to `nbformat/v4/nbformat.v4.4.schema.json` and commit the file as an archived version of that particular nbformat specification. * Update the `nbformat` and `nbformat_minor` variables in `nbformat/v4/nbbase.py` If there are inconsequential changes to the format spec in a package release (such as fixing a typo in the documentation of a field), just update the archived spec file when the package is released. nbformat-5.0.4/COPYING.md000066400000000000000000000055101361214057700147710ustar00rootroot00000000000000# Licensing terms This project is licensed under the terms of the Modified BSD License (also known as New or Revised or 3-Clause BSD), as follows: - Copyright (c) 2001-2015, IPython Development Team - Copyright (c) 2015-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Jupyter Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## About the Jupyter Development Team The Jupyter Development Team is the set of all contributors to the Jupyter project. This includes all of the Jupyter subprojects. The core team that coordinates development on GitHub can be found here: https://github.com/jupyter/. ## Our Copyright Policy Jupyter uses a shared copyright model. Each contributor maintains copyright over their contributions to Jupyter. But, it is important to note that these contributions are typically only changes to the repositories. Thus, the Jupyter source code, in its entirety is not the copyright of any single person or institution. Instead, it is the collective copyright of the entire Jupyter Development Team. If individual contributors want to maintain a record of what changes/contributions they have specific copyright on, they should indicate their copyright in the commit message of the change, when they commit the change to one of the Jupyter repositories. With this in mind, the following banner should be used in any source code file to indicate the copyright and license terms: # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. nbformat-5.0.4/MANIFEST.in000066400000000000000000000006521361214057700150770ustar00rootroot00000000000000include COPYING.md include CONTRIBUTING.md include README.md # Javascript include package.json include index.js # Documentation graft docs exclude docs/\#* # Examples graft examples # docs subdirs we want to skip prune docs/build prune docs/gh-pages prune docs/dist # Patterns to exclude from any directory global-exclude *~ global-exclude *.pyc global-exclude *.pyo global-exclude .git global-exclude .ipynb_checkpoints nbformat-5.0.4/README.md000066400000000000000000000021471361214057700146210ustar00rootroot00000000000000# The Jupyter Notebook Format [![codecov.io](https://codecov.io/github/jupyter/nbformat/coverage.svg?branch=master)](https://codecov.io/github/jupyter/nbformat?branch=master) [![Code Health](https://landscape.io/github/jupyter/nbformat/master/landscape.svg?style=flat)](https://landscape.io/github/jupyter/nbformat/master) `nbformat` contains the reference implementation of the [Jupyter Notebook format][], and Python APIs for working with notebooks. There is also a JSON schema for notebook format versions >= 3. [Jupyter Notebook format]: https://nbformat.readthedocs.org/en/latest/format_description.html ## Installation From the command line: ``` {.sourceCode .bash} pip install nbformat ``` ## Python Version Support This library supported python 2.7 and python 3.5+ for `4.x.x` releases. With python 2's end-of-life nbformat `5.x.x` is now python 3.5+ only. Support for 3.5 will be dropped when it's officially sunset by the python organization. ## Contributing Read [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to setup a local development environment and make code changes back to nbformat. nbformat-5.0.4/RELEASING.md000066400000000000000000000035201361214057700151710ustar00rootroot00000000000000# Releasing ## Prerequisites - First check that the docs/changelog.rst is up to date for the next release version - If you have a schema version change, you need to bump the schema version manually: First copy `nbformat/v4/nbformat/.v4.schema.json` to `nbformat/v4/nbformat/.v4.schema.json`. Then edit the top of `nbformat/v4/nbbase.py`: ``` # Change the nbformat_minor and nbformat_schema variables when incrementing the # nbformat version # current major version nbformat = 4 # current minor version nbformat_minor = # schema files for (major, minor) version tuples. (None, None) means the current version nbformat_schema = { (None, None): 'nbformat.v4.schema.json', (4, 0): 'nbformat.v4.0.schema.json', ... (4, ): 'nbformat.v4..schema.json' } ``` If you do one of these steps but not the others it will fail many tests. ## Push to GitHub Change from patch to minor or major for appropriate version updates. ```bash # Commit, test, publish, tag release bumpversion minor # CHECK FIRST: If the patch version currently set is not sufficient git commit -am "Prepared " bumpversion suffix # Remove the .dev git commit -am "Generated release " git tag git push && git push --tags ``` ## Push to PyPI ```bash rm -rf dist/* rm -rf build/* python setup.py sdist bdist_wheel # Double check the dist/* files have the right verison (no `.dev`) and install the wheel to ensure it's good pip install dist/* twine upload dist/* ``` ## Push to npm ```bash npm publish ``` Note for JavaScript developers -- `bumpversion` updates the version in `package.json`. ## Prep repo for development - `bumpversion patch # Resets the patch and dev versions` - `git commit -am "Resumed patch dev"; git push` nbformat-5.0.4/appveyor.yml000066400000000000000000000011521361214057700157250ustar00rootroot00000000000000# Do not build feature branch with open Pull Requests skip_branch_with_pr: true # environment variables environment: matrix: - PYTHON: "C:\\Python35-x64" PYTHON_VERSION: "3.5.x" PYTHON_MAJOR: 3 PYTHON_ARCH: "64" # scripts that run after cloning repository install: # Ensure python scripts are from right version: - 'SET "PATH=%PYTHON%\\Scripts;%PATH%"' # Install our package: - pip install codecov - 'pip install --upgrade ".[test]"' build: off # to run your custom scripts instead of automatic tests test_script: - 'py.test -v --cov nbformat nbformat' on_success: - codecov nbformat-5.0.4/docs/000077500000000000000000000000001361214057700142665ustar00rootroot00000000000000nbformat-5.0.4/docs/Makefile000066400000000000000000000163711361214057700157360ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " applehelp to make an Apple Help Book" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/nbformat.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/nbformat.qhc" applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @echo @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." @echo "N.B. You won't be able to view it unless you put it in" \ "~/Library/Documentation/Help or install it in your application" \ "bundle." devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/nbformat" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/nbformat" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." coverage: $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage @echo "Testing of coverage in the sources finished, look at the " \ "results in $(BUILDDIR)/coverage/python.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." nbformat-5.0.4/docs/api.rst000066400000000000000000000055701361214057700156000ustar00rootroot00000000000000Python API for working with notebook files ========================================== .. module:: nbformat Reading and writing ------------------- .. autofunction:: read .. autofunction:: reads The reading functions require you to pass the *as_version* parameter. Your code should specify the notebook format that it knows how to work with: for instance, if your code handles version 4 notebooks:: nb = nbformat.read('path/to/notebook.ipynb', as_version=4) This will automatically upgrade or downgrade notebooks in other versions of the notebook format to the structure your code knows about. .. autofunction:: write .. autofunction:: writes .. data:: NO_CONVERT This special value can be passed to the reading and writing functions, to indicate that the notebook should be loaded/saved in the format it's supplied. .. data:: current_nbformat current_nbformat_minor These integers represent the current notebook format version that the nbformat module knows about. NotebookNode objects -------------------- The functions in this module work with :class:`NotebookNode` objects, which are like dictionaries, but allow attribute access (``nb.cells``). The structure of these objects matches the notebook format described in :doc:`format_description`. .. autoclass:: NotebookNode .. autofunction:: from_dict Other functions --------------- .. autofunction:: convert .. autofunction:: validate .. autoclass:: ValidationError Constructing notebooks programmatically --------------------------------------- .. module:: nbformat.v4 These functions return :class:`~.NotebookNode` objects with the necessary fields. .. autofunction:: new_notebook .. autofunction:: new_code_cell .. autofunction:: new_markdown_cell .. autofunction:: new_raw_cell .. autofunction:: new_output .. autofunction:: output_from_msg Notebook signatures ------------------- .. module:: nbformat.sign This machinery is used by the notebook web application to record which notebooks are *trusted*, and may show dynamic output as soon as they're loaded. See :ref:`notebook:notebook_security` for more information. .. autoclass:: NotebookNotary .. automethod:: sign .. automethod:: unsign .. automethod:: check_signature .. automethod:: mark_cells .. automethod:: check_cells .. _pluggable_signature_store: Signature storage ***************** Signatures are stored using a pluggable :class:`SignatureStore` subclass. To implement your own, override the methods below and configure ``NotebookNotary.store_factory``. .. autoclass:: SignatureStore .. automethod:: store_signature .. automethod:: remove_signature .. automethod:: check_signature .. automethod:: close By default, :class:`NotebookNotary` will use an SQLite based store if SQLite bindings are available, and an in-memory store otherwise. .. autoclass:: SQLiteSignatureStore .. autoclass:: MemorySignatureStore nbformat-5.0.4/docs/changelog.rst000066400000000000000000000072241361214057700167540ustar00rootroot00000000000000.. _changelog: ========================= Changes in nbformat ========================= 5.0.4 ===== - Fixed issue causing python 2 to pick up 5.0.x releases. 5.0.3 ===== - Removed debug print statements from project. 5.0.2 ===== - Added schema validation files for older versions. This was breaking notebook generation. 5.0.1 ===== 5.0 === `5.0 on GitHub https://github.com/jupyter/nbformat/milestone/5`__ - Starting with 5.0, ``nbformat`` is now Python 3 only (>= 3.5) - Add execution timings in code cell metadata for v4 spec. ``"metadata": { "execution": {...}}`` should be populated with kernel-specific timing information. - Documentation for how markup is used in notebooks added - Link to json schema docs from format page added - Documented the editable metadata flag - Update description for collapsed field - Documented nbformat versions 4.0-4.3 with accurate json schema specification files - Clarified info about :ref:`name`'s meaning for cells - Added a default execution_count of None for new_output_cell('execute_result') - Added support for handling nbjson kwargs - Wheels now correctly have a LICENSE file - Travis builds now have a few more execution environments 4.4 === `4.4 on GitHub `__ - Explicitly state that metadata fields can be ignored. - Introduce official jupyter namespace inside metadata (``metadata.jupyter``). - Introduce ``source_hidden`` and ``outputs_hidden`` as official front-end metadata fields to indicate hiding source and outputs areas. **NB**: These fields should not be used to hide elements in exported formats. - Fix ending the redundant storage of signatures in the signature database. - :func:`nbformat.validate` can be set to not raise a ValidationError if additional properties are included. - Fix for errors with connecting and backing up the signature database. - Dict-like objects added to NotebookNode attributes are now transformed to be NotebookNode objects; transformation also works for `.update()`. 4.3 === `4.3 on GitHub `__ - A new pluggable ``SignatureStore`` class allows specifying different ways to record the signatures of trusted notebooks. The default is still an SQLite database. See :ref:`pluggable_signature_store` for more information. - :func:`nbformat.read` and :func:`nbformat.write` accept file paths as bytes as well as unicode. - Fix for calling :func:`nbformat.validate` on an empty dictionary. - Fix for running the tests where the locale makes ASCII the default encoding. - Include nbformat-schema files (v3 and v4) in nbformat-schema npm package. - Include configuration for appveyor's continuous integration service. 4.2 === 4.2.0 ----- `4.2 on GitHub `__ - Update nbformat spec version to 4.2, allowing JSON outputs to have any JSONable type, not just ``object``, and mime-types of the form ``application/anything+json``. - Define basics of ``authors`` in notebook metadata. ``nb.metadata.authors`` shall be a list of objects with the property ``name``, a string of each author's full name. - Update use of traitlets API to require traitlets 4.1. - Support trusting notebooks on stdin with ``cat notebook | jupyter trust`` 4.1 === 4.1.0 ----- `4.1 on GitHub `__ - Update nbformat spec version to 4.1, adding support for attachments on markdown and raw cells. - Catch errors opening trust database, falling back on ``:memory:`` if the database cannot be opened. 4.0 === `4.0 on GitHub `__ The first release of nbformat as its own package. nbformat-5.0.4/docs/conf.py000066400000000000000000000231671361214057700155760ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # nbformat documentation build configuration file, created by # sphinx-quickstart on Thu May 14 17:26:52 2015. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys import os import shlex # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.napoleon', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'nbformat' copyright = '2015, Jupyter Development Team' author = 'Jupyter Development Team' # numpydoc configuration numpydoc_show_class_members = False # Otherwise Sphinx emits thousands of warnings numpydoc_class_members_toctree = False # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '5.0' # The full version, including alpha/beta/rc tags. release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". # html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. #html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' #html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value #html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. #html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. htmlhelp_basename = 'nbformatdoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', # Latex figure (float) alignment #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'nbformat.tex', 'nbformat Documentation', 'Jupyter Development Team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'nbformat', 'nbformat Documentation', [author], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'nbformat', 'nbformat Documentation', author, 'nbformat', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), 'jupyterclient': ('https://jupyter-client.readthedocs.io/en/stable', None), 'nbconvert': ('https://nbconvert.readthedocs.org/en/stable', None), 'notebook': ('https://jupyter-notebook.readthedocs.org/en/stable', None), } nbformat-5.0.4/docs/format_description.rst000066400000000000000000000330001361214057700207070ustar00rootroot00000000000000.. _notebook_file_format: ======================== The Notebook file format ======================== The official Jupyter Notebook format is defined with `this JSON schema `_, which is used by Jupyter tools to validate notebooks. This page contains a human-readable description of the notebook format. .. note:: *All* metadata fields are optional. While the types and values of some metadata fields are defined, no metadata fields are required to be defined. Any metadata field may also be ignored. Top-level structure =================== At the highest level, a Jupyter notebook is a dictionary with a few keys: - metadata (dict) - nbformat (int) - nbformat_minor (int) - cells (list) .. sourcecode:: python { "metadata" : { "kernel_info": { # if kernel_info is defined, its name field is required. "name" : "the name of the kernel" }, "language_info": { # if language_info is defined, its name field is required. "name" : "the programming language of the kernel", "version": "the version of the language", "codemirror_mode": "The name of the codemirror mode to use [optional]" } }, "nbformat": 4, "nbformat_minor": 0, "cells" : [ # list of cell dictionaries, see below ], } Some fields, such as code input and text output, are characteristically multi-line strings. When these fields are written to disk, they **may** be written as a list of strings, which should be joined with ``''`` when reading back into memory. In programmatic APIs for working with notebooks (Python, Javascript), these are always re-joined into the original multi-line string. If you intend to work with notebook files directly, you must allow multi-line string fields to be either a string or list of strings. Cell Types ========== There are a few basic cell types for encapsulating code and text. All cells have the following basic structure: .. sourcecode:: python { "cell_type" : "type", "metadata" : {}, "source" : "single string or [list, of, strings]", } .. note:: On disk, multi-line strings **MAY** be split into lists of strings. When read with the nbformat Python API, these multi-line strings will always be a single string. Markdown cells -------------- Markdown cells are used for body-text, and contain markdown, as defined in `GitHub-flavored markdown`_, and implemented in marked_. .. _GitHub-flavored markdown: https://help.github.com/articles/github-flavored-markdown .. _marked: https://github.com/chjj/marked .. sourcecode:: python { "cell_type" : "markdown", "metadata" : {}, "source" : "[multi-line *markdown*]", } .. versionchanged:: nbformat 4.0 Heading cells have been removed, in favor of simple headings in markdown. Code cells ---------- Code cells are the primary content of Jupyter notebooks. They contain source code in the language of the document's associated kernel, and a list of outputs associated with executing that code. They also have an execution_count, which must be an integer or ``null``. .. sourcecode:: python { "cell_type" : "code", "execution_count": 1, # integer or null "metadata" : { "collapsed" : True, # whether the output of the cell is collapsed "scrolled": False, # any of true, false or "auto" }, "source" : "[some multi-line code]", "outputs": [{ # list of output dicts (described below) "output_type": "stream", ... }], } .. versionchanged:: nbformat 4.0 ``input`` was renamed to ``source``, for consistency among cell types. .. versionchanged:: nbformat 4.0 ``prompt_number`` renamed to ``execution_count`` Code cell outputs ----------------- A code cell can have a variety of outputs (stream data or rich mime-type output). These correspond to :ref:`messages ` produced as a result of executing the cell. All outputs have an ``output_type`` field, which is a string defining what type of output it is. stream output ************* .. sourcecode:: python { "output_type" : "stream", "name" : "stdout", # or stderr "text" : "[multiline stream text]", } .. versionchanged:: nbformat 4.0 The ``stream`` key was changed to ``name`` to match the stream message. .. _display-data: display_data ************ Rich display outputs, as created by ``display_data`` messages, contain data keyed by mime-type. This is often called a mime-bundle, and shows up in various locations in the notebook format and message spec. The metadata of these messages may be keyed by mime-type as well. .. sourcecode:: python { "output_type" : "display_data", "data" : { "text/plain" : "[multiline text data]", "image/png": "[base64-encoded-multiline-png-data]", "application/json": { # JSON data is included as-is "json": "data", }, }, "metadata" : { "image/png": { "width": 640, "height": 480, }, }, } .. versionchanged:: nbformat 4.0 ``application/json`` output is no longer double-serialized into a string. .. versionchanged:: nbformat 4.0 mime-types are used for keys, instead of a combination of short names (``text``) and mime-types, and are stored in a ``data`` key, rather than the top-level. i.e. ``output.data['image/png']`` instead of ``output.png``. execute_result ************** Results of executing a cell (as created by ``displayhook`` in Python) are stored in ``execute_result`` outputs. `execute_result` outputs are identical to ``display_data``, adding only a ``execution_count`` field, which must be an integer. .. sourcecode:: python { "output_type" : "execute_result", "execution_count": 42, "data" : { "text/plain" : "[multiline text data]", "image/png": "[base64-encoded-multiline-png-data]", "application/json": { # JSON data is included as-is "json": "data", }, }, "metadata" : { "image/png": { "width": 640, "height": 480, }, }, } .. versionchanged:: nbformat 4.0 ``pyout`` renamed to ``execute_result`` .. versionchanged:: nbformat 4.0 ``prompt_number`` renamed to ``execution_count`` error ***** Failed execution may show a traceback .. sourcecode:: python { 'output_type': 'error', 'ename' : str, # Exception name, as a string 'evalue' : str, # Exception value, as a string # The traceback will contain a list of frames, # represented each as a string. 'traceback' : list, } .. versionchanged:: nbformat 4.0 ``pyerr`` renamed to ``error`` .. _raw nbconvert cells: Raw NBConvert cells ------------------- .. _nbconvert: https://nbconvert.readthedocs.org A raw cell is defined as content that should be included *unmodified* in `nbconvert`_ output. For example, this cell could include raw LaTeX for nbconvert to pdf via latex, or restructured text for use in Sphinx documentation. The notebook authoring environment does not render raw cells. The only logic in a raw cell is the `format` metadata field. If defined, it specifies which nbconvert output format is the intended target for the raw cell. When outputting to any other format, the raw cell's contents will be excluded. In the default case when this value is undefined, a raw cell's contents will be included in any nbconvert output, regardless of format. .. sourcecode:: python { "cell_type" : "raw", "metadata" : { # the mime-type of the target nbconvert format. # nbconvert to formats other than this will exclude this cell. "format" : "mime/type" }, "source" : "[some nbformat output text]" } Cell attachments ---------------- .. versionadded:: 4.1 Markdown and raw cells can have a number of attachments, typically inline images that can be referenced in the markdown content of a cell. The ``attachments`` dictionary of a cell contains a set of mime-bundles (see :ref:`display_data`) keyed by filename that represents the files attached to the cell. .. note:: The ``attachments`` dictionary is an optional field and can be undefined or empty if the cell does not have any attachments. .. sourcecode:: python { "cell_type" : "markdown", "metadata" : {}, "source" : ["Here is an *inline* image ![inline image](attachment:test.png)"], "attachments" : { "test.png": { "image/png" : "base64-encoded-png-data" } } } Backward-compatible changes =========================== The notebook format is an evolving format. When backward-compatible changes are made, the notebook format minor version is incremented. When backward-incompatible changes are made, the major version is incremented. As of nbformat 4.x, backward-compatible changes include: - new fields in any dictionary (notebook, cell, output, metadata, etc.) - new cell types - new output types New cell or output types will not be rendered in versions that do not recognize them, but they will be preserved. Metadata ======== Metadata is a place that you can put arbitrary JSONable information about your notebook, cell, or output. Because it is a shared namespace, any custom metadata should use a sufficiently unique namespace, such as `metadata.kaylees_md.foo = "bar"`. Metadata fields officially defined for Jupyter notebooks are listed here: Notebook metadata ----------------- The following metadata keys are defined at the notebook level: =========== =============== ============== Key Value Interpretation =========== =============== ============== kernelspec dict A :ref:`kernel specification ` authors list of dicts A list of authors of the document =========== =============== ============== A notebook's authors is a list of dictionaries containing information about each author of the notebook. Currently, only the name is required. Additional fields may be added. .. sourcecode:: python nb.metadata.authors = [ { 'name': 'Fernando Perez', }, { 'name': 'Brian Granger', }, ] Cell metadata ------------- Official Jupyter metadata, as used by Jupyter frontends should be placed in the `metadata.jupyter` namespace, for example `metadata.jupyter.foo = "bar"`. The following metadata keys are defined at the cell level: =========== =============== ============== Key Value Interpretation =========== =============== ============== collapsed bool Whether the cell's output container should be collapsed scrolled bool or 'auto' Whether the cell's output is scrolled, unscrolled, or autoscrolled deletable bool If False, prevent deletion of the cell editable bool If False, prevent editing of the cell (by definition, this also prevents deleting the cell) format 'mime/type' The mime-type of a :ref:`Raw NBConvert Cell ` name str A name for the cell. Should be unique across the notebook. Uniqueness must be verified outside of the json schema. tags list of str A list of string tags on the cell. Commas are not allowed in a tag jupyter dict A namespace holding jupyter specific fields. See docs below for more details execution dict A namespace holding execution specific fields. See docs below for more details =========== =============== ============== The following metadata keys are defined at the cell level within the `jupyter` namespace =============== =============== ============== Key Value Interpretation =============== =============== ============== source_hidden bool Whether the cell's source should be shown outputs_hidden bool Whether the cell's outputs should be shown =============== =============== ============== The following metadata keys are defined at the cell level within the `execution` namespace. These are lower level fields capturing common kernel message timestamps for better visibility in applications where needed. Most users will not look at these directly. ==================== ================ ============== Key Value Interpretation ==================== ================ ============== iopub.execute_input ISO 8601 format Indicates the time at which the kernel broadcast an execute_input message. This represents the time when request for work was received by the kernel. iopub.status.busy ISO 8601 format Indicates the time at which the iopub channel's kernel status message is 'busy'. This represents the time when work was started by the kernel. shell.execute_reply ISO 8601 format Indicates the time at which the shell channel's execute_reply status message was created. This represents the time when work was completed by the kernel. iopub.status.idle ISO 8601 format Indicates the time at which the iopub channel's kernel status message is 'idle'. This represents the time when the kernel is ready to accept new work. ==================== ================ ============== Output metadata --------------- The following metadata keys are defined for code cell outputs: =========== =============== ============== Key Value Interpretation =========== =============== ============== isolated bool Whether the output should be isolated into an IFrame =========== =============== ============== nbformat-5.0.4/docs/index.rst000066400000000000000000000007011361214057700161250ustar00rootroot00000000000000=========================== The Jupyter Notebook Format =========================== Jupyter (né IPython) notebook files are simple JSON documents, containing text, source code, rich media output, and metadata. Each segment of the document is stored in a cell. Contents: .. toctree:: :maxdepth: 2 format_description markup api changelog Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` nbformat-5.0.4/docs/make.bat000066400000000000000000000161201361214057700156730ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled echo. coverage to run coverage check of the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) REM Check if sphinx-build is available and fallback to Python version if any %SPHINXBUILD% 2> nul if errorlevel 9009 goto sphinx_python goto sphinx_ok :sphinx_python set SPHINXBUILD=python -m sphinx.__init__ %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) :sphinx_ok if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\nbformat.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\nbformat.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "coverage" ( %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage if errorlevel 1 exit /b 1 echo. echo.Testing of coverage in the sources finished, look at the ^ results in %BUILDDIR%/coverage/python.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end nbformat-5.0.4/docs/markup.rst000066400000000000000000000041361361214057700163230ustar00rootroot00000000000000.. _markup: ======================== Supported markup formats ======================== The Jupyter Notebook format supports Markdown in text cells. There is not a strict specification for the flavor of markdown that is supported, but this page should help guide the user / developer in understanding what behavior to expect with Jupyter interfaces and markup languages. What flavor of Markdown does the notebook format support? ========================================================= Most Jupyter Notebook interfaces use the `marked.js `_ JavaScript library for rendering markdown. This supports markdown in the following markdown flavors: * `CommonMark `_. * `GitHub Flavored Markdown `_ See the `Marked.js specification page `_ for more information. .. note:: Currently, as the Marked.js specification changes, so to will the behavior of Markdown in many notebook interfaces. MathJax configuration ===================== There are a few extra modifications that Jupyter interfaces tend to use for rendering markdown. Specifically, they automatically render mathematical equations using `MathJax `_. This is currently the MathJax configuration that is used: .. code:: javascript { tex2jax: { inlineMath: [ ['$','$'], ["\\(","\\)"] ], displayMath: [ ['$$','$$'], ["\\[","\\]"] ], processEscapes: true, processEnvironments: true }, MathML: { extensions: ['content-mathml.js'] }, displayAlign: 'center', "HTML-CSS": { availableFonts: [], imageFont: null, preferredFont: null, webFont: "STIX-Web", styles: {'.MathJax_Display': {"margin": 0}}, linebreaks: { automatic: true } }, } See the `MathJax script for the classic Notebook UI `_ for one example. nbformat-5.0.4/docs/requirements.txt000066400000000000000000000001521361214057700175500ustar00rootroot00000000000000ipython_genutils jsonschema traitlets -e git+https://github.com/jupyter/jupyter_core.git#egg=jupyter_core nbformat-5.0.4/index.js000066400000000000000000000001771361214057700150100ustar00rootroot00000000000000exports.v3 = require('./nbformat/v3/nbformat.v3.schema.json'); exports.v4 = require('./nbformat/v4/nbformat.v4.schema.json'); nbformat-5.0.4/nbformat/000077500000000000000000000000001361214057700151465ustar00rootroot00000000000000nbformat-5.0.4/nbformat/__init__.py000066400000000000000000000114341361214057700172620ustar00rootroot00000000000000"""The Jupyter notebook format Use this module to read or write notebook files as particular nbformat versions. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import io from traitlets.log import get_logger from ._version import version_info, __version__ from . import v1 from . import v2 from . import v3 from . import v4 from .sentinel import Sentinel __all__ = ['versions', 'validate', 'ValidationError', 'convert', 'from_dict', 'NotebookNode', 'current_nbformat', 'current_nbformat_minor', 'NBFormatError', 'NO_CONVERT', 'reads', 'read', 'writes', 'write', 'version_info', '__version__', ] versions = { 1: v1, 2: v2, 3: v3, 4: v4, } from .validator import validate, ValidationError from .converter import convert from . import reader from .notebooknode import from_dict, NotebookNode from .v4 import ( nbformat as current_nbformat, nbformat_minor as current_nbformat_minor, ) class NBFormatError(ValueError): pass # no-conversion singleton NO_CONVERT = Sentinel('NO_CONVERT', __name__, """Value to prevent nbformat to convert notebooks to most recent version. """) def reads(s, as_version, **kwargs): """Read a notebook from a string and return the NotebookNode object as the given version. The string can contain a notebook of any version. The notebook will be returned `as_version`, converting, if necessary. Notebook format errors will be logged. Parameters ---------- s : unicode The raw unicode string to read the notebook from. as_version : int The version of the notebook format to return. The notebook will be converted, if necessary. Pass nbformat.NO_CONVERT to prevent conversion. Returns ------- nb : NotebookNode The notebook that was read. """ nb = reader.reads(s, **kwargs) if as_version is not NO_CONVERT: nb = convert(nb, as_version) try: validate(nb) except ValidationError as e: get_logger().error("Notebook JSON is invalid: %s", e) return nb def writes(nb, version=NO_CONVERT, **kwargs): """Write a notebook to a string in a given format in the given nbformat version. Any notebook format errors will be logged. Parameters ---------- nb : NotebookNode The notebook to write. version : int, optional The nbformat version to write. If unspecified, or specified as nbformat.NO_CONVERT, the notebook's own version will be used and no conversion performed. Returns ------- s : unicode The notebook as a JSON string. """ if version is not NO_CONVERT: nb = convert(nb, version) else: version, _ = reader.get_version(nb) try: validate(nb) except ValidationError as e: get_logger().error("Notebook JSON is invalid: %s", e) return versions[version].writes_json(nb, **kwargs) def read(fp, as_version, **kwargs): """Read a notebook from a file as a NotebookNode of the given version. The string can contain a notebook of any version. The notebook will be returned `as_version`, converting, if necessary. Notebook format errors will be logged. Parameters ---------- fp : file or str A file-like object with a read method that returns unicode (use ``io.open()`` in Python 2), or a path to a file. as_version: int The version of the notebook format to return. The notebook will be converted, if necessary. Pass nbformat.NO_CONVERT to prevent conversion. Returns ------- nb : NotebookNode The notebook that was read. """ if isinstance(fp, (str, bytes)): with io.open(fp, encoding='utf-8') as f: return read(f, as_version, **kwargs) return reads(fp.read(), as_version, **kwargs) def write(nb, fp, version=NO_CONVERT, **kwargs): """Write a notebook to a file in a given nbformat version. The file-like object must accept unicode input. Parameters ---------- nb : NotebookNode The notebook to write. fp : file or str Any file-like object with a write method that accepts unicode, or a path to write a file. version : int, optional The nbformat version to write. If nb is not this version, it will be converted. If unspecified, or specified as nbformat.NO_CONVERT, the notebook's own version will be used and no conversion performed. """ if isinstance(fp, (str, bytes)): with io.open(fp, 'w', encoding='utf-8') as f: return write(nb, f, version=version, **kwargs) s = writes(nb, version, **kwargs) if isinstance(s, bytes): s = s.decode('utf8') fp.write(s) if not s.endswith(u'\n'): fp.write(u'\n') nbformat-5.0.4/nbformat/_compat.py000066400000000000000000000005261361214057700171450ustar00rootroot00000000000000"""Code for supporting compatibility across python versions.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. try: from base64 import decodebytes, encodebytes except ImportError: from base64 import encodestring as encodebytes from base64 import decodestring as decodebytes nbformat-5.0.4/nbformat/_version.py000066400000000000000000000001611361214057700173420ustar00rootroot00000000000000# Make sure to update package.json, too! version_info = (5, 0, 4) __version__ = '.'.join(map(str, version_info)) nbformat-5.0.4/nbformat/converter.py000066400000000000000000000040321361214057700175260ustar00rootroot00000000000000"""API for converting notebooks between versions.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from . import versions from .reader import get_version def convert(nb, to_version): """Convert a notebook node object to a specific version. Assumes that all the versions starting from 1 to the latest major X are implemented. In other words, there should never be a case where v1 v2 v3 v5 exist without a v4. Also assumes that all conversions can be made in one step increments between major versions and ignores minor revisions. Parameters ---------- nb : NotebookNode to_version : int Major revision to convert the notebook to. Can either be an upgrade or a downgrade. """ # Get input notebook version. (version, version_minor) = get_version(nb) # Check if destination is target version, if so return contents if version == to_version: return nb # If the version exist, try to convert to it one step at a time. elif to_version in versions: # Get the the version that this recursion will convert to as a step # closer to the final revision. Make sure the newer of the conversion # functions is used to perform the conversion. if to_version > version: step_version = version + 1 convert_function = versions[step_version].upgrade else: step_version = version - 1 convert_function = versions[version].downgrade # Convert and make sure version changed during conversion. converted = convert_function(nb) if converted.get('nbformat', 1) == version: raise ValueError("Failed to convert notebook from v%d to v%d." % (version, step_version)) # Recursively convert until target version is reached. return convert(converted, to_version) else: raise ValueError("Cannot convert notebook to v%d because that " \ "version doesn't exist" % (to_version)) nbformat-5.0.4/nbformat/current.py000066400000000000000000000123511361214057700172040ustar00rootroot00000000000000"""Deprecated API for working with notebooks - use nbformat for read/write/validate public API - use nbformat.vX directly for Python API for composing notebooks """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function import re import warnings warnings.warn("""nbformat.current is deprecated. - use nbformat for read/write/validate public API - use nbformat.vX directly to composing notebooks of a particular version """) from nbformat.v3 import ( NotebookNode, new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet, parse_filename, new_metadata, new_author, new_heading_cell, nbformat, nbformat_minor, nbformat_schema, to_notebook_json, ) from nbformat import v3 as _v_latest from .reader import reads as reader_reads from . import versions from .converter import convert from .validator import validate, ValidationError from traitlets.log import get_logger __all__ = ['NotebookNode', 'new_code_cell', 'new_text_cell', 'new_notebook', 'new_output', 'new_worksheet', 'parse_filename', 'new_metadata', 'new_author', 'new_heading_cell', 'nbformat', 'nbformat_minor', 'nbformat_schema', 'to_notebook_json', 'convert', 'validate', 'NBFormatError', 'parse_py', 'reads_json', 'writes_json', 'reads_py', 'writes_py', 'reads', 'writes', 'read', 'write'] current_nbformat = nbformat current_nbformat_minor = nbformat_minor current_nbformat_module = _v_latest.__name__ class NBFormatError(ValueError): pass def _warn_format(): warnings.warn("""Non-JSON file support in nbformat is deprecated. Use nbconvert to create files of other formats.""") def parse_py(s, **kwargs): """Parse a string into a (nbformat, string) tuple.""" nbf = current_nbformat nbm = current_nbformat_minor pattern = r'# (?P\d+[\.\d+]*)' m = re.search(pattern,s) if m is not None: digits = m.group('nbformat').split('.') nbf = int(digits[0]) if len(digits) > 1: nbm = int(digits[1]) return nbf, nbm, s def reads_json(nbjson, **kwargs): """DEPRECATED, use reads""" warnings.warn("reads_json is deprecated, use reads") return reads(nbjson) def writes_json(nb, **kwargs): """DEPRECATED, use writes""" warnings.warn("writes_json is deprecated, use writes") return writes(nb, **kwargs) def reads_py(s, **kwargs): """DEPRECATED: use nbconvert""" _warn_format() nbf, nbm, s = parse_py(s, **kwargs) if nbf in (2, 3): nb = versions[nbf].to_notebook_py(s, **kwargs) else: raise NBFormatError('Unsupported PY nbformat version: %i' % nbf) return nb def writes_py(nb, **kwargs): """DEPRECATED: use nbconvert""" _warn_format() return versions[3].writes_py(nb, **kwargs) # High level API def reads(s, format='DEPRECATED', version=current_nbformat, **kwargs): """Read a notebook from a string and return the NotebookNode object. This function properly handles notebooks of any version. The notebook returned will always be in the current version's format. Parameters ---------- s : unicode The raw unicode string to read the notebook from. Returns ------- nb : NotebookNode The notebook that was read. """ if format not in {'DEPRECATED', 'json'}: _warn_format() nb = reader_reads(s, **kwargs) nb = convert(nb, version) try: validate(nb) except ValidationError as e: get_logger().error("Notebook JSON is invalid: %s", e) return nb def writes(nb, format='DEPRECATED', version=current_nbformat, **kwargs): """Write a notebook to a string in a given format in the current nbformat version. This function always writes the notebook in the current nbformat version. Parameters ---------- nb : NotebookNode The notebook to write. version : int The nbformat version to write. Used for downgrading notebooks. Returns ------- s : unicode The notebook string. """ if format not in {'DEPRECATED', 'json'}: _warn_format() nb = convert(nb, version) try: validate(nb) except ValidationError as e: get_logger().error("Notebook JSON is invalid: %s", e) return versions[version].writes_json(nb, **kwargs) def read(fp, format='DEPRECATED', **kwargs): """Read a notebook from a file and return the NotebookNode object. This function properly handles notebooks of any version. The notebook returned will always be in the current version's format. Parameters ---------- fp : file Any file-like object with a read method. Returns ------- nb : NotebookNode The notebook that was read. """ return reads(fp.read(), **kwargs) def write(nb, fp, format='DEPRECATED', **kwargs): """Write a notebook to a file in a given format in the current nbformat version. This function always writes the notebook in the current nbformat version. Parameters ---------- nb : NotebookNode The notebook to write. fp : file Any file-like object with a write method. """ s = writes(nb, **kwargs) if isinstance(s, bytes): s = s.decode('utf8') return fp.write(s) nbformat-5.0.4/nbformat/notebooknode.py000066400000000000000000000032551361214057700202130ustar00rootroot00000000000000"""NotebookNode - adding attribute access to dicts""" from ipython_genutils.ipstruct import Struct try: from collections.abc import Mapping except ImportError: from collections import Mapping class NotebookNode(Struct): """A dict-like node with attribute-access""" def __setitem__(self, key, value): if isinstance(value, Mapping) and not isinstance(value, NotebookNode): value = from_dict(value) super(NotebookNode, self).__setitem__(key, value) def update(self, *args, **kwargs): """ A dict-like update method based on CPython's MutableMapping `update` method. """ if len(args) > 1: raise TypeError('update expected at most 1 arguments, got %d' % len(args)) if args: other = args[0] if isinstance(other, Mapping): for key in other: self[key] = other[key] elif hasattr(other, "keys"): for key in other.keys(): self[key] = other[key] else: for key, value in other: self[key] = value for key, value in kwargs.items(): self[key] = value def from_dict(d): """Convert dict to dict-like NotebookNode Recursively converts any dict in the container to a NotebookNode. This does not check that the contents of the dictionary make a valid notebook or part of a notebook. """ if isinstance(d, dict): return NotebookNode({k: from_dict(v) for k, v in d.items()}) elif isinstance(d, (tuple, list)): return [from_dict(i) for i in d] else: return d nbformat-5.0.4/nbformat/reader.py000066400000000000000000000040141361214057700167610ustar00rootroot00000000000000"""API for reading notebooks of different versions""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import json class NotJSONError(ValueError): pass def parse_json(s, **kwargs): """Parse a JSON string into a dict.""" try: nb_dict = json.loads(s, **kwargs) except ValueError: # Limit the error message to 80 characters. Display whatever JSON will fit. raise NotJSONError(("Notebook does not appear to be JSON: %r" % s)[:77] + "...") return nb_dict # High level API def get_version(nb): """Get the version of a notebook. Parameters ---------- nb : dict NotebookNode or dict containing notebook data. Returns ------- Tuple containing major (int) and minor (int) version numbers """ major = nb.get('nbformat', 1) minor = nb.get('nbformat_minor', 0) return (major, minor) def reads(s, **kwargs): """Read a notebook from a json string and return the NotebookNode object. This function properly reads notebooks of any version. No version conversion is performed. Parameters ---------- s : unicode The raw unicode string to read the notebook from. Returns ------- nb : NotebookNode The notebook that was read. """ from . import versions, NBFormatError nb_dict = parse_json(s, **kwargs) (major, minor) = get_version(nb_dict) if major in versions: return versions[major].to_notebook_json(nb_dict, minor=minor) else: raise NBFormatError('Unsupported nbformat version %s' % major) def read(fp, **kwargs): """Read a notebook from a file and return the NotebookNode object. This function properly reads notebooks of any version. No version conversion is performed. Parameters ---------- fp : file Any file-like object with a read method. Returns ------- nb : NotebookNode The notebook that was read. """ return reads(fp.read(), **kwargs) nbformat-5.0.4/nbformat/sentinel.py000066400000000000000000000006451361214057700173460ustar00rootroot00000000000000"""Sentinel class for constants with useful reprs""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. class Sentinel(object): def __init__(self, name, module, docstring=None): self.name = name self.module = module if docstring: self.__doc__ = docstring def __repr__(self): return str(self.module)+'.'+self.name nbformat-5.0.4/nbformat/sign.py000066400000000000000000000477461361214057700165020ustar00rootroot00000000000000"""Utilities for signing notebooks""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from collections import OrderedDict from contextlib import contextmanager from datetime import datetime import hashlib from hmac import HMAC import io import os import sys try: import sqlite3 except ImportError: try: from pysqlite2 import dbapi2 as sqlite3 except ImportError: sqlite3 = None from ipython_genutils.py3compat import cast_bytes, cast_unicode from traitlets import ( Instance, Bytes, Enum, Any, Unicode, Bool, Integer, TraitType, default, observe, ) from traitlets.config import LoggingConfigurable, MultipleInstanceError from jupyter_core.application import JupyterApp, base_flags from . import read, reads, NO_CONVERT, __version__ from ._compat import encodebytes try: # Python 3 algorithms = hashlib.algorithms_guaranteed # shake algorithms in py36 are not compatible with hmac # due to required length argument in digests algorithms = [ a for a in algorithms if not a.startswith('shake_') ] except AttributeError: algorithms = hashlib.algorithms # This has been added to traitlets, but is not released as of traitlets 4.3.1, # so a copy is included here for now. class Callable(TraitType): """A trait which is callable. Notes ----- Classes are callable, as are instances with a __call__() method.""" info_text = 'a callable' def validate(self, obj, value): if callable(value): return value else: self.error(obj, value) class SignatureStore(object): """Base class for a signature store.""" def store_signature(self, digest, algorithm): """Implement in subclass to store a signature. Should not raise if the signature is already stored. """ raise NotImplementedError def check_signature(self, digest, algorithm): """Implement in subclass to check if a signature is known. Return True for a known signature, False for unknown. """ raise NotImplementedError def remove_signature(self, digest, algorithm): """Implement in subclass to delete a signature. Should not raise if the signature is not stored. """ raise NotImplementedError def close(self): """Close any open connections this store may use. If the store maintains any open connections (e.g. to a database), they should be closed. """ pass class MemorySignatureStore(SignatureStore): """Non-persistent storage of signatures in memory. """ cache_size = 65535 def __init__(self): # We really only want an ordered set, but the stdlib has OrderedDict, # and it's easy to use a dict as a set. self.data = OrderedDict() def store_signature(self, digest, algorithm): key = (digest, algorithm) # Pop it so it goes to the end when we reinsert it self.data.pop(key, None) self.data[key] = None self._maybe_cull() def _maybe_cull(self): """If more than cache_size signatures are stored, delete the oldest 25% """ if len(self.data) < self.cache_size: return for _ in range(len(self.data) // 4): self.data.popitem(last=False) def check_signature(self, digest, algorithm): key = (digest, algorithm) if key in self.data: # Move it to the end (.move_to_end() method is new in Py3) del self.data[key] self.data[key] = None return True return False def remove_signature(self, digest, algorithm): self.data.pop((digest, algorithm), None) class SQLiteSignatureStore(SignatureStore, LoggingConfigurable): """Store signatures in an SQLite database. """ # 64k entries ~ 12MB cache_size = Integer(65535, help="""The number of notebook signatures to cache. When the number of signatures exceeds this value, the oldest 25% of signatures will be culled. """ ).tag(config=True) def __init__(self, db_file, **kwargs): super(SQLiteSignatureStore, self).__init__(**kwargs) self.db_file = db_file self.db = self._connect_db(db_file) def close(self): if self.db is not None: self.db.close() def _connect_db(self, db_file): kwargs = dict( detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES) db = None try: db = sqlite3.connect(db_file, **kwargs) self.init_db(db) except (sqlite3.DatabaseError, sqlite3.OperationalError): if db_file != ':memory:': old_db_location = db_file + ".bak" if db is not None: db.close() self.log.warning( ("The signatures database cannot be opened; maybe it is corrupted or encrypted. " "You may need to rerun your notebooks to ensure that they are trusted to run Javascript. " "The old signatures database has been renamed to %s and a new one has been created."), old_db_location) try: os.rename(db_file, old_db_location) db = sqlite3.connect(db_file, **kwargs) self.init_db(db) except (sqlite3.DatabaseError, sqlite3.OperationalError, OSError): if db is not None: db.close() self.log.warning( ("Failed commiting signatures database to disk. " "You may need to move the database file to a non-networked file system, " "using config option `NotebookNotary.db_file`. " "Using in-memory signatures database for the remainder of this session.")) self.db_file = ':memory:' db = sqlite3.connect(':memory:', **kwargs) self.init_db(db) else: raise return db def init_db(self, db): db.execute(""" CREATE TABLE IF NOT EXISTS nbsignatures ( id integer PRIMARY KEY AUTOINCREMENT, algorithm text, signature text, path text, last_seen timestamp )""") db.execute(""" CREATE INDEX IF NOT EXISTS algosig ON nbsignatures(algorithm, signature) """) db.commit() def store_signature(self, digest, algorithm): if self.db is None: return if not self.check_signature(digest, algorithm): self.db.execute(""" INSERT INTO nbsignatures (algorithm, signature, last_seen) VALUES (?, ?, ?) """, (algorithm, digest, datetime.utcnow()) ) else: self.db.execute("""UPDATE nbsignatures SET last_seen = ? WHERE algorithm = ? AND signature = ?; """, (datetime.utcnow(), algorithm, digest) ) self.db.commit() # Check size and cull old entries if necessary n, = self.db.execute("SELECT Count(*) FROM nbsignatures").fetchone() if n > self.cache_size: self.cull_db() def check_signature(self, digest, algorithm): if self.db is None: return False r = self.db.execute("""SELECT id FROM nbsignatures WHERE algorithm = ? AND signature = ?; """, (algorithm, digest)).fetchone() if r is None: return False self.db.execute("""UPDATE nbsignatures SET last_seen = ? WHERE algorithm = ? AND signature = ?; """, (datetime.utcnow(), algorithm, digest), ) self.db.commit() return True def remove_signature(self, digest, algorithm): self.db.execute("""DELETE FROM nbsignatures WHERE algorithm = ? AND signature = ?; """, (algorithm, digest) ) self.db.commit() def cull_db(self): """Cull oldest 25% of the trusted signatures when the size limit is reached""" self.db.execute("""DELETE FROM nbsignatures WHERE id IN ( SELECT id FROM nbsignatures ORDER BY last_seen DESC LIMIT -1 OFFSET ? ); """, (max(int(0.75 * self.cache_size), 1),)) def yield_everything(obj): """Yield every item in a container as bytes Allows any JSONable object to be passed to an HMAC digester without having to serialize the whole thing. """ if isinstance(obj, dict): for key in sorted(obj): value = obj[key] yield cast_bytes(key) for b in yield_everything(value): yield b elif isinstance(obj, (list, tuple)): for element in obj: for b in yield_everything(element): yield b elif isinstance(obj, str): yield obj.encode('utf8') else: yield str(obj).encode('utf8') def yield_code_cells(nb): """Iterator that yields all cells in a notebook nbformat version independent """ if nb.nbformat >= 4: for cell in nb['cells']: if cell['cell_type'] == 'code': yield cell elif nb.nbformat == 3: for ws in nb['worksheets']: for cell in ws['cells']: if cell['cell_type'] == 'code': yield cell @contextmanager def signature_removed(nb): """Context manager for operating on a notebook with its signature removed Used for excluding the previous signature when computing a notebook's signature. """ save_signature = nb['metadata'].pop('signature', None) try: yield finally: if save_signature is not None: nb['metadata']['signature'] = save_signature class NotebookNotary(LoggingConfigurable): """A class for computing and verifying notebook signatures.""" data_dir = Unicode() @default('data_dir') def _data_dir_default(self): app = None try: if JupyterApp.initialized(): app = JupyterApp.instance() except MultipleInstanceError: pass if app is None: # create an app, without the global instance app = JupyterApp() app.initialize(argv=[]) return app.data_dir store_factory = Callable( help="""A callable returning the storage backend for notebook signatures. The default uses an SQLite database.""").tag(config=True) @default('store_factory') def _store_factory_default(self): def factory(): if sqlite3 is None: self.log.warning("Missing SQLite3, all notebooks will be untrusted!") return MemorySignatureStore() return SQLiteSignatureStore(self.db_file) return factory db_file = Unicode( help="""The sqlite file in which to store notebook signatures. By default, this will be in your Jupyter data directory. You can set it to ':memory:' to disable sqlite writing to the filesystem. """).tag(config=True) @default('db_file') def _db_file_default(self): if not self.data_dir: return ':memory:' return os.path.join(self.data_dir, u'nbsignatures.db') algorithm = Enum(algorithms, default_value='sha256', help="""The hashing algorithm used to sign notebooks.""" ).tag(config=True) @observe('algorithm') def _algorithm_changed(self, change): self.digestmod = getattr(hashlib, change.new) digestmod = Any() @default('digestmod') def _digestmod_default(self): return getattr(hashlib, self.algorithm) secret_file = Unicode( help="""The file where the secret key is stored.""" ).tag(config=True) @default('secret_file') def _secret_file_default(self): if not self.data_dir: return '' return os.path.join(self.data_dir, 'notebook_secret') secret = Bytes( help="""The secret key with which notebooks are signed.""" ).tag(config=True) @default('secret') def _secret_default(self): # note : this assumes an Application is running if os.path.exists(self.secret_file): with io.open(self.secret_file, 'rb') as f: return f.read() else: secret = encodebytes(os.urandom(1024)) self._write_secret_file(secret) return secret def __init__(self, **kwargs): super(NotebookNotary, self).__init__(**kwargs) self.store = self.store_factory() def _write_secret_file(self, secret): """write my secret to my secret_file""" self.log.info("Writing notebook-signing key to %s", self.secret_file) with io.open(self.secret_file, 'wb') as f: f.write(secret) try: os.chmod(self.secret_file, 0o600) except OSError: self.log.warning( "Could not set permissions on %s", self.secret_file ) return secret def compute_signature(self, nb): """Compute a notebook's signature by hashing the entire contents of the notebook via HMAC digest. """ hmac = HMAC(self.secret, digestmod=self.digestmod) # don't include the previous hash in the content to hash with signature_removed(nb): # sign the whole thing for b in yield_everything(nb): hmac.update(b) return hmac.hexdigest() def check_signature(self, nb): """Check a notebook's stored signature If a signature is stored in the notebook's metadata, a new signature is computed and compared with the stored value. Returns True if the signature is found and matches, False otherwise. The following conditions must all be met for a notebook to be trusted: - a signature is stored in the form 'scheme:hexdigest' - the stored scheme matches the requested scheme - the requested scheme is available from hashlib - the computed hash from notebook_signature matches the stored hash """ if nb.nbformat < 3: return False signature = self.compute_signature(nb) return self.store.check_signature(signature, self.algorithm) def sign(self, nb): """Sign a notebook, indicating that its output is trusted on this machine Stores hash algorithm and hmac digest in a local database of trusted notebooks. """ if nb.nbformat < 3: return signature = self.compute_signature(nb) self.store.store_signature(signature, self.algorithm) def unsign(self, nb): """Ensure that a notebook is untrusted by removing its signature from the trusted database, if present. """ signature = self.compute_signature(nb) self.store.remove_signature(signature, self.algorithm) def mark_cells(self, nb, trusted): """Mark cells as trusted if the notebook's signature can be verified Sets ``cell.metadata.trusted = True | False`` on all code cells, depending on the *trusted* parameter. This will typically be the return value from ``self.check_signature(nb)``. This function is the inverse of check_cells """ if nb.nbformat < 3: return for cell in yield_code_cells(nb): cell['metadata']['trusted'] = trusted def _check_cell(self, cell, nbformat_version): """Do we trust an individual cell? Return True if: - cell is explicitly trusted - cell has no potentially unsafe rich output If a cell has no output, or only simple print statements, it will always be trusted. """ # explicitly trusted if cell['metadata'].pop("trusted", False): return True # explicitly safe output if nbformat_version >= 4: unsafe_output_types = ['execute_result', 'display_data'] safe_keys = {"output_type", "execution_count", "metadata"} else: # v3 unsafe_output_types = ['pyout', 'display_data'] safe_keys = {"output_type", "prompt_number", "metadata"} for output in cell['outputs']: output_type = output['output_type'] if output_type in unsafe_output_types: # if there are any data keys not in the safe whitelist output_keys = set(output) if output_keys.difference(safe_keys): return False return True def check_cells(self, nb): """Return whether all code cells are trusted. A cell is trusted if the 'trusted' field in its metadata is truthy, or if it has no potentially unsafe outputs. If there are no code cells, return True. This function is the inverse of mark_cells. """ if nb.nbformat < 3: return False trusted = True for cell in yield_code_cells(nb): # only distrust a cell if it actually has some output to distrust if not self._check_cell(cell, nb.nbformat): trusted = False return trusted trust_flags = { 'reset' : ( {'TrustNotebookApp' : { 'reset' : True}}, """Delete the trusted notebook cache. All previously signed notebooks will become untrusted. """ ), } trust_flags.update(base_flags) class TrustNotebookApp(JupyterApp): version = __version__ description="""Sign one or more Jupyter notebooks with your key, to trust their dynamic (HTML, Javascript) output. Otherwise, you will have to re-execute the notebook to see output. """ # This command line tool should use the same config file as the notebook @default('config_file_name') def _config_file_name_default(self): return 'jupyter_notebook_config' examples = """ jupyter trust mynotebook.ipynb and_this_one.ipynb """ flags = trust_flags reset = Bool(False, help="""If True, delete the trusted signature cache. After reset, all previously signed notebooks will become untrusted. """ ).tag(config=True) notary = Instance(NotebookNotary) @default('notary') def _notary_default(self): return NotebookNotary(parent=self, data_dir=self.data_dir) def sign_notebook_file(self, notebook_path): """Sign a notebook from the filesystem""" if not os.path.exists(notebook_path): self.log.error("Notebook missing: %s" % notebook_path) self.exit(1) with io.open(notebook_path, encoding='utf8') as f: nb = read(f, NO_CONVERT) self.sign_notebook(nb, notebook_path) def sign_notebook(self, nb, notebook_path=''): """Sign a notebook that's been loaded""" if self.notary.check_signature(nb): print("Notebook already signed: %s" % notebook_path) else: print("Signing notebook: %s" % notebook_path) self.notary.sign(nb) def generate_new_key(self): """Generate a new notebook signature key""" print("Generating new notebook key: %s" % self.notary.secret_file) self.notary._write_secret_file(os.urandom(1024)) def start(self): if self.reset: if os.path.exists(self.notary.db_file): print("Removing trusted signature cache: %s" % self.notary.db_file) os.remove(self.notary.db_file) self.generate_new_key() return if not self.extra_args: self.log.debug("Reading notebook from stdin") nb_s = cast_unicode(sys.stdin.read()) nb = reads(nb_s, NO_CONVERT) self.sign_notebook(nb, '') else: for notebook_path in self.extra_args: self.sign_notebook_file(notebook_path) main = TrustNotebookApp.launch_instance if __name__ == '__main__': main() nbformat-5.0.4/nbformat/tests/000077500000000000000000000000001361214057700163105ustar00rootroot00000000000000nbformat-5.0.4/nbformat/tests/__init__.py000066400000000000000000000000001361214057700204070ustar00rootroot00000000000000nbformat-5.0.4/nbformat/tests/base.py000066400000000000000000000007221361214057700175750ustar00rootroot00000000000000""" Contains base test class for nbformat """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import os import unittest import io class TestsBase(unittest.TestCase): """Base tests class.""" def fopen(self, f, mode=u'r',encoding='utf-8'): return io.open(os.path.join(self._get_files_path(), f), mode, encoding=encoding) def _get_files_path(self): return os.path.dirname(__file__) nbformat-5.0.4/nbformat/tests/invalid.ipynb000066400000000000000000000416501361214057700210070ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {} }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Printed Using Python" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "bad stream", "text": [ "hello\n" ] } ], "source": [ "print(\"hello\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pyout" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "HTML\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import HTML\n", "HTML(\"\"\"\n", "\n", "HTML\n", "\"\"\")" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "console.log(\"hi\");" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%javascript\n", "console.log(\"hi\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Image" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "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\n" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "Image(\"http://ipython.org/_static/IPy_header.png\")" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }nbformat-5.0.4/nbformat/tests/test2.ipynb000066400000000000000000001325231361214057700204220ustar00rootroot00000000000000{ "metadata": { "name": "01_notebook_introduction" }, "nbformat": 2, "worksheets": [ { "cells": [ { "cell_type": "markdown", "source": [ "# An introduction to the Jupyter notebook", "", "The IPython web notebook is a frontend that allows for new modes", "of interaction with IPython: this web-based interface allows you to execute Python and IPython", "commands in each input cell just like you would at the IPython terminal or Qt console, but you can", "also save an entire session as a document in a file with the `.ipynb` extension.", "", "The document you are reading now is precisely an example of one such notebook, and we will show you", "here how to best use this new interface.", "", "The first thing to understand is that a notebook consists of a sequence of 'cells' that can contain ", "either text (such as this one) or code meant for execution (such as the next one):", "", "* Text cells can be written using [Markdown syntax](http://daringfireball.net/projects/markdown/syntax) ", "(in a future release we will also provide support for reStructuredText and Sphinx integration, and we ", "welcome help from interested contributors to make that happen).", "", "* Code cells take IPython input (i.e. Python code, `%magics`, `!system calls`, etc) like IPython at", "the terminal or at the Qt Console. The only difference is that in order to execute a cell, you *must*", "use `Shift-Enter`, as pressing `Enter` will add a new line of text to the cell. When you type ", "`Shift-Enter`, the cell content is executed, output displayed and a new cell is created below. Try", "it now by putting your cursor on the next cell and typing `Shift-Enter`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "\"This is the new Jupyter notebook\"" ], "language": "python", "outputs": [ { "output_type": "pyout", "prompt_number": 1, "text": [ "'This is the new Jupyter notebook'" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "source": [ "You can re-execute the same cell over and over as many times as you want. Simply put your", "cursor in the cell again, edit at will, and type `Shift-Enter` to execute. ", "", "**Tip:** A cell can also be executed", "*in-place*, where IPython executes its content but leaves the cursor in the same cell. This is done by", "typing `Ctrl-Enter` instead, and is useful if you want to quickly run a command to check something ", "before tping the real content you want to leave in the cell. For example, in the next cell, try issuing", "several system commands in-place with `Ctrl-Enter`, such as `pwd` and then `ls`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ls" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "00_notebook_tour.ipynb formatting.ipynb sympy_quantum_computing.ipynb", "01_notebook_introduction.ipynb python-logo.svg trapezoid_rule.ipynb", "display_protocol.ipynb sympy.ipynb" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "source": [ "In a cell, you can type anything from a single python expression to an arbitrarily long amount of code ", "(although for reasons of readability, you should probably limit this to a few dozen lines):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def f(x):", " \"\"\"My function", " x : parameter\"\"\"", " ", " return x+1", "", "print \"f(3) = \", f(3)" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "f(3) = 4" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "source": [ "## User interface", "", "When you start a new notebook server with `ipython notebook`, your", "browser should open into the *Dashboard*, a page listing all notebooks", "available in the current directory as well as letting you create new", "notebooks. In this page, you can also drag and drop existing `.py` files", "over the file list to import them as notebooks (see the manual for ", "[further details on how these files are ", "interpreted](http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html)).", "", "Once you open an existing notebook (like this one) or create a new one,", "you are in the main notebook interface, which consists of a main editing", "area (where these cells are contained) as well as a collapsible left panel, ", "a permanent header area at the top, and a pager that rises from the", "bottom when needed and can be collapsed again." ] }, { "cell_type": "markdown", "source": [ "### Main editing area", "", "Here, you can move with the arrow keys or using the ", "scroll bars. The cursor enters code cells immediately, but only selects", "text (markdown) cells without entering in them; to enter a text cell,", "use `Enter`, and `Shift-Enter` to exit it again (just like to execute a ", "code cell)." ] }, { "cell_type": "markdown", "source": [ "### Left panel", "", "This panel contains a number of panes that can be", "collapsed vertically by clicking on their title bar, and the whole panel", "can also be collapsed by clicking on the vertical divider (note that you", "can not *drag* the divider, for now you can only click on it).", "", "The *Notebook* section contains actions that pertain to the whole notebook,", "such as downloading the current notebook either in its original format", "or as a `.py` script, and printing it. When you click the `Print` button,", "a new HTML page opens with a static copy of the notebook; you can then", "use your web browser's mechanisms to save or print this file.", "", "The *Cell* section lets you manipulate individual cells, and the names should ", "be fairly self-explanatory.", "", "The *Kernel* section lets you signal the kernel executing your code. ", "`Interrupt` does the equivalent of hitting `Ctrl-C` at a terminal, and", "`Restart` fully kills the kernel process and starts a fresh one. Obviously", "this means that all your previous variables are destroyed, but it also", "makes it easy to get a fresh kernel in which to re-execute a notebook, perhaps", "after changing an extension module for which Python's `reload` mechanism", "does not work. If you check the 'Kill kernel upon exit' box, when you ", "close the page IPython will automatically shut down the running kernel;", "otherwise the kernels won't close until you stop the whole ", "", "The *Help* section contains links to the documentation of some projects", "closely related to IPython as well as the minimal keybindings you need to", "know. But you should use `Ctrl-m h` (or click the `QuickHelp` button at", "the top) and learn some of the other keybindings, as it will make your ", "workflow much more fluid and efficient.", "", "The *Configuration* section at the bottom lets you change some values", "related to the display of tooltips and the behavior of the tab completer." ] }, { "cell_type": "markdown", "source": [ "### Header bar", "", "The header area at the top allows you to rename an existing ", "notebook and open up a short help tooltip. This area also indicates", "with a red **Busy** mark on the right whenever the kernel is busy executing", "code." ] }, { "cell_type": "markdown", "source": [ "### The pager at the bottom", "", "Whenever IPython needs to display additional ", "information, such as when you type `somefunction?` in a cell, the notebook", "opens a pane at the bottom where this information is shown. You can keep", "this pager pane open for reference (it doesn't block input in the main area)", "or dismiss it by clicking on its divider bar." ] }, { "cell_type": "markdown", "source": [ "### Tab completion and tooltips", "", "The notebook uses the same underlying machinery for tab completion that ", "IPython uses at the terminal, but displays the information differently.", "Whey you complete with the `Tab` key, IPython shows a drop list with all", "available completions. If you type more characters while this list is open,", "IPython automatically eliminates from the list options that don't match the", "new characters; once there is only one option left you can hit `Tab` once", "more (or `Enter`) to complete. You can also select the completion you", "want with the arrow keys or the mouse, and then hit `Enter`.", "", "In addition, if you hit `Tab` inside of open parentheses, IPython will ", "search for the docstring of the last object left of the parens and will", "display it on a tooltip. For example, type `list(` and you will", "see the docstring for the builtin `list` constructor:" ] }, { "cell_type": "code", "collapsed": true, "input": [ "# Position your cursor after the ( and hit the Tab key:", "list(" ], "language": "python", "outputs": [] }, { "cell_type": "markdown", "source": [ "## The frontend/kernel model", "", "The Jupyter notebook works on a client/server model where an *IPython kernel*", "starts in a separate process and acts as a server to executes the code you type,", "while the web browser provides acts as a client, providing a front end environment", "for you to type. But one kernel is capable of simultaneously talking to more than", "one client, and they do not all need to be of the same kind. All IPython frontends", "are capable of communicating with a kernel, and any number of them can be active", "at the same time. In addition to allowing you to have, for example, more than one", "browser session active, this lets you connect clients with different user interface features.", "", "For example, you may want to connect a Qt console to your kernel and use it as a help", "browser, calling `??` on objects in the Qt console (whose pager is more flexible than the", "one in the notebook). You can start a new Qt console connected to your current kernel by ", "using the `%qtconsole` magic, this will automatically detect the necessary connection", "information.", "", "If you want to open one manually, or want to open a text console from a terminal, you can ", "get your kernel's connection information with the `%connect_info` magic:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%connect_info" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{", " \"stdin_port\": 53970, ", " \"ip\": \"127.0.0.1\", ", " \"hb_port\": 53971, ", " \"key\": \"30daac61-6b73-4bae-a7d9-9dca538794d5\", ", " \"shell_port\": 53968, ", " \"iopub_port\": 53969", "}", "", "Paste the above JSON into a file, and connect with:", " $> ipython --existing ", "or, if you are local, you can connect with just:", " $> ipython --existing kernel-dd85d1cc-c335-44f4-bed8-f1a2173a819a.json ", "or even just:", " $> ipython --existing ", "if this is the most recent IPython session you have started." ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "source": [ "## The kernel's `raw_input` and `%debug`", "", "The one feature the notebook currently doesn't support as a client is the ability to send data to the kernel's", "standard input socket. That is, if the kernel requires information to be typed interactively by calling the", "builtin `raw_input` function, the notebook will be blocked. This happens for example if you run a script", "that queries interactively for parameters, and very importantly, is how the interactive IPython debugger that ", "activates when you type `%debug` works.", "", "So, in order to be able to use `%debug` or anything else that requires `raw_input`, you can either use a Qt ", "console or a terminal console:", "", "- From the notebook, typing `%qtconsole` finds all the necessary connection data for you.", "- From the terminal, first type `%connect_info` while still in the notebook, and then copy and paste the ", "resulting information, using `qtconsole` or `console` depending on which type of client you want." ] }, { "cell_type": "markdown", "source": [ "## Display of complex objects", "", "As the 'tour' notebook shows, the Jupyter notebook has fairly sophisticated display capabilities. In addition", "to the examples there, you can study the `display_protocol` notebook in this same examples folder, to ", "learn how to customize arbitrary objects (in your own code or external libraries) to display in the notebook", "in any way you want, including graphical forms or mathematical expressions." ] }, { "cell_type": "markdown", "source": [ "## Plotting support", "", "As we've explained already, the notebook is just another frontend talking to the same IPython kernel that", "you're already familiar with, so the same options for plotting support apply.", "", "If you start the notebook with `--pylab`, you will get matplotlib's floating, interactive windows and you", "can call the `display` function to paste figures into the notebook document. If you start it with ", "`--pylab inline`, all plots will appear inline automatically. In this regard, the notebook works identically", "to the Qt console.", "", "Note that if you start the notebook server with pylab support, *all* kernels are automatically started in", "pylab mode and with the same choice of backend (i.e. floating windows or inline figures). But you can also", "start the notebook server simply by typing `ipython notebook`, and then selectively turn on pylab support ", "only for the notebooks you want by using the `%pylab` magic (see its docstring for details)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%pylab inline", "plot(rand(100))" ], "language": "python", "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "", "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].", "For more information, type 'help(pylab)'." ] }, { "output_type": "pyout", "prompt_number": 5, "text": [ "[]" ] }, { "output_type": "display_data", "png": "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\n" } ], "prompt_number": 5 }, { "cell_type": "markdown", "source": [ "## Security", "", "By default the notebook only listens on localhost, so it does not expose your computer to attacks coming from", "the internet. By default the notebook does not require any authentication, but you can configure it to", "ask for a password before allowing access to the files. ", "", "Furthermore, you can require the notebook to encrypt all communications by using SSL and making all connections", "using the https protocol instead of plain http. This is a good idea if you decide to run your notebook on", "addresses that are visible from the internet. For further details on how to configure this, see the", "[security section](http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html#security) of the ", "manual.", "", "Finally, note that you can also run a notebook with the `--read-only` flag, which lets you provide access", "to your notebook documents to others without letting them execute code (which can be useful to broadcast", "a computation to colleagues or students, for example). The read-only flag behaves differently depending", "on whether the server has a password or not:", "", "- Passwordless server: users directly see all notebooks in read-only mode.", "- Password-protected server: users can see all notebooks in read-only mode, but a login button is available", "and once a user authenticates, he or she obtains write/execute privileges.", "", "The first case above makes it easy to broadcast on the fly an existing notebook by simply starting a *second* ", "notebook server in the same directory as the first, but in read-only mode. This can be done without having", "to configure a password first (which requires calling a hashing function and editing a configuration file)." ] }, { "cell_type": "code", "collapsed": true, "input": [], "language": "python", "outputs": [] } ] } ] }nbformat-5.0.4/nbformat/tests/test3.ipynb000066400000000000000000000370021361214057700204170ustar00rootroot00000000000000{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "nbconvert latex test" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Printed Using Python" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(\"hello\")" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "hello\n" ] } ], "prompt_number": 1 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Pyout" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.display import HTML\n", "HTML(\"\"\"\n", "\n", "HTML\n", "\"\"\")" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "\n", "\n", "HTML\n" ], "metadata": {}, "output_type": "pyout", "prompt_number": 3, "text": [ "" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "console.log(\"hi\");" ], "language": "python", "metadata": {}, "outputs": [ { "javascript": [ "console.log(\"hi\");" ], "metadata": {}, "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 7 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Image" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.display import Image\n", "Image(\"http://ipython.org/_static/IPy_header.png\")" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "png": "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\n", "prompt_number": 6, "text": [ "" ] } ], "prompt_number": 6 } ], "metadata": {} } ] }nbformat-5.0.4/nbformat/tests/test4.ipynb000066400000000000000000000417131361214057700204240ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# nbconvert latex test" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Printed Using Python" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello\n" ] } ], "source": [ "print(\"hello\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pyout" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "HTML\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import HTML\n", "HTML(\"\"\"\n", "\n", "HTML\n", "\"\"\")" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "console.log(\"hi\");" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%javascript\n", "console.log(\"hi\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Image" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "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\n" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "Image(\"http://ipython.org/_static/IPy_header.png\")" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }nbformat-5.0.4/nbformat/tests/test4custom.ipynb000066400000000000000000000015631361214057700216560ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/vnd.raw.v1+json": { "apples": [ "🍎", "🍏" ], "bananas": 2, "oranges": "apples" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import IPython\n", "\n", "bundle = {}\n", "bundle['application/vnd.raw.v1+json'] = {\n", " 'apples': ['🍎', '🍏'],\n", " 'bananas': 2,\n", " 'oranges': 'apples'\n", "}\n", "\n", "IPython.display.display(bundle, raw=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { }, "nbformat": 4, "nbformat_minor": 2 } nbformat-5.0.4/nbformat/tests/test4docinfo.ipynb000066400000000000000000000420231361214057700217610ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# nbconvert latex test" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Printed Using Python" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello\n" ] } ], "source": [ "print(\"hello\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pyout" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "HTML\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import HTML\n", "HTML(\"\"\"\n", "\n", "HTML\n", "\"\"\")" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "console.log(\"hi\");" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%javascript\n", "console.log(\"hi\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Image" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "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\n" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "Image(\"http://ipython.org/_static/IPy_header.png\")" ] } ], "metadata": { "title": "Test Notebook", "authors": [{"name": "Jean Tester"}] }, "nbformat": 4, "nbformat_minor": 0 } nbformat-5.0.4/nbformat/tests/test4jupyter_metadata.ipynb000066400000000000000000000006551361214057700237070ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false, "source_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello\n" ] } ], "source": [ "print(\"hello\")" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 } nbformat-5.0.4/nbformat/tests/test4jupyter_metadata_timings.ipynb000066400000000000000000000022551361214057700254370ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2019-08-26T17:50:29.604738Z", "iopub.status.busy": "2019-08-26T17:50:29.603423Z", "iopub.status.idle": "2019-08-26T17:50:29.628032Z", "shell.execute_reply": "2019-08-26T17:50:29.623438Z", "shell.execute_reply.started": "2019-08-26T17:50:29.604616Z" } }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1+1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" }, "record_timing": true }, "nbformat": 4, "nbformat_minor": 4 } nbformat-5.0.4/nbformat/tests/test4plus.ipynb000066400000000000000000000431241361214057700213260ustar00rootroot00000000000000{ "extra": "future", "cells": [ { "cell_type": "markdown", "extra": 5, "metadata": {}, "source": [ "# nbconvert latex test" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Printed Using Python" ] }, { "cell_type": "code", "execution_count": 1, "future": "yes", "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "extra": "future", "output_type": "stream", "text": [ "hello\n" ] } ], "source": [ "print(\"hello\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pyout" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "HTML\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import HTML\n", "HTML(\"\"\"\n", "\n", "HTML\n", "\"\"\")" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "console.log(\"hi\");" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%javascript\n", "console.log(\"hi\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Image" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "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\n" ], "extra": "yes", "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "extra": "yes", "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "Image(\"http://ipython.org/_static/IPy_header.png\")" ] }, { "cell_type": "future cell", "metadata": {}, "key": "value" }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello\n" ] }, { "output_type": "future output", "some key": [ "some data" ] }, { "name": "stdout", "output_type": "stream", "text": [ "hello again\n" ] } ], "source": [ "future_output()" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 99 }nbformat-5.0.4/nbformat/tests/test_api.py000066400000000000000000000030151361214057700204710ustar00rootroot00000000000000"""Test the APIs at the top-level of nbformat""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import json import os from .base import TestsBase from ipython_genutils.tempdir import TemporaryDirectory from ..reader import get_version from nbformat import read, current_nbformat, writes, write class TestAPI(TestsBase): def test_read(self): """Can older notebooks be opened and automatically converted to the current nbformat?""" # Open a version 2 notebook. with self.fopen(u'test2.ipynb', 'r') as f: nb = read(f, as_version=current_nbformat) # Check that the notebook was upgraded to the latest version automatically. (major, minor) = get_version(nb) self.assertEqual(major, current_nbformat) def test_write_downgrade_2(self): """dowgrade a v3 notebook to v2""" # Open a version 3 notebook. with self.fopen(u'test3.ipynb', 'r') as f: nb = read(f, as_version=3) jsons = writes(nb, version=2) nb2 = json.loads(jsons) (major, minor) = get_version(nb2) self.assertEqual(major, 2) def test_read_write_path(self): """read() and write() take filesystem paths""" path = os.path.join(self._get_files_path(), u'test4.ipynb') nb = read(path, as_version=4) with TemporaryDirectory() as td: dest = os.path.join(td, 'echidna.ipynb') write(nb, dest) assert os.path.isfile(dest) nbformat-5.0.4/nbformat/tests/test_convert.py000066400000000000000000000042551361214057700214070ustar00rootroot00000000000000"""Tests for nbformat.convert""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from .base import TestsBase from ..converter import convert from ..reader import read, get_version from ..validator import isvalid, validate from .. import current_nbformat class TestConvert(TestsBase): def test_downgrade_3_2(self): """Do notebook downgrades work?""" # Open a version 3 notebook and attempt to downgrade it to version 2. with self.fopen(u'test3.ipynb', u'r') as f: nb = read(f) nb = convert(nb, 2) # Check if downgrade was successful. (major, minor) = get_version(nb) self.assertEqual(major, 2) def test_upgrade_2_3(self): """Do notebook upgrades work?""" # Open a version 2 notebook and attempt to upgrade it to version 3. with self.fopen(u'test2.ipynb', u'r') as f: nb = read(f) nb = convert(nb, 3) # Check if upgrade was successful. (major, minor) = get_version(nb) self.assertEqual(major, 3) def test_upgrade_downgrade_4_3_4(self): """Test that a v4 notebook downgraded to v3 and then upgraded to v4 passes validation tests""" with self.fopen(u'test4.ipynb', u'r') as f: nb = read(f) validate(nb) nb = convert(nb, 3) validate(nb) nb = convert(nb, 4) self.assertEqual(isvalid(nb), True) def test_open_current(self): """Can an old notebook be opened and converted to the current version while remembering the original version of the notebook?""" # Open a version 2 notebook and attempt to upgrade it to the current version # while remembering it's version information. with self.fopen(u'test2.ipynb', u'r') as f: nb = read(f) (original_major, original_minor) = get_version(nb) nb = convert(nb, current_nbformat) # Check if upgrade was successful. (major, minor) = get_version(nb) self.assertEqual(major, current_nbformat) # Check if the original major revision was remembered. self.assertEqual(original_major, 2) nbformat-5.0.4/nbformat/tests/test_reader.py000066400000000000000000000025461361214057700211720ustar00rootroot00000000000000""" Contains tests class for reader.py """ #----------------------------------------------------------------------------- # Copyright (C) 2013 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from .base import TestsBase from ..reader import read, get_version #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- class TestReader(TestsBase): def test_read(self): """Can older notebooks be opened without modification?""" # Open a version 3 notebook. Make sure it is still version 3. with self.fopen(u'test3.ipynb', u'r') as f: nb = read(f) (major, minor) = get_version(nb) self.assertEqual(major, 3) # Open a version 2 notebook. Make sure it is still version 2. with self.fopen(u'test2.ipynb', u'r') as f: nb = read(f) (major, minor) = get_version(nb) self.assertEqual(major, 2) nbformat-5.0.4/nbformat/tests/test_sign.py000066400000000000000000000220621361214057700206630ustar00rootroot00000000000000"""Test Notebook signing""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import codecs import copy import os import shutil from subprocess import Popen, PIPE import sys import time import tempfile import testpath import unittest from .base import TestsBase from traitlets.config import Config from nbformat import read, sign, write class TestNotary(TestsBase): def setUp(self): self.data_dir = tempfile.mkdtemp() self.notary = sign.NotebookNotary( db_file=':memory:', secret=b'secret', data_dir=self.data_dir, ) with self.fopen(u'test3.ipynb', u'r') as f: self.nb = read(f, as_version=4) with self.fopen(u'test3.ipynb', u'r') as f: self.nb3 = read(f, as_version=3) def tearDown(self): self.notary.store.close() shutil.rmtree(self.data_dir) def test_invalid_db_file(self): invalid_sql_file = os.path.join(self.data_dir, 'invalid_db_file.db') with open(invalid_sql_file, 'w') as tempfile: tempfile.write(u'[invalid data]') invalid_notary = sign.NotebookNotary( db_file=invalid_sql_file, secret=b'secret', ) invalid_notary.sign(self.nb) invalid_notary.store.close() testpath.assert_isfile(os.path.join(self.data_dir, invalid_sql_file)) testpath.assert_isfile(os.path.join(self.data_dir, invalid_sql_file + '.bak')) def test_algorithms(self): last_sig = '' for algo in sign.algorithms: self.notary.algorithm = algo sig = self.notary.compute_signature(self.nb) self.assertNotEqual(last_sig, sig) last_sig = sig def test_sign_same(self): """Multiple signatures of the same notebook are the same""" sig1 = self.notary.compute_signature(self.nb) sig2 = self.notary.compute_signature(self.nb) self.assertEqual(sig1, sig2) def test_change_secret(self): """Changing the secret changes the signature""" sig1 = self.notary.compute_signature(self.nb) self.notary.secret = b'different' sig2 = self.notary.compute_signature(self.nb) self.assertNotEqual(sig1, sig2) def test_sign(self): self.assertFalse(self.notary.check_signature(self.nb)) self.notary.sign(self.nb) self.assertTrue(self.notary.check_signature(self.nb)) def test_unsign(self): self.notary.sign(self.nb) self.assertTrue(self.notary.check_signature(self.nb)) self.notary.unsign(self.nb) self.assertFalse(self.notary.check_signature(self.nb)) self.notary.unsign(self.nb) self.assertFalse(self.notary.check_signature(self.nb)) def test_cull_db(self): # this test has various sleeps of 2ms # to ensure low resolution timestamps compare as expected dt = 2e-3 nbs = [ copy.deepcopy(self.nb) for i in range(10) ] for row in self.notary.store.db.execute("SELECT * FROM nbsignatures"): print(row) self.notary.store.cache_size = 8 for i, nb in enumerate(nbs[:8]): nb.metadata.dirty = i self.notary.sign(nb) for i, nb in enumerate(nbs[:8]): time.sleep(dt) self.assertTrue(self.notary.check_signature(nb), 'nb %i is trusted' % i) # signing the 9th triggers culling of first 3 # (75% of 8 = 6, 9 - 6 = 3 culled) self.notary.sign(nbs[8]) self.assertFalse(self.notary.check_signature(nbs[0])) self.assertFalse(self.notary.check_signature(nbs[1])) self.assertFalse(self.notary.check_signature(nbs[2])) self.assertTrue(self.notary.check_signature(nbs[3])) # checking nb3 should keep it from being culled: self.notary.sign(nbs[0]) self.notary.sign(nbs[1]) self.notary.sign(nbs[2]) self.assertTrue(self.notary.check_signature(nbs[3])) self.assertFalse(self.notary.check_signature(nbs[4])) def test_check_signature(self): nb = self.nb md = nb.metadata notary = self.notary check_signature = notary.check_signature # no signature: md.pop('signature', None) self.assertFalse(check_signature(nb)) # hash only, no algo md.signature = notary.compute_signature(nb) self.assertFalse(check_signature(nb)) # proper signature, algo mismatch notary.algorithm = 'sha224' notary.sign(nb) notary.algorithm = 'sha256' self.assertFalse(check_signature(nb)) # check correctly signed notebook notary.sign(nb) self.assertTrue(check_signature(nb)) def test_mark_cells_untrusted(self): cells = self.nb.cells self.notary.mark_cells(self.nb, False) for cell in cells: self.assertNotIn('trusted', cell) if cell.cell_type == 'code': self.assertIn('trusted', cell.metadata) self.assertFalse(cell.metadata.trusted) else: self.assertNotIn('trusted', cell.metadata) def test_mark_cells_trusted(self): cells = self.nb.cells self.notary.mark_cells(self.nb, True) for cell in cells: self.assertNotIn('trusted', cell) if cell.cell_type == 'code': self.assertIn('trusted', cell.metadata) self.assertTrue(cell.metadata.trusted) else: self.assertNotIn('trusted', cell.metadata) def test_check_cells(self): nb = self.nb self.notary.mark_cells(nb, True) self.assertTrue(self.notary.check_cells(nb)) for cell in nb.cells: self.assertNotIn('trusted', cell) self.notary.mark_cells(nb, False) self.assertFalse(self.notary.check_cells(nb)) for cell in nb.cells: self.assertNotIn('trusted', cell) def test_trust_no_output(self): nb = self.nb self.notary.mark_cells(nb, False) for cell in nb.cells: if cell.cell_type == 'code': cell.outputs = [] self.assertTrue(self.notary.check_cells(nb)) def test_mark_cells_untrusted_v3(self): nb = self.nb3 cells = nb.worksheets[0].cells self.notary.mark_cells(nb, False) for cell in cells: self.assertNotIn('trusted', cell) if cell.cell_type == 'code': self.assertIn('trusted', cell.metadata) self.assertFalse(cell.metadata.trusted) else: self.assertNotIn('trusted', cell.metadata) def test_mark_cells_trusted_v3(self): nb = self.nb3 cells = nb.worksheets[0].cells self.notary.mark_cells(nb, True) for cell in cells: self.assertNotIn('trusted', cell) if cell.cell_type == 'code': self.assertIn('trusted', cell.metadata) self.assertTrue(cell.metadata.trusted) else: self.assertNotIn('trusted', cell.metadata) def test_check_cells_v3(self): nb = self.nb3 cells = nb.worksheets[0].cells self.notary.mark_cells(nb, True) self.assertTrue(self.notary.check_cells(nb)) for cell in cells: self.assertNotIn('trusted', cell) self.notary.mark_cells(nb, False) self.assertFalse(self.notary.check_cells(nb)) for cell in cells: self.assertNotIn('trusted', cell) def test_sign_stdin(self): def sign_stdin(nb): env = os.environ.copy() env["JUPYTER_DATA_DIR"] = self.data_dir p = Popen([sys.executable, '-m', 'nbformat.sign', '--log-level=0'], stdin=PIPE, stdout=PIPE, env=env, ) write(nb, codecs.getwriter("utf8")(p.stdin)) p.stdin.close() p.wait() self.assertEqual(p.returncode, 0) out = p.stdout.read().decode('utf8', 'replace') p.stdout.close() return out out = sign_stdin(self.nb3) self.assertIn('Signing notebook: ', out) out = sign_stdin(self.nb3) self.assertIn('already signed: ', out) def test_config_store(): store = sign.MemorySignatureStore() c = Config() c.NotebookNotary.store_factory = lambda: store notary = sign.NotebookNotary(config=c) assert notary.store is store class SignatureStoreTests(unittest.TestCase): def setUp(self): self.store = sign.MemorySignatureStore() def test_basics(self): digest = '0123457689abcef' algo = 'fake_sha' assert not self.store.check_signature(digest, algo) self.store.store_signature(digest, algo) assert self.store.check_signature(digest, algo) self.store.remove_signature(digest, algo) assert not self.store.check_signature(digest, algo) class SQLiteSignatureStoreTests(SignatureStoreTests): def setUp(self): self.store = sign.SQLiteSignatureStore(':memory:') nbformat-5.0.4/nbformat/tests/test_validator.py000066400000000000000000000107321361214057700217110ustar00rootroot00000000000000"""Test nbformat.validator""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import os from .base import TestsBase from jsonschema import ValidationError from nbformat import read from ..validator import isvalid, validate, iter_validate class TestValidator(TestsBase): def test_nb2(self): """Test that a v2 notebook converted to current passes validation""" with self.fopen(u'test2.ipynb', u'r') as f: nb = read(f, as_version=4) validate(nb) self.assertEqual(isvalid(nb), True) def test_nb3(self): """Test that a v3 notebook passes validation""" with self.fopen(u'test3.ipynb', u'r') as f: nb = read(f, as_version=4) validate(nb) self.assertEqual(isvalid(nb), True) def test_nb4(self): """Test that a v4 notebook passes validation""" with self.fopen(u'test4.ipynb', u'r') as f: nb = read(f, as_version=4) validate(nb) self.assertEqual(isvalid(nb), True) def test_nb4_document_info(self): """Test that a notebook with document_info passes validation""" with self.fopen(u'test4docinfo.ipynb', u'r') as f: nb = read(f, as_version=4) validate(nb) self.assertEqual(isvalid(nb), True) def test_nb4custom(self): """Test that a notebook with a custom JSON mimetype passes validation""" with self.fopen(u'test4custom.ipynb', u'r') as f: nb = read(f, as_version=4) validate(nb) self.assertEqual(isvalid(nb), True) def test_nb4jupyter_metadata(self): """Test that a notebook with a jupyter metadata passes validation""" with self.fopen(u'test4jupyter_metadata.ipynb', u'r') as f: nb = read(f, as_version=4) validate(nb) self.assertEqual(isvalid(nb), True) def test_nb4jupyter_metadata_timings(self): """Tests that a notebook with "timing" in metadata passes validation""" with self.fopen(u'test4jupyter_metadata_timings.ipynb', u'r') as f: nb = read(f, as_version=4) validate(nb) self.assertTrue(isvalid(nb)) def test_invalid(self): """Test than an invalid notebook does not pass validation""" # this notebook has a few different errors: # - one cell is missing its source # - invalid cell type # - invalid output_type with self.fopen(u'invalid.ipynb', u'r') as f: nb = read(f, as_version=4) with self.assertRaises(ValidationError): validate(nb) self.assertEqual(isvalid(nb), False) def test_validate_empty(self): """Test that an empty notebook (invalid) fails validation""" with self.assertRaises(ValidationError) as e: validate({}) def test_future(self): """Test that a notebook from the future with extra keys passes validation""" with self.fopen(u'test4plus.ipynb', u'r') as f: nb = read(f, as_version=4) with self.assertRaises(ValidationError): validate(nb, version=4, version_minor=3) self.assertEqual(isvalid(nb, version=4, version_minor=3), False) self.assertEqual(isvalid(nb), True) def test_validation_error(self): with self.fopen(u'invalid.ipynb', u'r') as f: nb = read(f, as_version=4) with self.assertRaises(ValidationError) as e: validate(nb) s = str(e.exception) self.assertRegexpMatches(s, "validating.*required.* in markdown_cell") self.assertRegexpMatches(s, "source.* is a required property") self.assertRegexpMatches(s, r"On instance\[u?['\"].*cells['\"]\]\[0\]") self.assertLess(len(s.splitlines()), 10) def test_iter_validation_error(self): with self.fopen(u'invalid.ipynb', u'r') as f: nb = read(f, as_version=4) errors = list(iter_validate(nb)) assert len(errors) == 3 assert {e.ref for e in errors} == {'markdown_cell', 'heading_cell', 'bad stream'} def test_iter_validation_empty(self): """Test that an empty notebook (invalid) fails validation via iter_validate""" errors = list(iter_validate({})) assert len(errors) == 1 assert type(errors[0]) == ValidationError def test_validation_no_version(self): """Test that an invalid notebook with no version fails validation""" with self.assertRaises(ValidationError) as e: validate({'invalid': 'notebook'}) nbformat-5.0.4/nbformat/v1/000077500000000000000000000000001361214057700154745ustar00rootroot00000000000000nbformat-5.0.4/nbformat/v1/__init__.py000066400000000000000000000015441361214057700176110ustar00rootroot00000000000000"""The main module for the v1 notebook format.""" #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from .nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_notebook ) from .nbjson import reads as reads_json, writes as writes_json from .nbjson import reads as read_json, writes as write_json from .nbjson import to_notebook as to_notebook_json from .convert import upgrade nbformat-5.0.4/nbformat/v1/convert.py000066400000000000000000000012221361214057700175230ustar00rootroot00000000000000"""Convert notebook to the v1 format.""" #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- def upgrade(nb, orig_version=None): raise ValueError('Cannot convert to v1 notebook format') nbformat-5.0.4/nbformat/v1/nbbase.py000066400000000000000000000035131361214057700173020ustar00rootroot00000000000000"""The basic dict based notebook format. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import pprint import uuid from ipython_genutils.ipstruct import Struct #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- class NotebookNode(Struct): pass def from_dict(d): if isinstance(d, dict): newd = NotebookNode() for k,v in d.items(): newd[k] = from_dict(v) return newd elif isinstance(d, (tuple, list)): return [from_dict(i) for i in d] else: return d def new_code_cell(code=None, prompt_number=None): """Create a new code cell with input and output""" cell = NotebookNode() cell.cell_type = u'code' if code is not None: cell.code = str(code) if prompt_number is not None: cell.prompt_number = int(prompt_number) return cell def new_text_cell(text=None): """Create a new text cell.""" cell = NotebookNode() if text is not None: cell.text = str(text) cell.cell_type = u'text' return cell def new_notebook(cells=None): """Create a notebook by name, id and a list of worksheets.""" nb = NotebookNode() if cells is not None: nb.cells = cells else: nb.cells = [] return nb nbformat-5.0.4/nbformat/v1/nbjson.py000066400000000000000000000026771361214057700173530ustar00rootroot00000000000000"""Read and write notebooks in JSON format. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from .rwbase import NotebookReader, NotebookWriter from .nbbase import from_dict import json #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- class JSONReader(NotebookReader): def reads(self, s, **kwargs): nb = json.loads(s, **kwargs) return self.to_notebook(nb, **kwargs) def to_notebook(self, d, **kwargs): """Convert from a raw JSON dict to a nested NotebookNode structure.""" return from_dict(d) class JSONWriter(NotebookWriter): def writes(self, nb, **kwargs): kwargs['indent'] = 4 return json.dumps(nb, **kwargs) _reader = JSONReader() _writer = JSONWriter() reads = _reader.reads read = _reader.read to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes nbformat-5.0.4/nbformat/v1/rwbase.py000066400000000000000000000026301361214057700173320ustar00rootroot00000000000000"""Base classes and function for readers and writers. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- class NotebookReader(object): def reads(self, s, **kwargs): """Read a notebook from a string.""" raise NotImplementedError("loads must be implemented in a subclass") def read(self, fp, **kwargs): """Read a notebook from a file like object""" return self.reads(fp.read(), **kwargs) class NotebookWriter(object): def writes(self, nb, **kwargs): """Write a notebook to a string.""" raise NotImplementedError("loads must be implemented in a subclass") def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" return fp.write(self.writes(nb,**kwargs)) nbformat-5.0.4/nbformat/v1/tests/000077500000000000000000000000001361214057700166365ustar00rootroot00000000000000nbformat-5.0.4/nbformat/v1/tests/__init__.py000066400000000000000000000000001361214057700207350ustar00rootroot00000000000000nbformat-5.0.4/nbformat/v1/tests/nbexamples.py000066400000000000000000000006631361214057700213530ustar00rootroot00000000000000from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_notebook ) nb0 = new_notebook() nb0.cells.append(new_text_cell( text='Some NumPy Examples' )) nb0.cells.append(new_code_cell( code='import numpy', prompt_number=1 )) nb0.cells.append(new_code_cell( code='a = numpy.random.rand(100)', prompt_number=2 )) nb0.cells.append(new_code_cell( code='print a', prompt_number=3 )) nbformat-5.0.4/nbformat/v1/tests/test_json.py000066400000000000000000000003331361214057700212170ustar00rootroot00000000000000from unittest import TestCase from ..nbjson import reads, writes from .nbexamples import nb0 class TestJSON(TestCase): def test_roundtrip(self): s = writes(nb0) self.assertEqual(reads(s),nb0) nbformat-5.0.4/nbformat/v1/tests/test_nbbase.py000066400000000000000000000021241361214057700215000ustar00rootroot00000000000000from unittest import TestCase from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_notebook ) class TestCell(TestCase): def test_empty_code_cell(self): cc = new_code_cell() self.assertEqual(cc.cell_type,'code') self.assertEqual('code' not in cc, True) self.assertEqual('prompt_number' not in cc, True) def test_code_cell(self): cc = new_code_cell(code='a=10', prompt_number=0) self.assertEqual(cc.code, u'a=10') self.assertEqual(cc.prompt_number, 0) def test_empty_text_cell(self): tc = new_text_cell() self.assertEqual(tc.cell_type, 'text') self.assertEqual('text' not in tc, True) def test_text_cell(self): tc = new_text_cell('hi') self.assertEqual(tc.text, u'hi') class TestNotebook(TestCase): def test_empty_notebook(self): nb = new_notebook() self.assertEqual(nb.cells, []) def test_notebooke(self): cells = [new_code_cell(),new_text_cell()] nb = new_notebook(cells=cells) self.assertEqual(nb.cells,cells) nbformat-5.0.4/nbformat/v2/000077500000000000000000000000001361214057700154755ustar00rootroot00000000000000nbformat-5.0.4/nbformat/v2/__init__.py000066400000000000000000000051051361214057700176070ustar00rootroot00000000000000"""The main API for the v2 notebook format. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import os from .nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet, new_metadata, new_author ) from .nbjson import reads as reads_json, writes as writes_json from .nbjson import reads as read_json, writes as write_json from .nbjson import to_notebook as to_notebook_json # Implementation removed, vulnerable to DoS attacks from .nbxml import reads as reads_xml from .nbxml import reads as read_xml from .nbxml import to_notebook as to_notebook_xml from .nbpy import reads as reads_py, writes as writes_py from .nbpy import reads as read_py, writes as write_py from .nbpy import to_notebook as to_notebook_py from .convert import downgrade, upgrade #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- nbformat = 2 nbformat_minor = 0 def parse_filename(fname): """Parse a notebook filename. This function takes a notebook filename and returns the notebook format (json/py) and the notebook name. This logic can be summarized as follows: * notebook.ipynb -> (notebook.ipynb, notebook, json) * notebook.json -> (notebook.json, notebook, json) * notebook.py -> (notebook.py, notebook, py) * notebook -> (notebook.ipynb, notebook, json) Parameters ---------- fname : unicode The notebook filename. The filename can use a specific filename extention (.ipynb, .json, .py) or none, in which case .ipynb will be assumed. Returns ------- (fname, name, format) : (unicode, unicode, unicode) The filename, notebook name and format. """ basename, ext = os.path.splitext(fname) if ext == u'.ipynb': format = u'json' elif ext == u'.json': format = u'json' elif ext == u'.py': format = u'py' else: basename = fname fname = fname + u'.ipynb' format = u'json' return fname, basename, format nbformat-5.0.4/nbformat/v2/convert.py000066400000000000000000000037171361214057700175370ustar00rootroot00000000000000"""Code for converting notebooks to and from the v2 format. Authors: * Brian Granger * Jonathan Frederic """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from .nbbase import ( new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output ) #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- def upgrade(nb, from_version=1): """Convert a notebook to the v2 format. Parameters ---------- nb : NotebookNode The Python representation of the notebook to convert. from_version : int The version of the notebook to convert from. """ if from_version == 1: newnb = new_notebook() ws = new_worksheet() for cell in nb.cells: if cell.cell_type == u'code': newcell = new_code_cell(input=cell.get('code'),prompt_number=cell.get('prompt_number')) elif cell.cell_type == u'text': newcell = new_text_cell(u'markdown',source=cell.get('text')) ws.cells.append(newcell) newnb.worksheets.append(ws) return newnb else: raise ValueError('Cannot convert a notebook from v%s to v2' % from_version) def downgrade(nb): """Convert a v2 notebook to v1. Parameters ---------- nb : NotebookNode The Python representation of the notebook to convert. """ raise Exception("Downgrade from notebook v2 to v1 is not supported.") nbformat-5.0.4/nbformat/v2/nbbase.py000066400000000000000000000125431361214057700173060ustar00rootroot00000000000000"""The basic dict based notebook format. The Python representation of a notebook is a nested structure of dictionary subclasses that support attribute access (ipython_genutils.ipstruct.Struct). The functions in this module are merely helpers to build the structs in the right form. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import pprint import uuid from ipython_genutils.ipstruct import Struct #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- class NotebookNode(Struct): pass def from_dict(d): if isinstance(d, dict): newd = NotebookNode() for k,v in d.items(): newd[k] = from_dict(v) return newd elif isinstance(d, (tuple, list)): return [from_dict(i) for i in d] else: return d def new_output(output_type=None, output_text=None, output_png=None, output_html=None, output_svg=None, output_latex=None, output_json=None, output_javascript=None, output_jpeg=None, prompt_number=None, etype=None, evalue=None, traceback=None): """Create a new code cell with input and output""" output = NotebookNode() if output_type is not None: output.output_type = str(output_type) if output_type != 'pyerr': if output_text is not None: output.text = str(output_text) if output_png is not None: output.png = bytes(output_png) if output_jpeg is not None: output.jpeg = bytes(output_jpeg) if output_html is not None: output.html = str(output_html) if output_svg is not None: output.svg = str(output_svg) if output_latex is not None: output.latex = str(output_latex) if output_json is not None: output.json = str(output_json) if output_javascript is not None: output.javascript = str(output_javascript) if output_type == u'pyout': if prompt_number is not None: output.prompt_number = int(prompt_number) if output_type == u'pyerr': if etype is not None: output.etype = str(etype) if evalue is not None: output.evalue = str(evalue) if traceback is not None: output.traceback = [str(frame) for frame in list(traceback)] return output def new_code_cell(input=None, prompt_number=None, outputs=None, language=u'python', collapsed=False): """Create a new code cell with input and output""" cell = NotebookNode() cell.cell_type = u'code' if language is not None: cell.language = str(language) if input is not None: cell.input = str(input) if prompt_number is not None: cell.prompt_number = int(prompt_number) if outputs is None: cell.outputs = [] else: cell.outputs = outputs if collapsed is not None: cell.collapsed = bool(collapsed) return cell def new_text_cell(cell_type, source=None, rendered=None): """Create a new text cell.""" cell = NotebookNode() if source is not None: cell.source = str(source) if rendered is not None: cell.rendered = str(rendered) cell.cell_type = cell_type return cell def new_worksheet(name=None, cells=None): """Create a worksheet by name with with a list of cells.""" ws = NotebookNode() if name is not None: ws.name = str(name) if cells is None: ws.cells = [] else: ws.cells = list(cells) return ws def new_notebook(metadata=None, worksheets=None): """Create a notebook by name, id and a list of worksheets.""" nb = NotebookNode() nb.nbformat = 2 if worksheets is None: nb.worksheets = [] else: nb.worksheets = list(worksheets) if metadata is None: nb.metadata = new_metadata() else: nb.metadata = NotebookNode(metadata) return nb def new_metadata(name=None, authors=None, license=None, created=None, modified=None, gistid=None): """Create a new metadata node.""" metadata = NotebookNode() if name is not None: metadata.name = str(name) if authors is not None: metadata.authors = list(authors) if created is not None: metadata.created = str(created) if modified is not None: metadata.modified = str(modified) if license is not None: metadata.license = str(license) if gistid is not None: metadata.gistid = str(gistid) return metadata def new_author(name=None, email=None, affiliation=None, url=None): """Create a new author.""" author = NotebookNode() if name is not None: author.name = str(name) if email is not None: author.email = str(email) if affiliation is not None: author.affiliation = str(affiliation) if url is not None: author.url = str(url) return author nbformat-5.0.4/nbformat/v2/nbjson.py000066400000000000000000000036201361214057700173410ustar00rootroot00000000000000"""Read and write notebooks in JSON format. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import copy import json from .nbbase import from_dict from .rwbase import ( NotebookReader, NotebookWriter, restore_bytes, rejoin_lines, split_lines ) #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- class BytesEncoder(json.JSONEncoder): """A JSON encoder that accepts b64 (and other *ascii*) bytestrings.""" def default(self, obj): if isinstance(obj, bytes): return obj.decode('ascii') return json.JSONEncoder.default(self, obj) class JSONReader(NotebookReader): def reads(self, s, **kwargs): nb = json.loads(s, **kwargs) nb = self.to_notebook(nb, **kwargs) return nb def to_notebook(self, d, **kwargs): return restore_bytes(rejoin_lines(from_dict(d))) class JSONWriter(NotebookWriter): def writes(self, nb, **kwargs): kwargs['cls'] = BytesEncoder kwargs['indent'] = 1 kwargs['sort_keys'] = True if kwargs.pop('split_lines', True): nb = split_lines(copy.deepcopy(nb)) return json.dumps(nb, **kwargs) _reader = JSONReader() _writer = JSONWriter() reads = _reader.reads read = _reader.read to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes nbformat-5.0.4/nbformat/v2/nbpy.py000066400000000000000000000121521361214057700170200ustar00rootroot00000000000000"""Read and write notebooks as regular .py files. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import re from .rwbase import NotebookReader, NotebookWriter from .nbbase import new_code_cell, new_text_cell, new_worksheet, new_notebook #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- _encoding_declaration_re = re.compile(r"^#.*coding[:=]\s*([-\w.]+)") class PyReaderError(Exception): pass class PyReader(NotebookReader): def reads(self, s, **kwargs): return self.to_notebook(s,**kwargs) def to_notebook(self, s, **kwargs): lines = s.splitlines() cells = [] cell_lines = [] state = u'codecell' for line in lines: if line.startswith(u'# ') or _encoding_declaration_re.match(line): pass elif line.startswith(u'# '): cell = self.new_cell(state, cell_lines) if cell is not None: cells.append(cell) state = u'codecell' cell_lines = [] elif line.startswith(u'# '): cell = self.new_cell(state, cell_lines) if cell is not None: cells.append(cell) state = u'htmlcell' cell_lines = [] elif line.startswith(u'# '): cell = self.new_cell(state, cell_lines) if cell is not None: cells.append(cell) state = u'markdowncell' cell_lines = [] else: cell_lines.append(line) if cell_lines and state == u'codecell': cell = self.new_cell(state, cell_lines) if cell is not None: cells.append(cell) ws = new_worksheet(cells=cells) nb = new_notebook(worksheets=[ws]) return nb def new_cell(self, state, lines): if state == u'codecell': input = u'\n'.join(lines) input = input.strip(u'\n') if input: return new_code_cell(input=input) elif state == u'htmlcell': text = self._remove_comments(lines) if text: return new_text_cell(u'html',source=text) elif state == u'markdowncell': text = self._remove_comments(lines) if text: return new_text_cell(u'markdown',source=text) def _remove_comments(self, lines): new_lines = [] for line in lines: if line.startswith(u'#'): new_lines.append(line[2:]) else: new_lines.append(line) text = u'\n'.join(new_lines) text = text.strip(u'\n') return text def split_lines_into_blocks(self, lines): if len(lines) == 1: yield lines[0] raise StopIteration() import ast source = '\n'.join(lines) code = ast.parse(source) starts = [x.lineno-1 for x in code.body] for i in range(len(starts)-1): yield '\n'.join(lines[starts[i]:starts[i+1]]).strip('\n') yield '\n'.join(lines[starts[-1]:]).strip('\n') class PyWriter(NotebookWriter): def writes(self, nb, **kwargs): lines = [u'# -*- coding: utf-8 -*-'] lines.extend([u'# 2','']) for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == u'code': input = cell.get(u'input') if input is not None: lines.extend([u'# ',u'']) lines.extend(input.splitlines()) lines.append(u'') elif cell.cell_type == u'html': input = cell.get(u'source') if input is not None: lines.extend([u'# ',u'']) lines.extend([u'# ' + line for line in input.splitlines()]) lines.append(u'') elif cell.cell_type == u'markdown': input = cell.get(u'source') if input is not None: lines.extend([u'# ',u'']) lines.extend([u'# ' + line for line in input.splitlines()]) lines.append(u'') lines.append('') return str('\n'.join(lines)) _reader = PyReader() _writer = PyWriter() reads = _reader.reads read = _reader.read to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes nbformat-5.0.4/nbformat/v2/nbxml.py000066400000000000000000000014131361214057700171660ustar00rootroot00000000000000"""REMOVED: Read and write notebook files as XML. """ REMOVED_MSG = """\ Reading notebooks as XML has been removed to harden security and avoid possible denial-of-service attacks. The XML notebook format was deprecated before the Jupyter (previously IPython) Notebook was ever released. We are not aware of anyone using it, so we have removed it. If you were using this code, and you need to continue using it, feel free to fork an earlier version of the nbformat package and maintain it yourself. The issue which prompted this removal is: https://github.com/jupyter/nbformat/issues/132 """ def reads(s, **kwargs): raise Exception(REMOVED_MSG) def read(fp, **kwargs): raise Exception(REMOVED_MSG) def to_notebook(root, **kwargs): raise Exception(REMOVED_MSG) nbformat-5.0.4/nbformat/v2/rwbase.py000066400000000000000000000133751361214057700173430ustar00rootroot00000000000000"""Base classes and utilities for readers and writers. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import pprint from ipython_genutils.py3compat import str_to_bytes from .._compat import encodebytes, decodebytes #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- def restore_bytes(nb): """Restore bytes of image data from unicode-only formats. Base64 encoding is handled elsewhere. Bytes objects in the notebook are always b64-encoded. We DO NOT encode/decode around file formats. """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': for output in cell.outputs: if 'png' in output: output.png = str_to_bytes(output.png, 'ascii') if 'jpeg' in output: output.jpeg = str_to_bytes(output.jpeg, 'ascii') return nb # output keys that are likely to have multiline values _multiline_outputs = ['text', 'html', 'svg', 'latex', 'javascript', 'json'] def rejoin_lines(nb): """rejoin multiline text into strings For reversing effects of ``split_lines(nb)``. This only rejoins lines that have been split, so if text objects were not split they will pass through unchanged. Used when reading JSON files that may have been passed through split_lines. """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': if 'input' in cell and isinstance(cell.input, list): cell.input = u'\n'.join(cell.input) for output in cell.outputs: for key in _multiline_outputs: item = output.get(key, None) if isinstance(item, list): output[key] = u'\n'.join(item) else: # text cell for key in ['source', 'rendered']: item = cell.get(key, None) if isinstance(item, list): cell[key] = u'\n'.join(item) return nb def split_lines(nb): """split likely multiline text into lists of strings For file output more friendly to line-based VCS. ``rejoin_lines(nb)`` will reverse the effects of ``split_lines(nb)``. Used when writing JSON files. """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': if 'input' in cell and isinstance(cell.input, str): cell.input = cell.input.splitlines() for output in cell.outputs: for key in _multiline_outputs: item = output.get(key, None) if isinstance(item, str): output[key] = item.splitlines() else: # text cell for key in ['source', 'rendered']: item = cell.get(key, None) if isinstance(item, str): cell[key] = item.splitlines() return nb # b64 encode/decode are never actually used, because all bytes objects in # the notebook are already b64-encoded, and we don't need/want to double-encode def base64_decode(nb): """Restore all bytes objects in the notebook from base64-encoded strings. Note: This is never used """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': for output in cell.outputs: if 'png' in output: if isinstance(output.png, str): output.png = output.png.encode('ascii') output.png = decodebytes(output.png) if 'jpeg' in output: if isinstance(output.jpeg, str): output.jpeg = output.jpeg.encode('ascii') output.jpeg = decodebytes(output.jpeg) return nb def base64_encode(nb): """Base64 encode all bytes objects in the notebook. These will be b64-encoded unicode strings Note: This is never used """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': for output in cell.outputs: if 'png' in output: output.png = encodebytes(output.png).decode('ascii') if 'jpeg' in output: output.jpeg = encodebytes(output.jpeg).decode('ascii') return nb class NotebookReader(object): """A class for reading notebooks.""" def reads(self, s, **kwargs): """Read a notebook from a string.""" raise NotImplementedError("loads must be implemented in a subclass") def read(self, fp, **kwargs): """Read a notebook from a file like object""" return self.read(fp.read(), **kwargs) class NotebookWriter(object): """A class for writing notebooks.""" def writes(self, nb, **kwargs): """Write a notebook to a string.""" raise NotImplementedError("loads must be implemented in a subclass") def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" return fp.write(self.writes(nb,**kwargs)) nbformat-5.0.4/nbformat/v2/tests/000077500000000000000000000000001361214057700166375ustar00rootroot00000000000000nbformat-5.0.4/nbformat/v2/tests/__init__.py000066400000000000000000000000001361214057700207360ustar00rootroot00000000000000nbformat-5.0.4/nbformat/v2/tests/nbexamples.py000066400000000000000000000043711361214057700213540ustar00rootroot00000000000000import os from ..._compat import encodebytes from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output, new_metadata, new_author ) # some random base64-encoded *bytes* png = encodebytes(os.urandom(5)) jpeg = encodebytes(os.urandom(6)) ws = new_worksheet(name='worksheet1') ws.cells.append(new_text_cell( u'html', source='Some NumPy Examples', rendered='Some NumPy Examples' )) ws.cells.append(new_code_cell( input='import numpy', prompt_number=1, collapsed=False )) ws.cells.append(new_text_cell( u'markdown', source='A random array', rendered='A random array' )) ws.cells.append(new_code_cell( input='a = numpy.random.rand(100)', prompt_number=2, collapsed=True )) ws.cells.append(new_code_cell( input='print a', prompt_number=3, collapsed=False, outputs=[new_output( output_type=u'pyout', output_text=u'', output_html=u'The HTML rep', output_latex=u'$a$', output_png=png, output_jpeg=jpeg, output_svg=u'', output_json=u'json data', output_javascript=u'var i=0;', prompt_number=3 ),new_output( output_type=u'display_data', output_text=u'', output_html=u'The HTML rep', output_latex=u'$a$', output_png=png, output_jpeg=jpeg, output_svg=u'', output_json=u'json data', output_javascript=u'var i=0;' ),new_output( output_type=u'pyerr', etype=u'NameError', evalue=u'NameError was here', traceback=[u'frame 0', u'frame 1', u'frame 2'] )] )) authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com', affiliation=u'Fox',url=u'http://www.fox.com')] md = new_metadata(name=u'My Notebook',license=u'BSD',created=u'8601_goes_here', modified=u'8601_goes_here',gistid=u'21341231',authors=authors) nb0 = new_notebook( worksheets=[ws, new_worksheet(name='worksheet2')], metadata=md ) nb0_py = """# -*- coding: utf-8 -*- # 2 # # Some NumPy Examples # import numpy # # A random array # a = numpy.random.rand(100) # print a """ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v2/tests/test_json.py�������������������������������������������������������0000664�0000000�0000000�00000001636�13612140577�0021227�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pprint from unittest import TestCase from ..nbjson import reads, writes from .nbexamples import nb0 class TestJSON(TestCase): def test_roundtrip(self): s = writes(nb0) # print # print pprint.pformat(nb0,indent=2) # print # print pprint.pformat(reads(s),indent=2) # print # print s self.assertEqual(reads(s),nb0) def test_roundtrip_nosplit(self): """Ensure that multiline blobs are still readable""" # ensures that notebooks written prior to splitlines change # are still readable. s = writes(nb0, split_lines=False) self.assertEqual(reads(s),nb0) def test_roundtrip_split(self): """Ensure that splitting multiline blocks is safe""" # This won't differ from test_roundtrip unless the default changes s = writes(nb0, split_lines=True) self.assertEqual(reads(s),nb0) ��������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v2/tests/test_nbbase.py�����������������������������������������������������0000664�0000000�0000000�00000010170�13612140577�0021501�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from unittest import TestCase from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output, new_author, new_metadata ) class TestCell(TestCase): def test_empty_code_cell(self): cc = new_code_cell() self.assertEqual(cc.cell_type,u'code') self.assertEqual(u'input' not in cc, True) self.assertEqual(u'prompt_number' not in cc, True) self.assertEqual(cc.outputs, []) self.assertEqual(cc.collapsed, False) def test_code_cell(self): cc = new_code_cell(input='a=10', prompt_number=0, collapsed=True) cc.outputs = [new_output(output_type=u'pyout', output_svg=u'foo',output_text=u'10',prompt_number=0)] self.assertEqual(cc.input, u'a=10') self.assertEqual(cc.prompt_number, 0) self.assertEqual(cc.language, u'python') self.assertEqual(cc.outputs[0].svg, u'foo') self.assertEqual(cc.outputs[0].text, u'10') self.assertEqual(cc.outputs[0].prompt_number, 0) self.assertEqual(cc.collapsed, True) def test_pyerr(self): o = new_output(output_type=u'pyerr', etype=u'NameError', evalue=u'Name not found', traceback=[u'frame 0', u'frame 1', u'frame 2'] ) self.assertEqual(o.output_type, u'pyerr') self.assertEqual(o.etype, u'NameError') self.assertEqual(o.evalue, u'Name not found') self.assertEqual(o.traceback, [u'frame 0', u'frame 1', u'frame 2']) def test_empty_html_cell(self): tc = new_text_cell(u'html') self.assertEqual(tc.cell_type, u'html') self.assertEqual(u'source' not in tc, True) self.assertEqual(u'rendered' not in tc, True) def test_html_cell(self): tc = new_text_cell(u'html', 'hi', 'hi') self.assertEqual(tc.source, u'hi') self.assertEqual(tc.rendered, u'hi') def test_empty_markdown_cell(self): tc = new_text_cell(u'markdown') self.assertEqual(tc.cell_type, u'markdown') self.assertEqual(u'source' not in tc, True) self.assertEqual(u'rendered' not in tc, True) def test_markdown_cell(self): tc = new_text_cell(u'markdown', 'hi', 'hi') self.assertEqual(tc.source, u'hi') self.assertEqual(tc.rendered, u'hi') class TestWorksheet(TestCase): def test_empty_worksheet(self): ws = new_worksheet() self.assertEqual(ws.cells,[]) self.assertEqual(u'name' not in ws, True) def test_worksheet(self): cells = [new_code_cell(), new_text_cell(u'html')] ws = new_worksheet(cells=cells,name=u'foo') self.assertEqual(ws.cells,cells) self.assertEqual(ws.name,u'foo') class TestNotebook(TestCase): def test_empty_notebook(self): nb = new_notebook() self.assertEqual(nb.worksheets, []) self.assertEqual(nb.metadata, NotebookNode()) self.assertEqual(nb.nbformat,2) def test_notebook(self): worksheets = [new_worksheet(),new_worksheet()] metadata = new_metadata(name=u'foo') nb = new_notebook(metadata=metadata,worksheets=worksheets) self.assertEqual(nb.metadata.name,u'foo') self.assertEqual(nb.worksheets,worksheets) self.assertEqual(nb.nbformat,2) class TestMetadata(TestCase): def test_empty_metadata(self): md = new_metadata() self.assertEqual(u'name' not in md, True) self.assertEqual(u'authors' not in md, True) self.assertEqual(u'license' not in md, True) self.assertEqual(u'saved' not in md, True) self.assertEqual(u'modified' not in md, True) self.assertEqual(u'gistid' not in md, True) def test_metadata(self): authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com')] md = new_metadata(name=u'foo',license=u'BSD',created=u'today', modified=u'now',gistid=u'21341231',authors=authors) self.assertEqual(md.name, u'foo') self.assertEqual(md.license, u'BSD') self.assertEqual(md.created, u'today') self.assertEqual(md.modified, u'now') self.assertEqual(md.gistid, u'21341231') self.assertEqual(md.authors, authors) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v2/tests/test_nbpy.py�������������������������������������������������������0000664�0000000�0000000�00000000477�13612140577�0021230�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from unittest import TestCase from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook ) from ..nbpy import reads, writes from .nbexamples import nb0, nb0_py class TestPy(TestCase): def test_write(self): s = writes(nb0) self.assertEqual(s,nb0_py) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/�������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13612140577�0015476�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/__init__.py��������������������������������������������������������������0000664�0000000�0000000�00000004430�13612140577�0017610�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""The main API for the v3 notebook format. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. __all__ = ['NotebookNode', 'new_code_cell', 'new_text_cell', 'new_notebook', 'new_output', 'new_worksheet', 'new_metadata', 'new_author', 'new_heading_cell', 'nbformat', 'nbformat_minor', 'nbformat_schema', 'reads_json', 'writes_json', 'read_json', 'write_json', 'to_notebook_json', 'reads_py', 'writes_py', 'read_py', 'write_py', 'to_notebook_py', 'downgrade', 'upgrade', 'parse_filename' ] import os from .nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet, new_metadata, new_author, new_heading_cell, nbformat, nbformat_minor, nbformat_schema ) from .nbjson import reads as reads_json, writes as writes_json from .nbjson import reads as read_json, writes as write_json from .nbjson import to_notebook as to_notebook_json from .nbpy import reads as reads_py, writes as writes_py from .nbpy import reads as read_py, writes as write_py from .nbpy import to_notebook as to_notebook_py from .convert import downgrade, upgrade def parse_filename(fname): """Parse a notebook filename. This function takes a notebook filename and returns the notebook format (json/py) and the notebook name. This logic can be summarized as follows: * notebook.ipynb -> (notebook.ipynb, notebook, json) * notebook.json -> (notebook.json, notebook, json) * notebook.py -> (notebook.py, notebook, py) * notebook -> (notebook.ipynb, notebook, json) Parameters ---------- fname : unicode The notebook filename. The filename can use a specific filename extention (.ipynb, .json, .py) or none, in which case .ipynb will be assumed. Returns ------- (fname, name, format) : (unicode, unicode, unicode) The filename, notebook name and format. """ basename, ext = os.path.splitext(fname) if ext == u'.ipynb': format = u'json' elif ext == u'.json': format = u'json' elif ext == u'.py': format = u'py' else: basename = fname fname = fname + u'.ipynb' format = u'json' return fname, basename, format ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/convert.py���������������������������������������������������������������0000664�0000000�0000000�00000005137�13612140577�0017536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Code for converting notebooks to and from the v2 format.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from .nbbase import ( new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output, nbformat, nbformat_minor ) from nbformat import v2 def _unbytes(obj): """There should be no bytes objects in a notebook v2 stores png/jpeg as b64 ascii bytes """ if isinstance(obj, dict): for k,v in obj.items(): obj[k] = _unbytes(v) elif isinstance(obj, list): for i,v in enumerate(obj): obj[i] = _unbytes(v) elif isinstance(obj, bytes): # only valid bytes are b64-encoded ascii obj = obj.decode('ascii') return obj def upgrade(nb, from_version=2, from_minor=0): """Convert a notebook to v3. Parameters ---------- nb : NotebookNode The Python representation of the notebook to convert. from_version : int The original version of the notebook to convert. from_minor : int The original minor version of the notebook to convert (only relevant for v >= 3). """ if from_version == 2: # Mark the original nbformat so consumers know it has been converted. nb.nbformat = nbformat nb.nbformat_minor = nbformat_minor nb.orig_nbformat = 2 nb = _unbytes(nb) for ws in nb['worksheets']: for cell in ws['cells']: cell.setdefault('metadata', {}) return nb elif from_version == 3: if from_minor != nbformat_minor: nb.orig_nbformat_minor = from_minor nb.nbformat_minor = nbformat_minor return nb else: raise ValueError('Cannot convert a notebook directly from v%s to v3. ' \ 'Try using the nbformat.convert module.' % from_version) def heading_to_md(cell): """turn heading cell into corresponding markdown""" cell.cell_type = "markdown" level = cell.pop('level', 1) cell.source = '#'*level + ' ' + cell.source def raw_to_md(cell): """let raw passthrough as markdown""" cell.cell_type = "markdown" def downgrade(nb): """Convert a v3 notebook to v2. Parameters ---------- nb : NotebookNode The Python representation of the notebook to convert. """ if nb.nbformat != 3: return nb nb.nbformat = 2 for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'heading': heading_to_md(cell) elif cell.cell_type == 'raw': raw_to_md(cell) return nb���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/nbbase.py����������������������������������������������������������������0000664�0000000�0000000�00000014536�13612140577�0017313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""The basic dict based notebook format. The Python representation of a notebook is a nested structure of dictionary subclasses that support attribute access (ipython_genutils.ipstruct.Struct). The functions in this module are merely helpers to build the structs in the right form. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import pprint import uuid from ipython_genutils.ipstruct import Struct from ipython_genutils.py3compat import cast_unicode #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- # Change this when incrementing the nbformat version nbformat = 3 nbformat_minor = 0 nbformat_schema = { (3, 0): 'nbformat.v3.schema.json' } class NotebookNode(Struct): pass def from_dict(d): if isinstance(d, dict): newd = NotebookNode() for k,v in d.items(): newd[k] = from_dict(v) return newd elif isinstance(d, (tuple, list)): return [from_dict(i) for i in d] else: return d def new_output(output_type, output_text=None, output_png=None, output_html=None, output_svg=None, output_latex=None, output_json=None, output_javascript=None, output_jpeg=None, prompt_number=None, ename=None, evalue=None, traceback=None, stream=None, metadata=None): """Create a new output, to go in the ``cell.outputs`` list of a code cell. """ output = NotebookNode() output.output_type = str(output_type) if metadata is None: metadata = {} if not isinstance(metadata, dict): raise TypeError("metadata must be dict") if output_type in {u'pyout', 'display_data'}: output.metadata = metadata if output_type != 'pyerr': if output_text is not None: output.text = cast_unicode(output_text) if output_png is not None: output.png = cast_unicode(output_png) if output_jpeg is not None: output.jpeg = cast_unicode(output_jpeg) if output_html is not None: output.html = cast_unicode(output_html) if output_svg is not None: output.svg = cast_unicode(output_svg) if output_latex is not None: output.latex = cast_unicode(output_latex) if output_json is not None: output.json = cast_unicode(output_json) if output_javascript is not None: output.javascript = cast_unicode(output_javascript) if output_type == u'pyout': if prompt_number is not None: output.prompt_number = int(prompt_number) if output_type == u'pyerr': if ename is not None: output.ename = cast_unicode(ename) if evalue is not None: output.evalue = cast_unicode(evalue) if traceback is not None: output.traceback = [cast_unicode(frame) for frame in list(traceback)] if output_type == u'stream': output.stream = 'stdout' if stream is None else cast_unicode(stream) return output def new_code_cell(input=None, prompt_number=None, outputs=None, language=u'python', collapsed=False, metadata=None): """Create a new code cell with input and output""" cell = NotebookNode() cell.cell_type = u'code' if language is not None: cell.language = cast_unicode(language) if input is not None: cell.input = cast_unicode(input) if prompt_number is not None: cell.prompt_number = int(prompt_number) if outputs is None: cell.outputs = [] else: cell.outputs = outputs if collapsed is not None: cell.collapsed = bool(collapsed) cell.metadata = NotebookNode(metadata or {}) return cell def new_text_cell(cell_type, source=None, rendered=None, metadata=None): """Create a new text cell.""" cell = NotebookNode() # VERSIONHACK: plaintext -> raw # handle never-released plaintext name for raw cells if cell_type == 'plaintext': cell_type = 'raw' if source is not None: cell.source = cast_unicode(source) cell.metadata = NotebookNode(metadata or {}) cell.cell_type = cell_type return cell def new_heading_cell(source=None, level=1, rendered=None, metadata=None): """Create a new section cell with a given integer level.""" cell = NotebookNode() cell.cell_type = u'heading' if source is not None: cell.source = cast_unicode(source) cell.level = int(level) cell.metadata = NotebookNode(metadata or {}) return cell def new_worksheet(name=None, cells=None, metadata=None): """Create a worksheet by name with with a list of cells.""" ws = NotebookNode() if cells is None: ws.cells = [] else: ws.cells = list(cells) ws.metadata = NotebookNode(metadata or {}) return ws def new_notebook(name=None, metadata=None, worksheets=None): """Create a notebook by name, id and a list of worksheets.""" nb = NotebookNode() nb.nbformat = nbformat nb.nbformat_minor = nbformat_minor if worksheets is None: nb.worksheets = [] else: nb.worksheets = list(worksheets) if metadata is None: nb.metadata = new_metadata() else: nb.metadata = NotebookNode(metadata) if name is not None: nb.metadata.name = cast_unicode(name) return nb def new_metadata(name=None, authors=None, license=None, created=None, modified=None, gistid=None): """Create a new metadata node.""" metadata = NotebookNode() if name is not None: metadata.name = cast_unicode(name) if authors is not None: metadata.authors = list(authors) if created is not None: metadata.created = cast_unicode(created) if modified is not None: metadata.modified = cast_unicode(modified) if license is not None: metadata.license = cast_unicode(license) if gistid is not None: metadata.gistid = cast_unicode(gistid) return metadata def new_author(name=None, email=None, affiliation=None, url=None): """Create a new author.""" author = NotebookNode() if name is not None: author.name = cast_unicode(name) if email is not None: author.email = cast_unicode(email) if affiliation is not None: author.affiliation = cast_unicode(affiliation) if url is not None: author.url = cast_unicode(url) return author ������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/nbformat.v3.schema.json��������������������������������������������������0000664�0000000�0000000�00000035076�13612140577�0022002�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "$schema": "http://json-schema.org/draft-04/schema#", "description": "IPython Notebook v3.0 JSON schema.", "type": "object", "additionalProperties": false, "required": ["metadata", "nbformat_minor", "nbformat", "worksheets"], "properties": { "metadata": { "description": "Notebook root-level metadata.", "type": "object", "additionalProperties": true, "properties": { "kernel_info": { "description": "Kernel information.", "type": "object", "required": ["name", "language"], "properties": { "name": { "description": "Name of the kernel specification.", "type": "string" }, "language": { "description": "The programming language which this kernel runs.", "type": "string" }, "codemirror_mode": { "description": "The codemirror mode to use for code in this language.", "type": "string" } } }, "signature": { "description": "Hash of the notebook.", "type": "string" } } }, "nbformat_minor": { "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.", "type": "integer", "minimum": 0 }, "nbformat": { "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.", "type": "integer", "minimum": 3, "maximum": 3 }, "orig_nbformat": { "description": "Original notebook format (major number) before converting the notebook between versions.", "type": "integer", "minimum": 1 }, "orig_nbformat_minor": { "description": "Original notebook format (minor number) before converting the notebook between versions.", "type": "integer", "minimum": 0 }, "worksheets" : { "description": "Array of worksheets", "type": "array", "items": {"$ref": "#/definitions/worksheet"} } }, "definitions": { "worksheet": { "additionalProperties": false, "required" : ["cells"], "properties":{ "cells": { "description": "Array of cells of the current notebook.", "type": "array", "items": { "type": "object", "oneOf": [ {"$ref": "#/definitions/raw_cell"}, {"$ref": "#/definitions/markdown_cell"}, {"$ref": "#/definitions/heading_cell"}, {"$ref": "#/definitions/code_cell"} ] } }, "metadata": { "type": "object", "description": "metadata of the current worksheet" } } }, "raw_cell": { "description": "Notebook raw nbconvert cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["raw"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "format": { "description": "Raw cell metadata format for nbconvert.", "type": "string" }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "source": {"$ref": "#/definitions/misc/source"} } }, "markdown_cell": { "description": "Notebook markdown cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["markdown", "html"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true }, "source": {"$ref": "#/definitions/misc/source"} } }, "heading_cell": { "description": "Notebook heading cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "source", "level"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["heading"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true }, "source": {"$ref": "#/definitions/misc/source"}, "level": { "description": "Level of heading cells.", "type": "integer", "minimum": 1 } } }, "code_cell": { "description": "Notebook code cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "input", "outputs", "language"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["code"] }, "language": { "description": "The cell's language (always Python)", "type": "string" }, "collapsed": { "description": "Whether the cell is collapsed/expanded.", "type": "boolean" }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true }, "input": {"$ref": "#/definitions/misc/source"}, "outputs": { "description": "Execution, display, or stream outputs.", "type": "array", "items": {"$ref": "#/definitions/output"} }, "prompt_number": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 } } }, "output": { "type": "object", "oneOf": [ {"$ref": "#/definitions/pyout"}, {"$ref": "#/definitions/display_data"}, {"$ref": "#/definitions/stream"}, {"$ref": "#/definitions/pyerr"} ] }, "pyout": { "description": "Result of executing a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "prompt_number"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["pyout"] }, "prompt_number": { "description": "A result's prompt number.", "type": ["integer"], "minimum": 0 }, "text": {"$ref": "#/definitions/misc/multiline_string"}, "latex": {"$ref": "#/definitions/misc/multiline_string"}, "png": {"$ref": "#/definitions/misc/multiline_string"}, "jpeg": {"$ref": "#/definitions/misc/multiline_string"}, "svg": {"$ref": "#/definitions/misc/multiline_string"}, "html": {"$ref": "#/definitions/misc/multiline_string"}, "javascript": {"$ref": "#/definitions/misc/multiline_string"}, "json": {"$ref": "#/definitions/misc/multiline_string"}, "pdf": {"$ref": "#/definitions/misc/multiline_string"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} }, "patternProperties": { "^[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": { "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" } } }, "display_data": { "description": "Data displayed as a result of code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["display_data"] }, "text": {"$ref": "#/definitions/misc/multiline_string"}, "latex": {"$ref": "#/definitions/misc/multiline_string"}, "png": {"$ref": "#/definitions/misc/multiline_string"}, "jpeg": {"$ref": "#/definitions/misc/multiline_string"}, "svg": {"$ref": "#/definitions/misc/multiline_string"}, "html": {"$ref": "#/definitions/misc/multiline_string"}, "javascript": {"$ref": "#/definitions/misc/multiline_string"}, "json": {"$ref": "#/definitions/misc/multiline_string"}, "pdf": {"$ref": "#/definitions/misc/multiline_string"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} }, "patternProperties": { "[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": { "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" } } }, "stream": { "description": "Stream output from a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "stream", "text"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["stream"] }, "stream": { "description": "The stream type/destination.", "type": "string" }, "text": { "description": "The stream's text output, represented as an array of strings.", "$ref": "#/definitions/misc/multiline_string" } } }, "pyerr": { "description": "Output of an error that occurred during code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "ename", "evalue", "traceback"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["pyerr"] }, "ename": { "description": "The name of the error.", "type": "string" }, "evalue": { "description": "The value, or message, of the error.", "type": "string" }, "traceback": { "description": "The error's traceback, represented as an array of strings.", "type": "array", "items": {"type": "string"} } } }, "misc": { "metadata_name": { "description": "The cell's name. If present, must be a non-empty string.", "type": "string", "pattern": "^.+$" }, "metadata_tags": { "description": "The cell's tags. Tags must be unique, and must not contain commas.", "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^[^,]+$" } }, "source": { "description": "Contents of the cell, represented as an array of lines.", "$ref": "#/definitions/misc/multiline_string" }, "prompt_number": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 }, "mimetype": { "patternProperties": { "^[a-zA-Z0-9\\-\\+]+/[a-zA-Z0-9\\-\\+]+": { "description": "The cell's mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" } } }, "output_metadata": { "description": "Cell output metadata.", "type": "object", "additionalProperties": true }, "multiline_string": { "oneOf" : [ {"type": "string"}, { "type": "array", "items": {"type": "string"} } ] } } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/nbjson.py����������������������������������������������������������������0000664�0000000�0000000�00000002653�13612140577�0017347�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Read and write notebooks in JSON format.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import copy import json from .nbbase import from_dict from .rwbase import ( NotebookReader, NotebookWriter, restore_bytes, rejoin_lines, split_lines, strip_transient, ) class BytesEncoder(json.JSONEncoder): """A JSON encoder that accepts b64 (and other *ascii*) bytestrings.""" def default(self, obj): if isinstance(obj, bytes): return obj.decode('ascii') return json.JSONEncoder.default(self, obj) class JSONReader(NotebookReader): def reads(self, s, **kwargs): nb = json.loads(s, **kwargs) nb = self.to_notebook(nb, **kwargs) nb = strip_transient(nb) return nb def to_notebook(self, d, **kwargs): return rejoin_lines(from_dict(d)) class JSONWriter(NotebookWriter): def writes(self, nb, **kwargs): kwargs['cls'] = BytesEncoder kwargs['indent'] = 1 kwargs['sort_keys'] = True kwargs['separators'] = (',',': ') nb = copy.deepcopy(nb) nb = strip_transient(nb) if kwargs.pop('split_lines', True): nb = split_lines(nb) return json.dumps(nb, **kwargs) _reader = JSONReader() _writer = JSONWriter() reads = _reader.reads read = _reader.read to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes �������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/nbpy.py������������������������������������������������������������������0000664�0000000�0000000�00000016611�13612140577�0017025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Read and write notebooks as regular .py files. Authors: * Brian Granger """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import re from .rwbase import NotebookReader, NotebookWriter from .nbbase import ( new_code_cell, new_text_cell, new_worksheet, new_notebook, new_heading_cell, nbformat, nbformat_minor, ) #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- _encoding_declaration_re = re.compile(r"^#.*coding[:=]\s*([-\w.]+)") class PyReaderError(Exception): pass class PyReader(NotebookReader): def reads(self, s, **kwargs): return self.to_notebook(s,**kwargs) def to_notebook(self, s, **kwargs): lines = s.splitlines() cells = [] cell_lines = [] kwargs = {} state = u'codecell' for line in lines: if line.startswith(u'# ') or _encoding_declaration_re.match(line): pass elif line.startswith(u'# '): cell = self.new_cell(state, cell_lines, **kwargs) if cell is not None: cells.append(cell) state = u'codecell' cell_lines = [] kwargs = {} elif line.startswith(u'# '): cell = self.new_cell(state, cell_lines, **kwargs) if cell is not None: cells.append(cell) state = u'htmlcell' cell_lines = [] kwargs = {} elif line.startswith(u'# '): cell = self.new_cell(state, cell_lines, **kwargs) if cell is not None: cells.append(cell) state = u'markdowncell' cell_lines = [] kwargs = {} # VERSIONHACK: plaintext -> raw elif line.startswith(u'# ') or line.startswith(u'# '): cell = self.new_cell(state, cell_lines, **kwargs) if cell is not None: cells.append(cell) state = u'rawcell' cell_lines = [] kwargs = {} elif line.startswith(u'# \d)>',line) if m is not None: state = u'headingcell' kwargs = {} kwargs['level'] = int(m.group('level')) else: state = u'codecell' kwargs = {} cell_lines = [] else: cell_lines.append(line) if cell_lines and state == u'codecell': cell = self.new_cell(state, cell_lines) if cell is not None: cells.append(cell) ws = new_worksheet(cells=cells) nb = new_notebook(worksheets=[ws]) return nb def new_cell(self, state, lines, **kwargs): if state == u'codecell': input = u'\n'.join(lines) input = input.strip(u'\n') if input: return new_code_cell(input=input) elif state == u'htmlcell': text = self._remove_comments(lines) if text: return new_text_cell(u'html',source=text) elif state == u'markdowncell': text = self._remove_comments(lines) if text: return new_text_cell(u'markdown',source=text) elif state == u'rawcell': text = self._remove_comments(lines) if text: return new_text_cell(u'raw',source=text) elif state == u'headingcell': text = self._remove_comments(lines) level = kwargs.get('level',1) if text: return new_heading_cell(source=text,level=level) def _remove_comments(self, lines): new_lines = [] for line in lines: if line.startswith(u'#'): new_lines.append(line[2:]) else: new_lines.append(line) text = u'\n'.join(new_lines) text = text.strip(u'\n') return text def split_lines_into_blocks(self, lines): if len(lines) == 1: yield lines[0] raise StopIteration() import ast source = '\n'.join(lines) code = ast.parse(source) starts = [x.lineno-1 for x in code.body] for i in range(len(starts)-1): yield '\n'.join(lines[starts[i]:starts[i+1]]).strip('\n') yield '\n'.join(lines[starts[-1]:]).strip('\n') class PyWriter(NotebookWriter): def writes(self, nb, **kwargs): lines = [u'# -*- coding: utf-8 -*-'] lines.extend([ u'# %i.%i' % (nbformat, nbformat_minor), u'', ]) for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == u'code': input = cell.get(u'input') if input is not None: lines.extend([u'# ',u'']) lines.extend(input.splitlines()) lines.append(u'') elif cell.cell_type == u'html': input = cell.get(u'source') if input is not None: lines.extend([u'# ',u'']) lines.extend([u'# ' + line for line in input.splitlines()]) lines.append(u'') elif cell.cell_type == u'markdown': input = cell.get(u'source') if input is not None: lines.extend([u'# ',u'']) lines.extend([u'# ' + line for line in input.splitlines()]) lines.append(u'') elif cell.cell_type == u'raw': input = cell.get(u'source') if input is not None: lines.extend([u'# ',u'']) lines.extend([u'# ' + line for line in input.splitlines()]) lines.append(u'') elif cell.cell_type == u'heading': input = cell.get(u'source') level = cell.get(u'level',1) if input is not None: lines.extend([u'# ' % level,u'']) lines.extend([u'# ' + line for line in input.splitlines()]) lines.append(u'') lines.append('') return u'\n'.join(lines) _reader = PyReader() _writer = PyWriter() reads = _reader.reads read = _reader.read to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes �����������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/rwbase.py����������������������������������������������������������������0000664�0000000�0000000�00000014263�13612140577�0017341�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Base classes and utilities for readers and writers.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from ipython_genutils.py3compat import str_to_bytes from .._compat import encodebytes, decodebytes def restore_bytes(nb): """Restore bytes of image data from unicode-only formats. Base64 encoding is handled elsewhere. Bytes objects in the notebook are always b64-encoded. We DO NOT encode/decode around file formats. Note: this is never used """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': for output in cell.outputs: if 'png' in output: output.png = str_to_bytes(output.png, 'ascii') if 'jpeg' in output: output.jpeg = str_to_bytes(output.jpeg, 'ascii') return nb # output keys that are likely to have multiline values _multiline_outputs = ['text', 'html', 'svg', 'latex', 'javascript', 'json'] # FIXME: workaround for old splitlines() def _join_lines(lines): """join lines that have been written by splitlines() Has logic to protect against `splitlines()`, which should have been `splitlines(True)` """ if lines and lines[0].endswith(('\n', '\r')): # created by splitlines(True) return u''.join(lines) else: # created by splitlines() return u'\n'.join(lines) def rejoin_lines(nb): """rejoin multiline text into strings For reversing effects of ``split_lines(nb)``. This only rejoins lines that have been split, so if text objects were not split they will pass through unchanged. Used when reading JSON files that may have been passed through split_lines. """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': if 'input' in cell and isinstance(cell.input, list): cell.input = _join_lines(cell.input) for output in cell.outputs: for key in _multiline_outputs: item = output.get(key, None) if isinstance(item, list): output[key] = _join_lines(item) else: # text, heading cell for key in ['source', 'rendered']: item = cell.get(key, None) if isinstance(item, list): cell[key] = _join_lines(item) return nb def split_lines(nb): """split likely multiline text into lists of strings For file output more friendly to line-based VCS. ``rejoin_lines(nb)`` will reverse the effects of ``split_lines(nb)``. Used when writing JSON files. """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': if 'input' in cell and isinstance(cell.input, str): cell.input = cell.input.splitlines(True) for output in cell.outputs: for key in _multiline_outputs: item = output.get(key, None) if isinstance(item, str): output[key] = item.splitlines(True) else: # text, heading cell for key in ['source', 'rendered']: item = cell.get(key, None) if isinstance(item, str): cell[key] = item.splitlines(True) return nb # b64 encode/decode are never actually used, because all bytes objects in # the notebook are already b64-encoded, and we don't need/want to double-encode def base64_decode(nb): """Restore all bytes objects in the notebook from base64-encoded strings. Note: This is never used """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': for output in cell.outputs: if 'png' in output: if isinstance(output.png, str): output.png = output.png.encode('ascii') output.png = decodebytes(output.png) if 'jpeg' in output: if isinstance(output.jpeg, str): output.jpeg = output.jpeg.encode('ascii') output.jpeg = decodebytes(output.jpeg) return nb def base64_encode(nb): """Base64 encode all bytes objects in the notebook. These will be b64-encoded unicode strings Note: This is never used """ for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': for output in cell.outputs: if 'png' in output: output.png = encodebytes(output.png).decode('ascii') if 'jpeg' in output: output.jpeg = encodebytes(output.jpeg).decode('ascii') return nb def strip_transient(nb): """Strip transient values that shouldn't be stored in files. This should be called in *both* read and write. """ nb.pop('orig_nbformat', None) nb.pop('orig_nbformat_minor', None) for ws in nb['worksheets']: for cell in ws['cells']: cell.get('metadata', {}).pop('trusted', None) # strip cell.trusted even though it shouldn't be used, # since it's where the transient value used to be stored. cell.pop('trusted', None) return nb class NotebookReader(object): """A class for reading notebooks.""" def reads(self, s, **kwargs): """Read a notebook from a string.""" raise NotImplementedError("loads must be implemented in a subclass") def read(self, fp, **kwargs): """Read a notebook from a file like object""" nbs = fp.read() return self.reads(nbs, **kwargs) class NotebookWriter(object): """A class for writing notebooks.""" def writes(self, nb, **kwargs): """Write a notebook to a string.""" raise NotImplementedError("loads must be implemented in a subclass") def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" nbs = self.writes(nb,**kwargs) return fp.write(nbs) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/tests/�������������������������������������������������������������������0000775�0000000�0000000�00000000000�13612140577�0016640�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/tests/__init__.py��������������������������������������������������������0000664�0000000�0000000�00000000000�13612140577�0020737�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/tests/formattest.py������������������������������������������������������0000664�0000000�0000000�00000002730�13612140577�0021404�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf8 -*- import io import os import shutil import tempfile pjoin = os.path.join from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook ) from ..nbpy import reads, writes, read, write from .nbexamples import nb0, nb0_py def open_utf8(fname, mode): return io.open(fname, mode=mode, encoding='utf-8') class NBFormatTest: """Mixin for writing notebook format tests""" # override with appropriate values in subclasses nb0_ref = None ext = None mod = None def setUp(self): self.wd = tempfile.mkdtemp() def tearDown(self): shutil.rmtree(self.wd) def assertNBEquals(self, nba, nbb): self.assertEqual(nba, nbb) def test_writes(self): s = self.mod.writes(nb0) if self.nb0_ref: self.assertEqual(s, self.nb0_ref) def test_reads(self): s = self.mod.writes(nb0) nb = self.mod.reads(s) def test_roundtrip(self): s = self.mod.writes(nb0) self.assertNBEquals(self.mod.reads(s),nb0) def test_write_file(self): with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'w') as f: self.mod.write(nb0, f) def test_read_file(self): with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'w') as f: self.mod.write(nb0, f) with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'r') as f: nb = self.mod.read(f) ����������������������������������������nbformat-5.0.4/nbformat/v3/tests/nbexamples.py������������������������������������������������������0000664�0000000�0000000�00000005671�13612140577�0021361�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- import os from ..._compat import encodebytes from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output, new_metadata, new_author, new_heading_cell, nbformat, nbformat_minor ) # some random base64-encoded *text* png = encodebytes(os.urandom(5)).decode('ascii') jpeg = encodebytes(os.urandom(6)).decode('ascii') ws = new_worksheet() ws.cells.append(new_text_cell( u'html', source='Some NumPy Examples', )) ws.cells.append(new_code_cell( input='import numpy', prompt_number=1, collapsed=False )) ws.cells.append(new_text_cell( u'markdown', source='A random array', )) ws.cells.append(new_text_cell( u'raw', source='A random array', )) ws.cells.append(new_heading_cell( u'My Heading', level=2 )) ws.cells.append(new_code_cell( input='a = numpy.random.rand(100)', prompt_number=2, collapsed=True )) ws.cells.append(new_code_cell( input='a = 10\nb = 5\n', prompt_number=3, )) ws.cells.append(new_code_cell( input='a = 10\nb = 5', prompt_number=4, )) ws.cells.append(new_code_cell( input=u'print "ünîcødé"', prompt_number=3, collapsed=False, outputs=[new_output( output_type=u'pyout', output_text=u'', output_html=u'The HTML rep', output_latex=u'$a$', output_png=png, output_jpeg=jpeg, output_svg=u'', output_json=u'{"json": "data"}', output_javascript=u'var i=0;', prompt_number=3 ),new_output( output_type=u'display_data', output_text=u'', output_html=u'The HTML rep', output_latex=u'$a$', output_png=png, output_jpeg=jpeg, output_svg=u'', output_json=u'{"json": "data"}', output_javascript=u'var i=0;' ),new_output( output_type=u'pyerr', ename=u'NameError', evalue=u'NameError was here', traceback=[u'frame 0', u'frame 1', u'frame 2'] ),new_output( output_type=u'stream', output_text='foo\rbar\r\n' ),new_output( output_type=u'stream', stream='stderr', output_text='\rfoo\rbar\n' )] )) authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com', affiliation=u'Fox',url=u'http://www.fox.com')] md = new_metadata(name=u'My Notebook',license=u'BSD',created=u'8601_goes_here', modified=u'8601_goes_here',gistid=u'21341231',authors=authors) nb0 = new_notebook( worksheets=[ws, new_worksheet()], metadata=md ) nb0_py = u"""# -*- coding: utf-8 -*- # %i.%i # # Some NumPy Examples # import numpy # # A random array # # A random array # # My Heading # a = numpy.random.rand(100) # a = 10 b = 5 # a = 10 b = 5 # print "ünîcødé" """ % (nbformat, nbformat_minor) �����������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/tests/test_json.py�������������������������������������������������������0000664�0000000�0000000�00000006461�13612140577�0021231�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import copy import json from unittest import TestCase from ..._compat import decodebytes from ..nbjson import reads, writes from ..nbbase import from_dict from .. import nbjson from .nbexamples import nb0 from . import formattest from .nbexamples import nb0 class TestJSON(formattest.NBFormatTest, TestCase): nb0_ref = None ext = 'ipynb' mod = nbjson def test_roundtrip_nosplit(self): """Ensure that multiline blobs are still readable""" # ensures that notebooks written prior to splitlines change # are still readable. s = writes(nb0, split_lines=False) self.assertEqual(nbjson.reads(s),nb0) def test_roundtrip_split(self): """Ensure that splitting multiline blocks is safe""" # This won't differ from test_roundtrip unless the default changes s = writes(nb0, split_lines=True) self.assertEqual(nbjson.reads(s),nb0) def test_strip_transient(self): """transient values aren't written to files""" nb = copy.deepcopy(nb0) nb.orig_nbformat = 2 nb.orig_nbformat_minor = 3 nb.worksheets[0].cells[0].metadata.trusted = False nbs = nbjson.writes(nb) nb2 = from_dict(json.loads(nbs)) self.assertNotIn('orig_nbformat', nb2) self.assertNotIn('orig_nbformat_minor', nb2) for cell in nb2.worksheets[0].cells: self.assertNotIn('trusted', cell.metadata) def test_to_json(self): """to_notebook_json doesn't strip transient""" nb = copy.deepcopy(nb0) nb.orig_nbformat = 2 nb.orig_nbformat_minor = 3 nb.worksheets[0].cells[0].metadata.trusted = False nbs = json.dumps(nb) nb2 = nbjson.to_notebook(json.loads(nbs)) nb2 = from_dict(json.loads(nbs)) self.assertIn('orig_nbformat', nb2) self.assertIn('orig_nbformat_minor', nb2) cell = nb2.worksheets[0].cells[0] self.assertIn('trusted', cell.metadata) def test_read_png(self): """PNG output data is b64 unicode""" s = writes(nb0) nb1 = nbjson.reads(s) found_png = False for cell in nb1.worksheets[0].cells: if not 'outputs' in cell: continue for output in cell.outputs: if 'png' in output: found_png = True pngdata = output['png'] self.assertEqual(type(pngdata), str) # test that it is valid b64 data b64bytes = pngdata.encode('ascii') raw_bytes = decodebytes(b64bytes) assert found_png, "never found png output" def test_read_jpeg(self): """JPEG output data is b64 unicode""" s = writes(nb0) nb1 = nbjson.reads(s) found_jpeg = False for cell in nb1.worksheets[0].cells: if not 'outputs' in cell: continue for output in cell.outputs: if 'jpeg' in output: found_jpeg = True jpegdata = output['jpeg'] self.assertEqual(type(jpegdata), str) # test that it is valid b64 data b64bytes = jpegdata.encode('ascii') raw_bytes = decodebytes(b64bytes) assert found_jpeg, "never found jpeg output" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/tests/test_misc.py�������������������������������������������������������0000664�0000000�0000000�00000002136�13612140577�0021206�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os from unittest import TestCase from .. import parse_filename class MiscTests(TestCase): def check_filename(self, path, exp_fname, exp_bname, exp_format): fname, bname, format = parse_filename(path) self.assertEqual(fname, exp_fname) self.assertEqual(bname, exp_bname) self.assertEqual(format, exp_format) def test_parse_filename(self): # check format detection self.check_filename("test.ipynb", "test.ipynb", "test", "json") self.check_filename("test.json", "test.json", "test", "json") self.check_filename("test.py", "test.py", "test", "py") # check parsing an unknown format self.check_filename("test.nb", "test.nb.ipynb", "test.nb", "json") # check parsing a full file path abs_path = os.path.abspath("test.ipynb") basename, ext = os.path.splitext(abs_path) self.check_filename(abs_path, abs_path, basename, "json") # check parsing a file name containing dots self.check_filename("test.nb.ipynb", "test.nb.ipynb", "test.nb", "json") ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/tests/test_nbbase.py�����������������������������������������������������0000664�0000000�0000000�00000012433�13612140577�0021506�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from unittest import TestCase from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output, new_author, new_metadata, new_heading_cell, nbformat ) class TestCell(TestCase): def test_empty_code_cell(self): cc = new_code_cell() self.assertEqual(cc.cell_type,u'code') self.assertEqual(u'input' not in cc, True) self.assertEqual(u'prompt_number' not in cc, True) self.assertEqual(cc.outputs, []) self.assertEqual(cc.collapsed, False) def test_code_cell(self): cc = new_code_cell(input='a=10', prompt_number=0, collapsed=True) cc.outputs = [new_output(output_type=u'pyout', output_svg=u'foo',output_text=u'10',prompt_number=0)] self.assertEqual(cc.input, u'a=10') self.assertEqual(cc.prompt_number, 0) self.assertEqual(cc.language, u'python') self.assertEqual(cc.outputs[0].svg, u'foo') self.assertEqual(cc.outputs[0].text, u'10') self.assertEqual(cc.outputs[0].prompt_number, 0) self.assertEqual(cc.collapsed, True) def test_pyerr(self): o = new_output(output_type=u'pyerr', ename=u'NameError', evalue=u'Name not found', traceback=[u'frame 0', u'frame 1', u'frame 2'] ) self.assertEqual(o.output_type, u'pyerr') self.assertEqual(o.ename, u'NameError') self.assertEqual(o.evalue, u'Name not found') self.assertEqual(o.traceback, [u'frame 0', u'frame 1', u'frame 2']) def test_empty_html_cell(self): tc = new_text_cell(u'html') self.assertEqual(tc.cell_type, u'html') self.assertEqual(u'source' not in tc, True) def test_html_cell(self): tc = new_text_cell(u'html', 'hi') self.assertEqual(tc.source, u'hi') def test_empty_markdown_cell(self): tc = new_text_cell(u'markdown') self.assertEqual(tc.cell_type, u'markdown') self.assertEqual(u'source' not in tc, True) def test_markdown_cell(self): tc = new_text_cell(u'markdown', 'hi') self.assertEqual(tc.source, u'hi') def test_empty_raw_cell(self): tc = new_text_cell(u'raw') self.assertEqual(tc.cell_type, u'raw') self.assertEqual(u'source' not in tc, True) def test_raw_cell(self): tc = new_text_cell(u'raw', 'hi') self.assertEqual(tc.source, u'hi') def test_empty_heading_cell(self): tc = new_heading_cell() self.assertEqual(tc.cell_type, u'heading') self.assertEqual(u'source' not in tc, True) def test_heading_cell(self): tc = new_heading_cell(u'hi', level=2) self.assertEqual(tc.source, u'hi') self.assertEqual(tc.level, 2) class TestWorksheet(TestCase): def test_empty_worksheet(self): ws = new_worksheet() self.assertEqual(ws.cells,[]) self.assertEqual(u'name' not in ws, True) def test_worksheet(self): cells = [new_code_cell(), new_text_cell(u'html')] ws = new_worksheet(cells=cells) self.assertEqual(ws.cells,cells) class TestNotebook(TestCase): def test_empty_notebook(self): nb = new_notebook() self.assertEqual(nb.worksheets, []) self.assertEqual(nb.metadata, NotebookNode()) self.assertEqual(nb.nbformat,nbformat) def test_notebook(self): worksheets = [new_worksheet(),new_worksheet()] metadata = new_metadata(name=u'foo') nb = new_notebook(metadata=metadata,worksheets=worksheets) self.assertEqual(nb.metadata.name,u'foo') self.assertEqual(nb.worksheets,worksheets) self.assertEqual(nb.nbformat,nbformat) def test_notebook_name(self): worksheets = [new_worksheet(),new_worksheet()] nb = new_notebook(name='foo',worksheets=worksheets) self.assertEqual(nb.metadata.name,u'foo') self.assertEqual(nb.worksheets,worksheets) self.assertEqual(nb.nbformat,nbformat) class TestMetadata(TestCase): def test_empty_metadata(self): md = new_metadata() self.assertEqual(u'name' not in md, True) self.assertEqual(u'authors' not in md, True) self.assertEqual(u'license' not in md, True) self.assertEqual(u'saved' not in md, True) self.assertEqual(u'modified' not in md, True) self.assertEqual(u'gistid' not in md, True) def test_metadata(self): authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com')] md = new_metadata(name=u'foo',license=u'BSD',created=u'today', modified=u'now',gistid=u'21341231',authors=authors) self.assertEqual(md.name, u'foo') self.assertEqual(md.license, u'BSD') self.assertEqual(md.created, u'today') self.assertEqual(md.modified, u'now') self.assertEqual(md.gistid, u'21341231') self.assertEqual(md.authors, authors) class TestOutputs(TestCase): def test_binary_png(self): out = new_output(output_png=b'\x89PNG\r\n\x1a\n', output_type='display_data') def test_b64b6tes_png(self): out = new_output(output_png=b'iVBORw0KG', output_type='display_data') def test_binary_jpeg(self): out = new_output(output_jpeg=b'\xff\xd8', output_type='display_data') def test_b64b6tes_jpeg(self): out = new_output(output_jpeg=b'/9', output_type='display_data') �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v3/tests/test_nbpy.py�������������������������������������������������������0000664�0000000�0000000�00000002743�13612140577�0021227�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf8 -*- from unittest import TestCase from ipython_genutils.py3compat import string_types, iteritems from . import formattest from .. import nbpy from .nbexamples import nb0, nb0_py class TestPy(formattest.NBFormatTest, TestCase): nb0_ref = nb0_py ext = 'py' mod = nbpy ignored_keys = ['collapsed', 'outputs', 'prompt_number', 'metadata'] def assertSubset(self, da, db): """assert that da is a subset of db, ignoring self.ignored_keys. Called recursively on containers, ultimately comparing individual elements. """ if isinstance(da, dict): for k,v in iteritems(da): if k in self.ignored_keys: continue self.assertTrue(k in db) self.assertSubset(v, db[k]) elif isinstance(da, list): for a,b in zip(da, db): self.assertSubset(a,b) else: if isinstance(da, string_types) and isinstance(db, string_types): # pyfile is not sensitive to preserving leading/trailing # newlines in blocks through roundtrip da = da.strip('\n') db = db.strip('\n') self.assertEqual(da, db) return True def assertNBEquals(self, nba, nbb): # since roundtrip is lossy, only compare keys that are preserved # assumes nba is read from my file format return self.assertSubset(nba, nbb) �����������������������������nbformat-5.0.4/nbformat/v4/�������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13612140577�0015477�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/__init__.py��������������������������������������������������������������0000664�0000000�0000000�00000001306�13612140577�0017610�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""The main API for the v4 notebook format.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. __all__ = ['nbformat', 'nbformat_minor', 'nbformat_schema', 'new_code_cell', 'new_markdown_cell', 'new_notebook', 'new_output', 'output_from_msg', 'reads', 'writes', 'to_notebook', 'downgrade', 'upgrade'] from .nbbase import ( nbformat, nbformat_minor, nbformat_schema, new_code_cell, new_markdown_cell, new_raw_cell, new_notebook, new_output, output_from_msg, ) from .nbjson import reads, writes, to_notebook reads_json = reads writes_json = writes to_notebook_json = to_notebook from .convert import downgrade, upgrade ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/convert.py���������������������������������������������������������������0000664�0000000�0000000�00000020665�13612140577�0017542�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Code for converting notebooks to and from v3.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import json import re from .nbbase import ( nbformat, nbformat_minor, NotebookNode, ) from nbformat import v3 from traitlets.log import get_logger def _warn_if_invalid(nb, version): """Log validation errors, if there are any.""" from nbformat import validate, ValidationError try: validate(nb, version=version) except ValidationError as e: get_logger().error("Notebook JSON is not valid v%i: %s", version, e) def upgrade(nb, from_version=3, from_minor=0): """Convert a notebook to v4. Parameters ---------- nb : NotebookNode The Python representation of the notebook to convert. from_version : int The original version of the notebook to convert. from_minor : int The original minor version of the notebook to convert (only relevant for v >= 3). """ if from_version == 3: # Validate the notebook before conversion _warn_if_invalid(nb, from_version) # Mark the original nbformat so consumers know it has been converted orig_nbformat = nb.pop('orig_nbformat', None) orig_nbformat_minor = nb.pop('orig_nbformat_minor', None) nb.metadata.orig_nbformat = orig_nbformat or 3 nb.metadata.orig_nbformat_minor = orig_nbformat_minor or 0 # Mark the new format nb.nbformat = nbformat nb.nbformat_minor = nbformat_minor # remove worksheet(s) nb['cells'] = cells = [] # In the unlikely event of multiple worksheets, # they will be flattened for ws in nb.pop('worksheets', []): # upgrade each cell for cell in ws['cells']: cells.append(upgrade_cell(cell)) # upgrade metadata nb.metadata.pop('name', '') nb.metadata.pop('signature', '') # Validate the converted notebook before returning it _warn_if_invalid(nb, nbformat) return nb elif from_version == 4: # nothing to do if from_minor != nbformat_minor: nb.metadata.orig_nbformat_minor = from_minor nb.nbformat_minor = nbformat_minor return nb else: raise ValueError('Cannot convert a notebook directly from v%s to v4. ' \ 'Try using the nbformat.convert module.' % from_version) def upgrade_cell(cell): """upgrade a cell from v3 to v4 heading cell: - -> markdown heading code cell: - remove language metadata - cell.input -> cell.source - cell.prompt_number -> cell.execution_count - update outputs """ cell.setdefault('metadata', NotebookNode()) if cell.cell_type == 'code': cell.pop('language', '') if 'collapsed' in cell: cell.metadata['collapsed'] = cell.pop('collapsed') cell.source = cell.pop('input', '') cell.execution_count = cell.pop('prompt_number', None) cell.outputs = upgrade_outputs(cell.outputs) elif cell.cell_type == 'heading': cell.cell_type = 'markdown' level = cell.pop('level', 1) cell.source = u'{hashes} {single_line}'.format( hashes='#' * level, single_line = ' '.join(cell.get('source', '').splitlines()), ) elif cell.cell_type == 'html': # Technically, this exists. It will never happen in practice. cell.cell_type = 'markdown' return cell def downgrade_cell(cell): """downgrade a cell from v4 to v3 code cell: - set cell.language - cell.input <- cell.source - cell.prompt_number <- cell.execution_count - update outputs markdown cell: - single-line heading -> heading cell """ if cell.cell_type == 'code': cell.language = 'python' cell.input = cell.pop('source', '') cell.prompt_number = cell.pop('execution_count', None) cell.collapsed = cell.metadata.pop('collapsed', False) cell.outputs = downgrade_outputs(cell.outputs) elif cell.cell_type == 'markdown': source = cell.get('source', '') if '\n' not in source and source.startswith('#'): prefix, text = re.match(r'(#+)\s*(.*)', source).groups() cell.cell_type = 'heading' cell.source = text cell.level = len(prefix) cell.pop('attachments', None) return cell _mime_map = { "text" : "text/plain", "html" : "text/html", "svg" : "image/svg+xml", "png" : "image/png", "jpeg" : "image/jpeg", "latex" : "text/latex", "json" : "application/json", "javascript" : "application/javascript", }; def to_mime_key(d): """convert dict with v3 aliases to plain mime-type keys""" for alias, mime in _mime_map.items(): if alias in d: d[mime] = d.pop(alias) return d def from_mime_key(d): """convert dict with mime-type keys to v3 aliases""" d2 = {} for alias, mime in _mime_map.items(): if mime in d: d2[alias] = d[mime] return d2 def upgrade_output(output): """upgrade a single code cell output from v3 to v4 - pyout -> execute_result - pyerr -> error - output.type -> output.data.mime/type - mime-type keys - stream.stream -> stream.name """ if output['output_type'] in {'pyout', 'display_data'}: output.setdefault('metadata', NotebookNode()) if output['output_type'] == 'pyout': output['output_type'] = 'execute_result' output['execution_count'] = output.pop('prompt_number', None) # move output data into data sub-dict data = {} for key in list(output): if key in {'output_type', 'execution_count', 'metadata'}: continue data[key] = output.pop(key) to_mime_key(data) output['data'] = data to_mime_key(output.metadata) if 'application/json' in data: data['application/json'] = json.loads(data['application/json']) # promote ascii bytes (from v2) to unicode for key in ('image/png', 'image/jpeg'): if key in data and isinstance(data[key], bytes): data[key] = data[key].decode('ascii') elif output['output_type'] == 'pyerr': output['output_type'] = 'error' elif output['output_type'] == 'stream': output['name'] = output.pop('stream', 'stdout') return output def downgrade_output(output): """downgrade a single code cell output to v3 from v4 - pyout <- execute_result - pyerr <- error - output.data.mime/type -> output.type - un-mime-type keys - stream.stream <- stream.name """ if output['output_type'] in {'execute_result', 'display_data'}: if output['output_type'] == 'execute_result': output['output_type'] = 'pyout' output['prompt_number'] = output.pop('execution_count', None) # promote data dict to top-level output namespace data = output.pop('data', {}) if 'application/json' in data: data['application/json'] = json.dumps(data['application/json']) data = from_mime_key(data) output.update(data) from_mime_key(output.get('metadata', {})) elif output['output_type'] == 'error': output['output_type'] = 'pyerr' elif output['output_type'] == 'stream': output['stream'] = output.pop('name') return output def upgrade_outputs(outputs): """upgrade outputs of a code cell from v3 to v4""" return [upgrade_output(op) for op in outputs] def downgrade_outputs(outputs): """downgrade outputs of a code cell to v3 from v4""" return [downgrade_output(op) for op in outputs] def downgrade(nb): """Convert a v4 notebook to v3. Parameters ---------- nb : NotebookNode The Python representation of the notebook to convert. """ if nb.nbformat != nbformat: return nb # Validate the notebook before conversion _warn_if_invalid(nb, nbformat) nb.nbformat = v3.nbformat nb.nbformat_minor = v3.nbformat_minor cells = [ downgrade_cell(cell) for cell in nb.pop('cells') ] nb.worksheets = [v3.new_worksheet(cells=cells)] nb.metadata.setdefault('name', '') # Validate the converted notebook before returning it _warn_if_invalid(nb, v3.nbformat) nb.orig_nbformat = nb.metadata.pop('orig_nbformat', nbformat) nb.orig_nbformat_minor = nb.metadata.pop('orig_nbformat_minor', nbformat_minor) return nb ���������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/nbbase.py����������������������������������������������������������������0000664�0000000�0000000�00000010275�13612140577�0017310�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Python API for composing notebook elements The Python representation of a notebook is a nested structure of dictionary subclasses that support attribute access (ipython_genutils.ipstruct.Struct). The functions in this module are merely helpers to build the structs in the right form. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from ..notebooknode import NotebookNode # Change the nbformat_minor and nbformat_schema variables when incrementing the # nbformat version # current major version nbformat = 4 # current minor version nbformat_minor = 4 # schema files for (major, minor) version tuples. (None, None) means the current version nbformat_schema = { (None, None): 'nbformat.v4.schema.json', (4, 0): 'nbformat.v4.0.schema.json', (4, 1): 'nbformat.v4.1.schema.json', (4, 2): 'nbformat.v4.2.schema.json', (4, 3): 'nbformat.v4.3.schema.json', (4, 4): 'nbformat.v4.4.schema.json' } def validate(node, ref=None): """validate a v4 node""" from .. import validate return validate(node, ref=ref, version=nbformat) def new_output(output_type, data=None, **kwargs): """Create a new output, to go in the ``cell.outputs`` list of a code cell.""" output = NotebookNode(output_type=output_type) # populate defaults: if output_type == 'stream': output.name = u'stdout' output.text = u'' elif output_type == 'display_data': output.metadata = NotebookNode() output.data = NotebookNode() elif output_type == 'execute_result': output.metadata = NotebookNode() output.data = NotebookNode() output.execution_count = None elif output_type == 'error': output.ename = "NotImplementedError" output.evalue = "" output.traceback = [] # load from args: output.update(kwargs) if data is not None: output.data = data # validate validate(output, output_type) return output def output_from_msg(msg): """Create a NotebookNode for an output from a kernel's IOPub message. Returns ------- NotebookNode: the output as a notebook node. Raises ------ ValueError: if the message is not an output message. """ msg_type = msg['header']['msg_type'] content = msg['content'] if msg_type == 'execute_result': return new_output(output_type=msg_type, metadata=content['metadata'], data=content['data'], execution_count=content['execution_count'], ) elif msg_type == 'stream': return new_output(output_type=msg_type, name=content['name'], text=content['text'], ) elif msg_type == 'display_data': return new_output(output_type=msg_type, metadata=content['metadata'], data=content['data'], ) elif msg_type == 'error': return new_output(output_type=msg_type, ename=content['ename'], evalue=content['evalue'], traceback=content['traceback'], ) else: raise ValueError("Unrecognized output msg type: %r" % msg_type) def new_code_cell(source='', **kwargs): """Create a new code cell""" cell = NotebookNode( cell_type='code', metadata=NotebookNode(), execution_count=None, source=source, outputs=[], ) cell.update(kwargs) validate(cell, 'code_cell') return cell def new_markdown_cell(source='', **kwargs): """Create a new markdown cell""" cell = NotebookNode( cell_type='markdown', source=source, metadata=NotebookNode(), ) cell.update(kwargs) validate(cell, 'markdown_cell') return cell def new_raw_cell(source='', **kwargs): """Create a new raw cell""" cell = NotebookNode( cell_type='raw', source=source, metadata=NotebookNode(), ) cell.update(kwargs) validate(cell, 'raw_cell') return cell def new_notebook(**kwargs): """Create a new notebook""" nb = NotebookNode( nbformat=nbformat, nbformat_minor=nbformat_minor, metadata=NotebookNode(), cells=[], ) nb.update(kwargs) validate(nb) return nb �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/nbformat.v4.0.schema.json������������������������������������������������0000664�0000000�0000000�00000034521�13612140577�0022134�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "$schema": "http://json-schema.org/draft-04/schema#", "description": "IPython Notebook v4.0 JSON schema.", "type": "object", "additionalProperties": false, "required": ["metadata", "nbformat_minor", "nbformat", "cells"], "properties": { "metadata": { "description": "Notebook root-level metadata.", "type": "object", "additionalProperties": true, "properties": { "kernelspec": { "description": "Kernel information.", "type": "object", "required": ["name", "display_name"], "properties": { "name": { "description": "Name of the kernel specification.", "type": "string" }, "display_name": { "description": "Name to display in UI.", "type": "string" } } }, "language_info": { "description": "Kernel information.", "type": "object", "required": ["name"], "properties": { "name": { "description": "The programming language which this kernel runs.", "type": "string" }, "codemirror_mode": { "description": "The codemirror mode to use for code in this language.", "oneOf": [ {"type": "string"}, {"type": "object"} ] }, "file_extension": { "description": "The file extension for files in this language.", "type": "string" }, "mimetype": { "description": "The mimetype corresponding to files in this language.", "type": "string" }, "pygments_lexer": { "description": "The pygments lexer to use for code in this language.", "type": "string" } } }, "orig_nbformat": { "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.", "type": "integer", "minimum": 1 } } }, "nbformat_minor": { "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.", "type": "integer", "minimum": 0 }, "nbformat": { "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.", "type": "integer", "minimum": 4, "maximum": 4 }, "cells": { "description": "Array of cells of the current notebook.", "type": "array", "items": {"$ref": "#/definitions/cell"} } }, "definitions": { "cell": { "type": "object", "oneOf": [ {"$ref": "#/definitions/raw_cell"}, {"$ref": "#/definitions/markdown_cell"}, {"$ref": "#/definitions/code_cell"} ] }, "raw_cell": { "description": "Notebook raw nbconvert cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["raw"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "format": { "description": "Raw cell metadata format for nbconvert.", "type": "string" }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "source": {"$ref": "#/definitions/misc/source"} } }, "markdown_cell": { "description": "Notebook markdown cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["markdown"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true }, "source": {"$ref": "#/definitions/misc/source"} } }, "code_cell": { "description": "Notebook code cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source", "outputs", "execution_count"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["code"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "collapsed": { "description": "Whether the cell is collapsed/expanded.", "type": "boolean" }, "scrolled": { "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.", "enum": [true, false, "auto"] }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "source": {"$ref": "#/definitions/misc/source"}, "outputs": { "description": "Execution, display, or stream outputs.", "type": "array", "items": {"$ref": "#/definitions/output"} }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 } } }, "unrecognized_cell": { "description": "Unrecognized cell from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["cell_type", "metadata"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "not" : { "enum": ["markdown", "code", "raw"] } }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true } } }, "output": { "type": "object", "oneOf": [ {"$ref": "#/definitions/execute_result"}, {"$ref": "#/definitions/display_data"}, {"$ref": "#/definitions/stream"}, {"$ref": "#/definitions/error"} ] }, "execute_result": { "description": "Result of executing a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata", "execution_count"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["execute_result"] }, "execution_count": { "description": "A result's prompt number.", "type": ["integer", "null"], "minimum": 0 }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "display_data": { "description": "Data displayed as a result of code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["display_data"] }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "stream": { "description": "Stream output from a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "name", "text"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["stream"] }, "name": { "description": "The name of the stream (stdout, stderr).", "type": "string" }, "text": { "description": "The stream's text output, represented as an array of strings.", "$ref": "#/definitions/misc/multiline_string" } } }, "error": { "description": "Output of an error that occurred during code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "ename", "evalue", "traceback"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["error"] }, "ename": { "description": "The name of the error.", "type": "string" }, "evalue": { "description": "The value, or message, of the error.", "type": "string" }, "traceback": { "description": "The error's traceback, represented as an array of strings.", "type": "array", "items": {"type": "string"} } } }, "unrecognized_output": { "description": "Unrecognized output from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["output_type"], "properties": { "output_type": { "description": "Type of cell output.", "not": { "enum": ["execute_result", "display_data", "stream", "error"] } } } }, "misc": { "metadata_name": { "description": "The cell's name. If present, must be a non-empty string.", "type": "string", "pattern": "^.+$" }, "metadata_tags": { "description": "The cell's tags. Tags must be unique, and must not contain commas.", "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^[^,]+$" } }, "source": { "description": "Contents of the cell, represented as an array of lines.", "$ref": "#/definitions/misc/multiline_string" }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 }, "mimebundle": { "description": "A mime-type keyed dictionary of data", "type": "object", "additionalProperties": false, "properties": { "application/json": { "type": "object" } }, "patternProperties": { "^(?!application/json$)[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": { "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" } } }, "output_metadata": { "description": "Cell output metadata.", "type": "object", "additionalProperties": true }, "multiline_string": { "oneOf" : [ {"type": "string"}, { "type": "array", "items": {"type": "string"} } ] } } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/nbformat.v4.1.schema.json������������������������������������������������0000664�0000000�0000000�00000035652�13612140577�0022143�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "$schema": "http://json-schema.org/draft-04/schema#", "description": "IPython Notebook v4.1 JSON schema.", "type": "object", "additionalProperties": false, "required": ["metadata", "nbformat_minor", "nbformat", "cells"], "properties": { "metadata": { "description": "Notebook root-level metadata.", "type": "object", "additionalProperties": true, "properties": { "kernelspec": { "description": "Kernel information.", "type": "object", "required": ["name", "display_name"], "properties": { "name": { "description": "Name of the kernel specification.", "type": "string" }, "display_name": { "description": "Name to display in UI.", "type": "string" } } }, "language_info": { "description": "Kernel information.", "type": "object", "required": ["name"], "properties": { "name": { "description": "The programming language which this kernel runs.", "type": "string" }, "codemirror_mode": { "description": "The codemirror mode to use for code in this language.", "oneOf": [ {"type": "string"}, {"type": "object"} ] }, "file_extension": { "description": "The file extension for files in this language.", "type": "string" }, "mimetype": { "description": "The mimetype corresponding to files in this language.", "type": "string" }, "pygments_lexer": { "description": "The pygments lexer to use for code in this language.", "type": "string" } } }, "orig_nbformat": { "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.", "type": "integer", "minimum": 1 } } }, "nbformat_minor": { "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.", "type": "integer", "minimum": 1 }, "nbformat": { "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.", "type": "integer", "minimum": 4, "maximum": 4 }, "cells": { "description": "Array of cells of the current notebook.", "type": "array", "items": {"$ref": "#/definitions/cell"} } }, "definitions": { "cell": { "type": "object", "oneOf": [ {"$ref": "#/definitions/raw_cell"}, {"$ref": "#/definitions/markdown_cell"}, {"$ref": "#/definitions/code_cell"} ] }, "raw_cell": { "description": "Notebook raw nbconvert cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["raw"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "format": { "description": "Raw cell metadata format for nbconvert.", "type": "string" }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "markdown_cell": { "description": "Notebook markdown cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["markdown"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "code_cell": { "description": "Notebook code cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source", "outputs", "execution_count"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["code"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "collapsed": { "description": "Whether the cell is collapsed/expanded.", "type": "boolean" }, "scrolled": { "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.", "enum": [true, false, "auto"] }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "source": {"$ref": "#/definitions/misc/source"}, "outputs": { "description": "Execution, display, or stream outputs.", "type": "array", "items": {"$ref": "#/definitions/output"} }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 } } }, "unrecognized_cell": { "description": "Unrecognized cell from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["cell_type", "metadata"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "not" : { "enum": ["markdown", "code", "raw"] } }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true } } }, "output": { "type": "object", "oneOf": [ {"$ref": "#/definitions/execute_result"}, {"$ref": "#/definitions/display_data"}, {"$ref": "#/definitions/stream"}, {"$ref": "#/definitions/error"} ] }, "execute_result": { "description": "Result of executing a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata", "execution_count"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["execute_result"] }, "execution_count": { "description": "A result's prompt number.", "type": ["integer", "null"], "minimum": 0 }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "display_data": { "description": "Data displayed as a result of code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["display_data"] }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "stream": { "description": "Stream output from a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "name", "text"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["stream"] }, "name": { "description": "The name of the stream (stdout, stderr).", "type": "string" }, "text": { "description": "The stream's text output, represented as an array of strings.", "$ref": "#/definitions/misc/multiline_string" } } }, "error": { "description": "Output of an error that occurred during code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "ename", "evalue", "traceback"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["error"] }, "ename": { "description": "The name of the error.", "type": "string" }, "evalue": { "description": "The value, or message, of the error.", "type": "string" }, "traceback": { "description": "The error's traceback, represented as an array of strings.", "type": "array", "items": {"type": "string"} } } }, "unrecognized_output": { "description": "Unrecognized output from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["output_type"], "properties": { "output_type": { "description": "Type of cell output.", "not": { "enum": ["execute_result", "display_data", "stream", "error"] } } } }, "misc": { "metadata_name": { "description": "The cell's name. If present, must be a non-empty string.", "type": "string", "pattern": "^.+$" }, "metadata_tags": { "description": "The cell's tags. Tags must be unique, and must not contain commas.", "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^[^,]+$" } }, "attachments": { "description": "Media attachments (e.g. inline images), stored as mimebundle keyed by filename.", "type": "object", "patternProperties": { ".*": { "description": "The attachment's data stored as a mimebundle.", "$ref": "#/definitions/misc/mimebundle" } } }, "source": { "description": "Contents of the cell, represented as an array of lines.", "$ref": "#/definitions/misc/multiline_string" }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 }, "mimebundle": { "description": "A mime-type keyed dictionary of data", "type": "object", "additionalProperties": false, "properties": { "application/json": { "type": "object" } }, "patternProperties": { "^(?!application/json$)[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": { "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" } } }, "output_metadata": { "description": "Cell output metadata.", "type": "object", "additionalProperties": true }, "multiline_string": { "oneOf" : [ {"type": "string"}, { "type": "array", "items": {"type": "string"} } ] } } } } ��������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/nbformat.v4.2.schema.json������������������������������������������������0000664�0000000�0000000�00000036742�13612140577�0022145�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "$schema": "http://json-schema.org/draft-04/schema#", "description": "Jupyter Notebook v4.2 JSON schema.", "type": "object", "additionalProperties": false, "required": ["metadata", "nbformat_minor", "nbformat", "cells"], "properties": { "metadata": { "description": "Notebook root-level metadata.", "type": "object", "additionalProperties": true, "properties": { "kernelspec": { "description": "Kernel information.", "type": "object", "required": ["name", "display_name"], "properties": { "name": { "description": "Name of the kernel specification.", "type": "string" }, "display_name": { "description": "Name to display in UI.", "type": "string" } } }, "language_info": { "description": "Kernel information.", "type": "object", "required": ["name"], "properties": { "name": { "description": "The programming language which this kernel runs.", "type": "string" }, "codemirror_mode": { "description": "The codemirror mode to use for code in this language.", "oneOf": [ {"type": "string"}, {"type": "object"} ] }, "file_extension": { "description": "The file extension for files in this language.", "type": "string" }, "mimetype": { "description": "The mimetype corresponding to files in this language.", "type": "string" }, "pygments_lexer": { "description": "The pygments lexer to use for code in this language.", "type": "string" } } }, "orig_nbformat": { "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.", "type": "integer", "minimum": 1 }, "title": { "description": "The title of the notebook document", "type": "string" }, "authors": { "description": "The author(s) of the notebook document", "type": "array", "item": { "type": "object", "properties": { "name": { "type": "string" } }, "additionalProperties": true } } } }, "nbformat_minor": { "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.", "type": "integer", "minimum": 2 }, "nbformat": { "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.", "type": "integer", "minimum": 4, "maximum": 4 }, "cells": { "description": "Array of cells of the current notebook.", "type": "array", "items": {"$ref": "#/definitions/cell"} } }, "definitions": { "cell": { "type": "object", "oneOf": [ {"$ref": "#/definitions/raw_cell"}, {"$ref": "#/definitions/markdown_cell"}, {"$ref": "#/definitions/code_cell"} ] }, "raw_cell": { "description": "Notebook raw nbconvert cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["raw"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "format": { "description": "Raw cell metadata format for nbconvert.", "type": "string" }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "markdown_cell": { "description": "Notebook markdown cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["markdown"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "code_cell": { "description": "Notebook code cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source", "outputs", "execution_count"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["code"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "collapsed": { "description": "Whether the cell is collapsed/expanded.", "type": "boolean" }, "scrolled": { "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.", "enum": [true, false, "auto"] }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "source": {"$ref": "#/definitions/misc/source"}, "outputs": { "description": "Execution, display, or stream outputs.", "type": "array", "items": {"$ref": "#/definitions/output"} }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 } } }, "unrecognized_cell": { "description": "Unrecognized cell from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["cell_type", "metadata"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "not" : { "enum": ["markdown", "code", "raw"] } }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true } } }, "output": { "type": "object", "oneOf": [ {"$ref": "#/definitions/execute_result"}, {"$ref": "#/definitions/display_data"}, {"$ref": "#/definitions/stream"}, {"$ref": "#/definitions/error"} ] }, "execute_result": { "description": "Result of executing a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata", "execution_count"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["execute_result"] }, "execution_count": { "description": "A result's prompt number.", "type": ["integer", "null"], "minimum": 0 }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "display_data": { "description": "Data displayed as a result of code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["display_data"] }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "stream": { "description": "Stream output from a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "name", "text"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["stream"] }, "name": { "description": "The name of the stream (stdout, stderr).", "type": "string" }, "text": { "description": "The stream's text output, represented as an array of strings.", "$ref": "#/definitions/misc/multiline_string" } } }, "error": { "description": "Output of an error that occurred during code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "ename", "evalue", "traceback"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["error"] }, "ename": { "description": "The name of the error.", "type": "string" }, "evalue": { "description": "The value, or message, of the error.", "type": "string" }, "traceback": { "description": "The error's traceback, represented as an array of strings.", "type": "array", "items": {"type": "string"} } } }, "unrecognized_output": { "description": "Unrecognized output from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["output_type"], "properties": { "output_type": { "description": "Type of cell output.", "not": { "enum": ["execute_result", "display_data", "stream", "error"] } } } }, "misc": { "metadata_name": { "description": "The cell's name. If present, must be a non-empty string. Must be unique across all the cells of a given notebook.", "type": "string", "pattern": "^.+$" }, "metadata_tags": { "description": "The cell's tags. Tags must be unique, and must not contain commas.", "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^[^,]+$" } }, "attachments": { "description": "Media attachments (e.g. inline images), stored as mimebundle keyed by filename.", "type": "object", "patternProperties": { ".*": { "description": "The attachment's data stored as a mimebundle.", "$ref": "#/definitions/misc/mimebundle" } } }, "source": { "description": "Contents of the cell, represented as an array of lines.", "$ref": "#/definitions/misc/multiline_string" }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 }, "mimebundle": { "description": "A mime-type keyed dictionary of data", "type": "object", "additionalProperties": { "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" }, "patternProperties": { "^application/(.*\\+)?json$": { "description": "Mimetypes with JSON output, can be any type" } } }, "output_metadata": { "description": "Cell output metadata.", "type": "object", "additionalProperties": true }, "multiline_string": { "oneOf" : [ {"type": "string"}, { "type": "array", "items": {"type": "string"} } ] } } } } ������������������������������nbformat-5.0.4/nbformat/v4/nbformat.v4.3.schema.json������������������������������������������������0000664�0000000�0000000�00000042020�13612140577�0022130�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "$schema": "http://json-schema.org/draft-04/schema#", "description": "Jupyter Notebook v4.3 JSON schema.", "type": "object", "additionalProperties": false, "required": ["metadata", "nbformat_minor", "nbformat", "cells"], "properties": { "metadata": { "description": "Notebook root-level metadata.", "type": "object", "additionalProperties": true, "properties": { "kernelspec": { "description": "Kernel information.", "type": "object", "required": ["name", "display_name"], "properties": { "name": { "description": "Name of the kernel specification.", "type": "string" }, "display_name": { "description": "Name to display in UI.", "type": "string" } } }, "language_info": { "description": "Kernel information.", "type": "object", "required": ["name"], "properties": { "name": { "description": "The programming language which this kernel runs.", "type": "string" }, "codemirror_mode": { "description": "The codemirror mode to use for code in this language.", "oneOf": [ {"type": "string"}, {"type": "object"} ] }, "file_extension": { "description": "The file extension for files in this language.", "type": "string" }, "mimetype": { "description": "The mimetype corresponding to files in this language.", "type": "string" }, "pygments_lexer": { "description": "The pygments lexer to use for code in this language.", "type": "string" } } }, "orig_nbformat": { "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.", "type": "integer", "minimum": 1 }, "title": { "description": "The title of the notebook document", "type": "string" }, "authors": { "description": "The author(s) of the notebook document", "type": "array", "item": { "type": "object", "properties": { "name": { "type": "string" } }, "additionalProperties": true } } } }, "nbformat_minor": { "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.", "type": "integer", "minimum": 3 }, "nbformat": { "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.", "type": "integer", "minimum": 4, "maximum": 4 }, "cells": { "description": "Array of cells of the current notebook.", "type": "array", "items": {"$ref": "#/definitions/cell"} } }, "definitions": { "cell": { "type": "object", "oneOf": [ {"$ref": "#/definitions/raw_cell"}, {"$ref": "#/definitions/markdown_cell"}, {"$ref": "#/definitions/code_cell"} ] }, "raw_cell": { "description": "Notebook raw nbconvert cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["raw"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "format": { "description": "Raw cell metadata format for nbconvert.", "type": "string" }, "jupyter": { "description": "Official Jupyter Metadata for Raw Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" } }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "markdown_cell": { "description": "Notebook markdown cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["markdown"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"}, "jupyter": { "description": "Official Jupyter Metadata for Markdown Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" } } }, "additionalProperties": true }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "code_cell": { "description": "Notebook code cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source", "outputs", "execution_count"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["code"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "jupyter": { "description": "Official Jupyter Metadata for Code Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" }, "outputs_hidden": { "description": "Whether the outputs are hidden.", "type": "boolean" } }, "collapsed": { "description": "Whether the cell is collapsed/expanded.", "type": "boolean" }, "scrolled": { "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.", "enum": [true, false, "auto"] }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "source": {"$ref": "#/definitions/misc/source"}, "outputs": { "description": "Execution, display, or stream outputs.", "type": "array", "items": {"$ref": "#/definitions/output"} }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 } } }, "unrecognized_cell": { "description": "Unrecognized cell from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["cell_type", "metadata"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "not" : { "enum": ["markdown", "code", "raw"] } }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true } } }, "output": { "type": "object", "oneOf": [ {"$ref": "#/definitions/execute_result"}, {"$ref": "#/definitions/display_data"}, {"$ref": "#/definitions/stream"}, {"$ref": "#/definitions/error"} ] }, "execute_result": { "description": "Result of executing a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata", "execution_count"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["execute_result"] }, "execution_count": { "description": "A result's prompt number.", "type": ["integer", "null"], "minimum": 0 }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "display_data": { "description": "Data displayed as a result of code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["display_data"] }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "stream": { "description": "Stream output from a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "name", "text"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["stream"] }, "name": { "description": "The name of the stream (stdout, stderr).", "type": "string" }, "text": { "description": "The stream's text output, represented as an array of strings.", "$ref": "#/definitions/misc/multiline_string" } } }, "error": { "description": "Output of an error that occurred during code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "ename", "evalue", "traceback"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["error"] }, "ename": { "description": "The name of the error.", "type": "string" }, "evalue": { "description": "The value, or message, of the error.", "type": "string" }, "traceback": { "description": "The error's traceback, represented as an array of strings.", "type": "array", "items": {"type": "string"} } } }, "unrecognized_output": { "description": "Unrecognized output from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["output_type"], "properties": { "output_type": { "description": "Type of cell output.", "not": { "enum": ["execute_result", "display_data", "stream", "error"] } } } }, "misc": { "metadata_name": { "description": "The cell's name. If present, must be a non-empty string. Must be unique across all the cells of a given notebook.", "type": "string", "pattern": "^.+$" }, "metadata_tags": { "description": "The cell's tags. Tags must be unique, and must not contain commas.", "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^[^,]+$" } }, "attachments": { "description": "Media attachments (e.g. inline images), stored as mimebundle keyed by filename.", "type": "object", "patternProperties": { ".*": { "description": "The attachment's data stored as a mimebundle.", "$ref": "#/definitions/misc/mimebundle" } } }, "source": { "description": "Contents of the cell, represented as an array of lines.", "$ref": "#/definitions/misc/multiline_string" }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 }, "mimebundle": { "description": "A mime-type keyed dictionary of data", "type": "object", "additionalProperties": { "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" }, "patternProperties": { "^application/(.*\\+)?json$": { "description": "Mimetypes with JSON output, can be any type" } } }, "output_metadata": { "description": "Cell output metadata.", "type": "object", "additionalProperties": true }, "multiline_string": { "oneOf" : [ {"type": "string"}, { "type": "array", "items": {"type": "string"} } ] } } } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/nbformat.v4.4.schema.json������������������������������������������������0000664�0000000�0000000�00000046130�13612140577�0022137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "$schema": "http://json-schema.org/draft-04/schema#", "description": "Jupyter Notebook v4.4 JSON schema.", "type": "object", "additionalProperties": false, "required": ["metadata", "nbformat_minor", "nbformat", "cells"], "properties": { "metadata": { "description": "Notebook root-level metadata.", "type": "object", "additionalProperties": true, "properties": { "kernelspec": { "description": "Kernel information.", "type": "object", "required": ["name", "display_name"], "properties": { "name": { "description": "Name of the kernel specification.", "type": "string" }, "display_name": { "description": "Name to display in UI.", "type": "string" } } }, "language_info": { "description": "Kernel information.", "type": "object", "required": ["name"], "properties": { "name": { "description": "The programming language which this kernel runs.", "type": "string" }, "codemirror_mode": { "description": "The codemirror mode to use for code in this language.", "oneOf": [ {"type": "string"}, {"type": "object"} ] }, "file_extension": { "description": "The file extension for files in this language.", "type": "string" }, "mimetype": { "description": "The mimetype corresponding to files in this language.", "type": "string" }, "pygments_lexer": { "description": "The pygments lexer to use for code in this language.", "type": "string" } } }, "orig_nbformat": { "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.", "type": "integer", "minimum": 1 }, "title": { "description": "The title of the notebook document", "type": "string" }, "authors": { "description": "The author(s) of the notebook document", "type": "array", "item": { "type": "object", "properties": { "name": { "type": "string" } }, "additionalProperties": true } } } }, "nbformat_minor": { "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.", "type": "integer", "minimum": 3 }, "nbformat": { "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.", "type": "integer", "minimum": 4, "maximum": 4 }, "cells": { "description": "Array of cells of the current notebook.", "type": "array", "items": {"$ref": "#/definitions/cell"} } }, "definitions": { "cell": { "type": "object", "oneOf": [ {"$ref": "#/definitions/raw_cell"}, {"$ref": "#/definitions/markdown_cell"}, {"$ref": "#/definitions/code_cell"} ] }, "raw_cell": { "description": "Notebook raw nbconvert cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["raw"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "format": { "description": "Raw cell metadata format for nbconvert.", "type": "string" }, "jupyter": { "description": "Official Jupyter Metadata for Raw Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" } }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "markdown_cell": { "description": "Notebook markdown cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["markdown"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"}, "jupyter": { "description": "Official Jupyter Metadata for Markdown Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" } } }, "additionalProperties": true }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "code_cell": { "description": "Notebook code cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source", "outputs", "execution_count"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["code"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "jupyter": { "description": "Official Jupyter Metadata for Code Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" }, "outputs_hidden": { "description": "Whether the outputs are hidden.", "type": "boolean" } }, "execution": { "description": "Execution time for the code in the cell. This tracks time at which messages are recieved from iopub or shell channels", "type": "object", "properties": { "iopub.execute_input": { "description": "header.date (in ISO 8601 format) of iopub channel's execute_input message. It indicates the time at which the kernel broadcast an execute_input message to connected frontends", "type": "string" }, "iopub.status.busy": { "description": "header.date (in ISO 8601 format) of iopub channel's kernel status message when the status is 'busy'", "type": "string" }, "shell.execute_reply": { "description": "header.date (in ISO 8601 format) of the shell channel's execute_reply message. It indicates the time at which the execute_reply message was created", "type": "string" }, "iopub.status.idle": { "description": "header.date (in ISO 8601 format) of iopub channel's execute_input message. It indicates the time at which kernel finished processing the associated request", "type": "string" } }, "additionalProperties": true, "patternProperties": { "^.*$": { "type": "string" } } }, "collapsed": { "description": "Whether the cell's output is collapsed/expanded.", "type": "boolean" }, "scrolled": { "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.", "enum": [true, false, "auto"] }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "source": {"$ref": "#/definitions/misc/source"}, "outputs": { "description": "Execution, display, or stream outputs.", "type": "array", "items": {"$ref": "#/definitions/output"} }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 } } }, "unrecognized_cell": { "description": "Unrecognized cell from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["cell_type", "metadata"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "not" : { "enum": ["markdown", "code", "raw"] } }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true } } }, "output": { "type": "object", "oneOf": [ {"$ref": "#/definitions/execute_result"}, {"$ref": "#/definitions/display_data"}, {"$ref": "#/definitions/stream"}, {"$ref": "#/definitions/error"} ] }, "execute_result": { "description": "Result of executing a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata", "execution_count"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["execute_result"] }, "execution_count": { "description": "A result's prompt number.", "type": ["integer", "null"], "minimum": 0 }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "display_data": { "description": "Data displayed as a result of code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["display_data"] }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "stream": { "description": "Stream output from a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "name", "text"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["stream"] }, "name": { "description": "The name of the stream (stdout, stderr).", "type": "string" }, "text": { "description": "The stream's text output, represented as an array of strings.", "$ref": "#/definitions/misc/multiline_string" } } }, "error": { "description": "Output of an error that occurred during code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "ename", "evalue", "traceback"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["error"] }, "ename": { "description": "The name of the error.", "type": "string" }, "evalue": { "description": "The value, or message, of the error.", "type": "string" }, "traceback": { "description": "The error's traceback, represented as an array of strings.", "type": "array", "items": {"type": "string"} } } }, "unrecognized_output": { "description": "Unrecognized output from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["output_type"], "properties": { "output_type": { "description": "Type of cell output.", "not": { "enum": ["execute_result", "display_data", "stream", "error"] } } } }, "misc": { "metadata_name": { "description": "The cell's name. If present, must be a non-empty string. Cell names are expected to be unique across all the cells in a given notebook. This criterion cannot be checked by the json schema and must be established by an additional check.", "type": "string", "pattern": "^.+$" }, "metadata_tags": { "description": "The cell's tags. Tags must be unique, and must not contain commas.", "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^[^,]+$" } }, "attachments": { "description": "Media attachments (e.g. inline images), stored as mimebundle keyed by filename.", "type": "object", "patternProperties": { ".*": { "description": "The attachment's data stored as a mimebundle.", "$ref": "#/definitions/misc/mimebundle" } } }, "source": { "description": "Contents of the cell, represented as an array of lines.", "$ref": "#/definitions/misc/multiline_string" }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 }, "mimebundle": { "description": "A mime-type keyed dictionary of data", "type": "object", "additionalProperties": { "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" }, "patternProperties": { "^application/(.*\\+)?json$": { "description": "Mimetypes with JSON output, can be any type" } } }, "output_metadata": { "description": "Cell output metadata.", "type": "object", "additionalProperties": true }, "multiline_string": { "oneOf" : [ {"type": "string"}, { "type": "array", "items": {"type": "string"} } ] } } } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/nbformat.v4.schema.json��������������������������������������������������0000664�0000000�0000000�00000046130�13612140577�0021775�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "$schema": "http://json-schema.org/draft-04/schema#", "description": "Jupyter Notebook v4.4 JSON schema.", "type": "object", "additionalProperties": false, "required": ["metadata", "nbformat_minor", "nbformat", "cells"], "properties": { "metadata": { "description": "Notebook root-level metadata.", "type": "object", "additionalProperties": true, "properties": { "kernelspec": { "description": "Kernel information.", "type": "object", "required": ["name", "display_name"], "properties": { "name": { "description": "Name of the kernel specification.", "type": "string" }, "display_name": { "description": "Name to display in UI.", "type": "string" } } }, "language_info": { "description": "Kernel information.", "type": "object", "required": ["name"], "properties": { "name": { "description": "The programming language which this kernel runs.", "type": "string" }, "codemirror_mode": { "description": "The codemirror mode to use for code in this language.", "oneOf": [ {"type": "string"}, {"type": "object"} ] }, "file_extension": { "description": "The file extension for files in this language.", "type": "string" }, "mimetype": { "description": "The mimetype corresponding to files in this language.", "type": "string" }, "pygments_lexer": { "description": "The pygments lexer to use for code in this language.", "type": "string" } } }, "orig_nbformat": { "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.", "type": "integer", "minimum": 1 }, "title": { "description": "The title of the notebook document", "type": "string" }, "authors": { "description": "The author(s) of the notebook document", "type": "array", "item": { "type": "object", "properties": { "name": { "type": "string" } }, "additionalProperties": true } } } }, "nbformat_minor": { "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.", "type": "integer", "minimum": 3 }, "nbformat": { "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.", "type": "integer", "minimum": 4, "maximum": 4 }, "cells": { "description": "Array of cells of the current notebook.", "type": "array", "items": {"$ref": "#/definitions/cell"} } }, "definitions": { "cell": { "type": "object", "oneOf": [ {"$ref": "#/definitions/raw_cell"}, {"$ref": "#/definitions/markdown_cell"}, {"$ref": "#/definitions/code_cell"} ] }, "raw_cell": { "description": "Notebook raw nbconvert cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["raw"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "format": { "description": "Raw cell metadata format for nbconvert.", "type": "string" }, "jupyter": { "description": "Official Jupyter Metadata for Raw Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" } }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "markdown_cell": { "description": "Notebook markdown cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["markdown"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"}, "jupyter": { "description": "Official Jupyter Metadata for Markdown Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" } } }, "additionalProperties": true }, "attachments": {"$ref": "#/definitions/misc/attachments"}, "source": {"$ref": "#/definitions/misc/source"} } }, "code_cell": { "description": "Notebook code cell.", "type": "object", "additionalProperties": false, "required": ["cell_type", "metadata", "source", "outputs", "execution_count"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "enum": ["code"] }, "metadata": { "description": "Cell-level metadata.", "type": "object", "additionalProperties": true, "properties": { "jupyter": { "description": "Official Jupyter Metadata for Code Cells", "type": "object", "additionalProperties": true, "source_hidden": { "description": "Whether the source is hidden.", "type": "boolean" }, "outputs_hidden": { "description": "Whether the outputs are hidden.", "type": "boolean" } }, "execution": { "description": "Execution time for the code in the cell. This tracks time at which messages are recieved from iopub or shell channels", "type": "object", "properties": { "iopub.execute_input": { "description": "header.date (in ISO 8601 format) of iopub channel's execute_input message. It indicates the time at which the kernel broadcast an execute_input message to connected frontends", "type": "string" }, "iopub.status.busy": { "description": "header.date (in ISO 8601 format) of iopub channel's kernel status message when the status is 'busy'", "type": "string" }, "shell.execute_reply": { "description": "header.date (in ISO 8601 format) of the shell channel's execute_reply message. It indicates the time at which the execute_reply message was created", "type": "string" }, "iopub.status.idle": { "description": "header.date (in ISO 8601 format) of iopub channel's execute_input message. It indicates the time at which kernel finished processing the associated request", "type": "string" } }, "additionalProperties": true, "patternProperties": { "^.*$": { "type": "string" } } }, "collapsed": { "description": "Whether the cell's output is collapsed/expanded.", "type": "boolean" }, "scrolled": { "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.", "enum": [true, false, "auto"] }, "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} } }, "source": {"$ref": "#/definitions/misc/source"}, "outputs": { "description": "Execution, display, or stream outputs.", "type": "array", "items": {"$ref": "#/definitions/output"} }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 } } }, "unrecognized_cell": { "description": "Unrecognized cell from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["cell_type", "metadata"], "properties": { "cell_type": { "description": "String identifying the type of cell.", "not" : { "enum": ["markdown", "code", "raw"] } }, "metadata": { "description": "Cell-level metadata.", "type": "object", "properties": { "name": {"$ref": "#/definitions/misc/metadata_name"}, "tags": {"$ref": "#/definitions/misc/metadata_tags"} }, "additionalProperties": true } } }, "output": { "type": "object", "oneOf": [ {"$ref": "#/definitions/execute_result"}, {"$ref": "#/definitions/display_data"}, {"$ref": "#/definitions/stream"}, {"$ref": "#/definitions/error"} ] }, "execute_result": { "description": "Result of executing a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata", "execution_count"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["execute_result"] }, "execution_count": { "description": "A result's prompt number.", "type": ["integer", "null"], "minimum": 0 }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "display_data": { "description": "Data displayed as a result of code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "data", "metadata"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["display_data"] }, "data": {"$ref": "#/definitions/misc/mimebundle"}, "metadata": {"$ref": "#/definitions/misc/output_metadata"} } }, "stream": { "description": "Stream output from a code cell.", "type": "object", "additionalProperties": false, "required": ["output_type", "name", "text"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["stream"] }, "name": { "description": "The name of the stream (stdout, stderr).", "type": "string" }, "text": { "description": "The stream's text output, represented as an array of strings.", "$ref": "#/definitions/misc/multiline_string" } } }, "error": { "description": "Output of an error that occurred during code cell execution.", "type": "object", "additionalProperties": false, "required": ["output_type", "ename", "evalue", "traceback"], "properties": { "output_type": { "description": "Type of cell output.", "enum": ["error"] }, "ename": { "description": "The name of the error.", "type": "string" }, "evalue": { "description": "The value, or message, of the error.", "type": "string" }, "traceback": { "description": "The error's traceback, represented as an array of strings.", "type": "array", "items": {"type": "string"} } } }, "unrecognized_output": { "description": "Unrecognized output from a future minor-revision to the notebook format.", "type": "object", "additionalProperties": true, "required": ["output_type"], "properties": { "output_type": { "description": "Type of cell output.", "not": { "enum": ["execute_result", "display_data", "stream", "error"] } } } }, "misc": { "metadata_name": { "description": "The cell's name. If present, must be a non-empty string. Cell names are expected to be unique across all the cells in a given notebook. This criterion cannot be checked by the json schema and must be established by an additional check.", "type": "string", "pattern": "^.+$" }, "metadata_tags": { "description": "The cell's tags. Tags must be unique, and must not contain commas.", "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^[^,]+$" } }, "attachments": { "description": "Media attachments (e.g. inline images), stored as mimebundle keyed by filename.", "type": "object", "patternProperties": { ".*": { "description": "The attachment's data stored as a mimebundle.", "$ref": "#/definitions/misc/mimebundle" } } }, "source": { "description": "Contents of the cell, represented as an array of lines.", "$ref": "#/definitions/misc/multiline_string" }, "execution_count": { "description": "The code cell's prompt number. Will be null if the cell has not been run.", "type": ["integer", "null"], "minimum": 0 }, "mimebundle": { "description": "A mime-type keyed dictionary of data", "type": "object", "additionalProperties": { "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.", "$ref": "#/definitions/misc/multiline_string" }, "patternProperties": { "^application/(.*\\+)?json$": { "description": "Mimetypes with JSON output, can be any type" } } }, "output_metadata": { "description": "Cell output metadata.", "type": "object", "additionalProperties": true }, "multiline_string": { "oneOf" : [ {"type": "string"}, { "type": "array", "items": {"type": "string"} } ] } } } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/nbjson.py����������������������������������������������������������������0000664�0000000�0000000�00000003463�13612140577�0017350�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Read and write notebooks in JSON format.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import copy import json from ..notebooknode import from_dict from .rwbase import ( NotebookReader, NotebookWriter, rejoin_lines, split_lines, strip_transient ) class BytesEncoder(json.JSONEncoder): """A JSON encoder that accepts b64 (and other *ascii*) bytestrings.""" def default(self, obj): if isinstance(obj, bytes): return obj.decode('ascii') return json.JSONEncoder.default(self, obj) class JSONReader(NotebookReader): def reads(self, s, **kwargs): """Read a JSON string into a Notebook object""" nb = json.loads(s, **kwargs) nb = self.to_notebook(nb, **kwargs) return nb def to_notebook(self, d, **kwargs): """Convert a disk-format notebook dict to in-memory NotebookNode handles multi-line values as strings, scrubbing of transient values, etc. """ nb = from_dict(d) nb = rejoin_lines(nb) nb = strip_transient(nb) return nb class JSONWriter(NotebookWriter): def writes(self, nb, **kwargs): """Serialize a NotebookNode object as a JSON string""" kwargs['cls'] = BytesEncoder kwargs['indent'] = 1 kwargs['sort_keys'] = True kwargs['separators'] = (',',': ') kwargs.setdefault('ensure_ascii', False) # don't modify in-memory dict nb = copy.deepcopy(nb) if kwargs.pop('split_lines', True): nb = split_lines(nb) nb = strip_transient(nb) return json.dumps(nb, **kwargs) _reader = JSONReader() _writer = JSONWriter() reads = _reader.reads read = _reader.read to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/rwbase.py����������������������������������������������������������������0000664�0000000�0000000�00000010262�13612140577�0017335�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Base classes and utilities for readers and writers.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. def _is_json_mime(mime): """Is a key a JSON mime-type that should be left alone?""" return mime == 'application/json' or \ (mime.startswith('application/') and mime.endswith('+json')) def _rejoin_mimebundle(data): """Rejoin the multi-line string fields in a mimebundle (in-place)""" for key, value in list(data.items()): if not _is_json_mime(key) \ and isinstance(value, list) \ and all(isinstance(line, str) for line in value): data[key] = ''.join(value) return data def rejoin_lines(nb): """rejoin multiline text into strings For reversing effects of ``split_lines(nb)``. This only rejoins lines that have been split, so if text objects were not split they will pass through unchanged. Used when reading JSON files that may have been passed through split_lines. """ for cell in nb.cells: if 'source' in cell and isinstance(cell.source, list): cell.source = ''.join(cell.source) attachments = cell.get('attachments', {}) for key, attachment in attachments.items(): _rejoin_mimebundle(attachment) if cell.get('cell_type', None) == 'code': for output in cell.get('outputs', []): output_type = output.get('output_type', '') if output_type in {'execute_result', 'display_data'}: _rejoin_mimebundle(output.get('data', {})) elif output_type: if isinstance(output.get('text', ''), list): output.text = ''.join(output.text) return nb _non_text_split_mimes = { 'application/javascript', 'image/svg+xml', } def _split_mimebundle(data): """Split multi-line string fields in a mimebundle (in-place)""" for key, value in list(data.items()): if isinstance(value, str) and ( key.startswith('text/') or key in _non_text_split_mimes ): data[key] = value.splitlines(True) return data def split_lines(nb): """split likely multiline text into lists of strings For file output more friendly to line-based VCS. ``rejoin_lines(nb)`` will reverse the effects of ``split_lines(nb)``. Used when writing JSON files. """ for cell in nb.cells: source = cell.get('source', None) if isinstance(source, str): cell['source'] = source.splitlines(True) attachments = cell.get('attachments', {}) for key, attachment in attachments.items(): _split_mimebundle(attachment) if cell.cell_type == 'code': for output in cell.outputs: if output.output_type in {'execute_result', 'display_data'}: _split_mimebundle(output.get('data', {})) elif output.output_type == 'stream': if isinstance(output.text, str): output.text = output.text.splitlines(True) return nb def strip_transient(nb): """Strip transient values that shouldn't be stored in files. This should be called in *both* read and write. """ nb.metadata.pop('orig_nbformat', None) nb.metadata.pop('orig_nbformat_minor', None) nb.metadata.pop('signature', None) for cell in nb.cells: cell.metadata.pop('trusted', None) return nb class NotebookReader(object): """A class for reading notebooks.""" def reads(self, s, **kwargs): """Read a notebook from a string.""" raise NotImplementedError("reads must be implemented in a subclass") def read(self, fp, **kwargs): """Read a notebook from a file like object""" nbs = fp.read() return self.reads(nbs, **kwargs) class NotebookWriter(object): """A class for writing notebooks.""" def writes(self, nb, **kwargs): """Write a notebook to a string.""" raise NotImplementedError("writes must be implemented in a subclass") def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" nbs = self.writes(nb, **kwargs) return fp.write(nbs) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/tests/�������������������������������������������������������������������0000775�0000000�0000000�00000000000�13612140577�0016641�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/tests/__init__.py��������������������������������������������������������0000664�0000000�0000000�00000000000�13612140577�0020740�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/tests/formattest.py������������������������������������������������������0000664�0000000�0000000�00000002415�13612140577�0021405�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf8 -*- import io import os import shutil import tempfile pjoin = os.path.join from .nbexamples import nb0 def open_utf8(fname, mode): return io.open(fname, mode=mode, encoding='utf-8') class NBFormatTest: """Mixin for writing notebook format tests""" # override with appropriate values in subclasses nb0_ref = None ext = None mod = None def setUp(self): self.wd = tempfile.mkdtemp() def tearDown(self): shutil.rmtree(self.wd) def assertNBEquals(self, nba, nbb): self.assertEqual(nba, nbb) def test_writes(self): s = self.mod.writes(nb0) if self.nb0_ref: self.assertEqual(s, self.nb0_ref) def test_reads(self): s = self.mod.writes(nb0) nb = self.mod.reads(s) def test_roundtrip(self): s = self.mod.writes(nb0) self.assertNBEquals(self.mod.reads(s),nb0) def test_write_file(self): with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'w') as f: self.mod.write(nb0, f) def test_read_file(self): with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'w') as f: self.mod.write(nb0, f) with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'r') as f: nb = self.mod.read(f) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/tests/nbexamples.py������������������������������������������������������0000664�0000000�0000000�00000006270�13612140577�0021356�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- import os from ..._compat import encodebytes from ..nbbase import ( new_code_cell, new_markdown_cell, new_notebook, new_output, new_raw_cell ) # some random base64-encoded *text* png = encodebytes(os.urandom(5)).decode('ascii') jpeg = encodebytes(os.urandom(6)).decode('ascii') cells = [] cells.append(new_markdown_cell( source='Some NumPy Examples', )) cells.append(new_code_cell( source='import numpy', execution_count=1, )) cells.append(new_markdown_cell( source='Cell with attachments', attachments={ 'attachment1': { 'text/plain': '\n'.join(['a', 'b', 'c']), 'application/vnd.stuff+json': ['a', 1, 'x'], } } )) cells.append(new_raw_cell( source='A random array', )) cells.append(new_markdown_cell( source=u'## My Heading', )) cells.append(new_code_cell( source='a = numpy.random.rand(100)', execution_count=2, )) cells.append(new_code_cell( source='a = 10\nb = 5\n', execution_count=3, )) cells.append(new_code_cell( source='a = 10\nb = 5', execution_count=4, )) cells.append(new_code_cell( source=u'json_outputs()', execution_count=12, outputs=[new_output( output_type=u'display_data', data={ 'text/plain': u'', 'application/json': { 'key': 'value', 'x': 5, 'lis': [1, 2, 'x'] }, 'application/vnd.listofstr+json': ['a', 'b', 'c'], 'application/vnd.numbers+json': [1, 2, 3], 'application/vnd.number+json': 42, 'application/vnd.object+json': { 'number': 5, 'array': [1,2], 'str': 'x' }, 'application/vnd.string+json': 'ok', }, )] )) cells.append(new_code_cell( source=u'print "ünîcødé"', execution_count=3, outputs=[new_output( output_type=u'execute_result', data={ 'text/plain': u'', 'text/html': u'The HTML rep', 'text/latex': u'$a$', 'image/png': png, 'image/jpeg': jpeg, 'image/svg+xml': u'', 'application/json': { 'key': 'value' }, 'application/javascript': u'var i=0;' }, execution_count=3 ),new_output( output_type=u'display_data', data={ 'text/plain': u'', 'text/html': u'The HTML rep', 'text/latex': u'$a$', 'image/png': png, 'image/jpeg': jpeg, 'image/svg+xml': u'', 'application/json': { 'key': 'value' }, 'application/javascript': u'var i=0;' }, ),new_output( output_type=u'error', ename=u'NameError', evalue=u'NameError was here', traceback=[u'frame 0', u'frame 1', u'frame 2'] ),new_output( output_type=u'stream', text='foo\rbar\r\n' ),new_output( output_type=u'stream', name='stderr', text='\rfoo\rbar\n' )] )) nb0 = new_notebook(cells=cells, metadata={ 'language': 'python', } ) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/tests/test_convert.py����������������������������������������������������0000664�0000000�0000000�00000003446�13612140577�0021741�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- import copy from nbformat import validate from .. import convert from . import nbexamples from nbformat.v3.tests import nbexamples as v3examples from nbformat import v3, v4 def test_upgrade_notebook(): nb03 = copy.deepcopy(v3examples.nb0) validate(nb03) nb04 = convert.upgrade(nb03) validate(nb04) def test_downgrade_notebook(): nb04 = copy.deepcopy(nbexamples.nb0) validate(nb04) nb03 = convert.downgrade(nb04) validate(nb03) def test_upgrade_heading(): v3h = v3.new_heading_cell v4m = v4.new_markdown_cell for v3cell, expected in [ ( v3h(source='foo', level=1), v4m(source='# foo'), ), ( v3h(source='foo\nbar\nmulti-line\n', level=4), v4m(source='#### foo bar multi-line'), ), ( v3h(source=u'ünìcö∂e–cønvërsioñ', level=4), v4m(source=u'#### ünìcö∂e–cønvërsioñ'), ), ]: upgraded = convert.upgrade_cell(v3cell) assert upgraded == expected def test_downgrade_heading(): v3h = v3.new_heading_cell v4m = v4.new_markdown_cell v3m = lambda source: v3.new_text_cell('markdown', source) for v4cell, expected in [ ( v4m(source='# foo'), v3h(source='foo', level=1), ), ( v4m(source='#foo'), v3h(source='foo', level=1), ), ( v4m(source='#\tfoo'), v3h(source='foo', level=1), ), ( v4m(source='# \t foo'), v3h(source='foo', level=1), ), ( v4m(source='# foo\nbar'), v3m(source='# foo\nbar'), ), ]: downgraded = convert.downgrade_cell(v4cell) assert downgraded == expected ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/tests/test_json.py�������������������������������������������������������0000664�0000000�0000000�00000011516�13612140577�0021227�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os import json from unittest import TestCase from ..._compat import decodebytes from ..nbjson import reads, writes from .. import nbjson, nbformat, nbformat_minor from .nbexamples import nb0 from . import formattest class TestJSON(formattest.NBFormatTest, TestCase): nb0_ref = None ext = 'ipynb' mod = nbjson def test_roundtrip_nosplit(self): """Ensure that multiline blobs are still readable""" # ensures that notebooks written prior to splitlines change # are still readable. s = writes(nb0, split_lines=False) self.assertEqual(nbjson.reads(s),nb0) def test_roundtrip_split(self): """Ensure that splitting multiline blocks is safe""" # This won't differ from test_roundtrip unless the default changes s = writes(nb0, split_lines=True) self.assertEqual(nbjson.reads(s),nb0) def test_splitlines(self): """Test splitlines in mime-bundles""" s = writes(nb0, split_lines=True) raw_nb = json.loads(s) for i, ref_cell in enumerate(nb0.cells): if ref_cell.source.strip() == 'Cell with attachments': attach_ref = ref_cell['attachments']['attachment1'] attach_json = raw_nb['cells'][i]['attachments']['attachment1'] if ref_cell.source.strip() == 'json_outputs()': output_ref = ref_cell['outputs'][0]['data'] output_json = raw_nb['cells'][i]['outputs'][0]['data'] for key, json_value in attach_json.items(): if key == 'text/plain': # text should be split assert json_value == attach_ref['text/plain'].splitlines(True) else: # JSON attachments assert json_value == attach_ref[key] # check that JSON outputs are left alone: for key, json_value in output_json.items(): if key == 'text/plain': # text should be split assert json_value == output_ref['text/plain'].splitlines(True) else: # JSON outputs should be left alone assert json_value == output_ref[key] def test_read_png(self): """PNG output data is b64 unicode""" s = writes(nb0) nb1 = nbjson.reads(s) found_png = False for cell in nb1.cells: if not 'outputs' in cell: continue for output in cell.outputs: if not 'data' in output: continue if 'image/png' in output.data: found_png = True pngdata = output.data['image/png'] self.assertEqual(type(pngdata), str) # test that it is valid b64 data b64bytes = pngdata.encode('ascii') raw_bytes = decodebytes(b64bytes) assert found_png, "never found png output" def test_read_jpeg(self): """JPEG output data is b64 unicode""" s = writes(nb0) nb1 = nbjson.reads(s) found_jpeg = False for cell in nb1.cells: if not 'outputs' in cell: continue for output in cell.outputs: if not 'data' in output: continue if 'image/jpeg' in output.data: found_jpeg = True jpegdata = output.data['image/jpeg'] self.assertEqual(type(jpegdata), str) # test that it is valid b64 data b64bytes = jpegdata.encode('ascii') raw_bytes = decodebytes(b64bytes) assert found_jpeg, "never found jpeg output" def test_latest_schema_matches(self): """Test to ensure all schema is locked to a known version""" assert nbformat == 4 assert nbformat_minor == 4 def test_base_version_matches_latest(self): """Test to ensure latest version file matches latest verison""" with open(os.path.join(os.path.dirname(__file__), '..', 'nbformat.v4.schema.json'), 'r') as schema_file: latest_schema = json.load(schema_file) with open(os.path.join(os.path.dirname(__file__), '..', 'nbformat.v{major}.{minor}.schema.json'.format( major=nbformat, minor=nbformat_minor)), 'r') as schema_file: ver_schema = json.load(schema_file) assert latest_schema == ver_schema def test_latest_matches_nbformat(self): """Test to ensure that the nbformat version matches the description of the latest schema""" with open(os.path.join(os.path.dirname(__file__), '..', 'nbformat.v4.schema.json'), 'r') as schema_file: schema = json.load(schema_file) assert schema['description'] == 'Jupyter Notebook v{major}.{minor} JSON schema.'.format( major=nbformat, minor=nbformat_minor ) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/v4/tests/test_nbbase.py�����������������������������������������������������0000664�0000000�0000000�00000005727�13612140577�0021517�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# coding: utf-8 """Tests for the Python API for composing notebook elements""" from nbformat.validator import isvalid, validate, ValidationError from ..nbbase import ( NotebookNode, nbformat, new_code_cell, new_markdown_cell, new_notebook, new_output, new_raw_cell, ) def test_empty_notebook(): nb = new_notebook() assert nb.cells == [] assert nb.metadata == NotebookNode() assert nb.nbformat == nbformat def test_empty_markdown_cell(): cell = new_markdown_cell() assert cell.cell_type == 'markdown' assert cell.source == '' def test_markdown_cell(): cell = new_markdown_cell(u'* Søme markdown') assert cell.source == u'* Søme markdown' def test_empty_raw_cell(): cell = new_raw_cell() assert cell.cell_type == u'raw' assert cell.source == '' def test_raw_cell(): cell = new_raw_cell('hi') assert cell.source == u'hi' def test_empty_code_cell(): cell = new_code_cell('hi') assert cell.cell_type == 'code' assert cell.source == u'hi' def test_empty_display_data(): output = new_output('display_data') assert output.output_type == 'display_data' def test_empty_stream(): output = new_output('stream') assert output.output_type == 'stream' assert output.name == 'stdout' assert output.text == '' def test_empty_execute_result(): output = new_output('execute_result', execution_count=1) assert output.output_type == 'execute_result' mimebundle = { 'text/plain': "some text", "application/json": { "key": "value" }, "image/svg+xml": 'ABCDEF', "application/octet-stream": 'ABC-123', "application/vnd.foo+bar": "Some other stuff", } def test_display_data(): output = new_output('display_data', mimebundle) for key, expected in mimebundle.items(): assert output.data[key] == expected def test_execute_result(): output = new_output('execute_result', mimebundle, execution_count=10) assert output.execution_count == 10 for key, expected in mimebundle.items(): assert output.data[key] == expected def test_error(): o = new_output(output_type=u'error', ename=u'NameError', evalue=u'Name not found', traceback=[u'frame 0', u'frame 1', u'frame 2'] ) assert o.output_type == u'error' assert o.ename == u'NameError' assert o.evalue == u'Name not found' assert o.traceback == [u'frame 0', u'frame 1', u'frame 2'] def test_code_cell_with_outputs(): cell = new_code_cell(execution_count=10, outputs=[ new_output('display_data', mimebundle), new_output('stream', text='hello'), new_output('execute_result', mimebundle, execution_count=10), ]) assert cell.execution_count == 10 assert len(cell.outputs) == 3 er = cell.outputs[-1] assert er.execution_count == 10 assert er['output_type'] == 'execute_result' def test_stream(): output = new_output('stream', name='stderr', text='hello there') assert output.name == 'stderr' assert output.text == 'hello there' �����������������������������������������nbformat-5.0.4/nbformat/v4/tests/test_validate.py���������������������������������������������������0000664�0000000�0000000�00000004634�13612140577�0022052�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Tests for nbformat validation""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import io import os import pytest from nbformat.validator import validate, ValidationError from ..nbjson import reads from ..nbbase import ( nbformat, new_code_cell, new_markdown_cell, new_notebook, new_output, new_raw_cell, ) def validate4(obj, ref=None): return validate(obj, ref, version=nbformat) def test_valid_code_cell(): cell = new_code_cell() validate4(cell, 'code_cell') def test_invalid_code_cell(): cell = new_code_cell() cell['source'] = 5 with pytest.raises(ValidationError): validate4(cell, 'code_cell') cell = new_code_cell() del cell['metadata'] with pytest.raises(ValidationError): validate4(cell, 'code_cell') cell = new_code_cell() del cell['source'] with pytest.raises(ValidationError): validate4(cell, 'code_cell') cell = new_code_cell() del cell['cell_type'] with pytest.raises(ValidationError): validate4(cell, 'code_cell') def test_invalid_markdown_cell(): cell = new_markdown_cell() cell['source'] = 5 with pytest.raises(ValidationError): validate4(cell, 'markdown_cell') cell = new_markdown_cell() del cell['metadata'] with pytest.raises(ValidationError): validate4(cell, 'markdown_cell') cell = new_markdown_cell() del cell['source'] with pytest.raises(ValidationError): validate4(cell, 'markdown_cell') cell = new_markdown_cell() del cell['cell_type'] with pytest.raises(ValidationError): validate4(cell, 'markdown_cell') def test_invalid_raw_cell(): cell = new_raw_cell() cell['source'] = 5 with pytest.raises(ValidationError): validate4(cell, 'raw_cell') cell = new_raw_cell() del cell['metadata'] with pytest.raises(ValidationError): validate4(cell, 'raw_cell') cell = new_raw_cell() del cell['source'] with pytest.raises(ValidationError): validate4(cell, 'raw_cell') cell = new_raw_cell() del cell['cell_type'] with pytest.raises(ValidationError): validate4(cell, 'raw_cell') def test_sample_notebook(): here = os.path.dirname(__file__) with io.open(os.path.join(here, os.pardir, os.pardir, 'tests', "test4.ipynb"), encoding='utf-8') as f: nb = reads(f.read()) validate4(nb) ����������������������������������������������������������������������������������������������������nbformat-5.0.4/nbformat/validator.py����������������������������������������������������������������0000664�0000000�0000000�00000024317�13612140577�0017514�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function import json import os import pprint import sys import warnings try: from jsonschema import ValidationError from jsonschema import Draft4Validator as Validator except ImportError as e: verbose_msg = """ Jupyter notebook format depends on the jsonschema package: https://pypi.python.org/pypi/jsonschema Please install it first. """ raise ImportError(str(e) + verbose_msg) from ipython_genutils.importstring import import_item from .reader import get_version, reads validators = {} def _relax_additional_properties(obj): """relax any `additionalProperties`""" if isinstance(obj, dict): for key, value in obj.items(): if key == 'additionalProperties': value = True else: value = _relax_additional_properties(value) obj[key] = value elif isinstance(obj, list): for i, value in enumerate(obj): obj[i] = _relax_additional_properties(value) return obj def _allow_undefined(schema): schema['definitions']['cell']['oneOf'].append( {"$ref": "#/definitions/unrecognized_cell"} ) schema['definitions']['output']['oneOf'].append( {"$ref": "#/definitions/unrecognized_output"} ) return schema def get_validator(version=None, version_minor=None, relax_add_props=False): """Load the JSON schema into a Validator""" if version is None: from .. import current_nbformat version = current_nbformat v = import_item("nbformat.v%s" % version) current_minor = getattr(v, 'nbformat_minor', 0) if version_minor is None: version_minor = current_minor version_tuple = (version, version_minor) if version_tuple not in validators: try: schema_json = _get_schema_json(v, version=version, version_minor=version_minor) except AttributeError: return None if current_minor < version_minor: # notebook from the future, relax all `additionalProperties: False` requirements schema_json = _relax_additional_properties(schema_json) # and allow undefined cell types and outputs schema_json = _allow_undefined(schema_json) validators[version_tuple] = Validator(schema_json) if relax_add_props: try: schema_json = _get_schema_json(v, version=version, version_minor=version_minor) except AttributeError: return None # this allows properties to be added for intermediate # representations while validating for all other kinds of errors schema_json = _relax_additional_properties(schema_json) validators[version_tuple] = Validator(schema_json) return validators[version_tuple] def _get_schema_json(v, version=None, version_minor=None): """ Gets the json schema from a given imported library and nbformat version. """ if (version, version_minor) in v.nbformat_schema: schema_path = os.path.join(os.path.dirname(v.__file__), v.nbformat_schema[(version, version_minor)]) elif version_minor > v.nbformat_minor: # load the latest schema schema_path = os.path.join(os.path.dirname(v.__file__), v.nbformat_schema[(None, None)]) else: raise AttributeError('Cannot find appropriate nbformat schema file.') with open(schema_path) as f: schema_json = json.load(f) return schema_json def isvalid(nbjson, ref=None, version=None, version_minor=None): """Checks whether the given notebook JSON conforms to the current notebook format schema. Returns True if the JSON is valid, and False otherwise. To see the individual errors that were encountered, please use the `validate` function instead. """ try: validate(nbjson, ref, version, version_minor) except ValidationError: return False else: return True def _format_as_index(indices): """ (from jsonschema._utils.format_as_index, copied to avoid relying on private API) Construct a single string containing indexing operations for the indices. For example, [1, 2, "foo"] -> [1][2]["foo"] """ if not indices: return "" return "[%s]" % "][".join(repr(index) for index in indices) _ITEM_LIMIT = 16 _STR_LIMIT = 64 def _truncate_obj(obj): """Truncate objects for use in validation tracebacks Cell and output lists are squashed, as are long strings, lists, and dicts. """ if isinstance(obj, dict): truncated = { k:_truncate_obj(v) for k,v in list(obj.items())[:_ITEM_LIMIT] } if isinstance(truncated.get('cells'), list): truncated['cells'] = ['...%i cells...' % len(obj['cells'])] if isinstance(truncated.get('outputs'), list): truncated['outputs'] = ['...%i outputs...' % len(obj['outputs'])] if len(obj) > _ITEM_LIMIT: truncated['...'] = '%i keys truncated' % (len(obj) - _ITEM_LIMIT) return truncated elif isinstance(obj, list): truncated = [ _truncate_obj(item) for item in obj[:_ITEM_LIMIT] ] if len(obj) > _ITEM_LIMIT: truncated.append('...%i items truncated...' % (len(obj) - _ITEM_LIMIT)) return truncated elif isinstance(obj, str): truncated = obj[:_STR_LIMIT] if len(obj) > _STR_LIMIT: truncated += '...' return truncated else: return obj class NotebookValidationError(ValidationError): """Schema ValidationError with truncated representation to avoid massive verbose tracebacks. """ def __init__(self, original, ref=None): self.original = original self.ref = getattr(self.original, 'ref', ref) self.message = self.original.message def __getattr__(self, key): return getattr(self.original, key) def __unicode__(self): """Custom str for validation errors avoids dumping full schema and notebook to logs """ error = self.original instance = _truncate_obj(error.instance) return u'\n'.join([ error.message, u'', u"Failed validating %r in %s%s:" % ( error.validator, self.ref or 'notebook', _format_as_index(list(error.relative_schema_path)[:-1])), u'', u'On instance%s:' % _format_as_index(error.relative_path), pprint.pformat(instance, width=78), ]) if sys.version_info >= (3,): __str__ = __unicode__ def better_validation_error(error, version, version_minor): """Get better ValidationError on oneOf failures oneOf errors aren't informative. if it's a cell type or output_type error, try validating directly based on the type for a better error message """ key = error.schema_path[-1] ref = None if key.endswith('Of'): if isinstance(error.instance, dict): if 'cell_type' in error.instance: ref = error.instance['cell_type'] + "_cell" elif 'output_type' in error.instance: ref = error.instance['output_type'] if ref: try: validate(error.instance, ref, version=version, version_minor=version_minor, ) except ValidationError as sub_error: # keep extending relative path error.relative_path.extend(sub_error.relative_path) sub_error.relative_path = error.relative_path better = better_validation_error(sub_error, version, version_minor) if better.ref is None: better.ref = ref return better except Exception: # if it fails for some reason, # let the original error through pass return NotebookValidationError(error, ref) def validate(nbdict=None, ref=None, version=None, version_minor=None, relax_add_props=False, nbjson=None): """Checks whether the given notebook dict-like object conforms to the relevant notebook format schema. Raises ValidationError if not valid. """ # backwards compatibility for nbjson argument if nbdict is not None: pass elif nbjson is not None: nbdict = nbjson else: raise TypeError("validate() missing 1 required argument: 'nbdict'") if ref is None: # if ref is not specified, we have a whole notebook, so we can get the version nbdict_version, nbdict_version_minor = get_version(nbdict) if version is None: version = nbdict_version if version_minor is None: version_minor = nbdict_version_minor else: # if ref is specified, and we don't have a version number, assume we're validating against 1.0 if version is None: version, version_minor = 1, 0 for error in iter_validate(nbdict, ref=ref, version=version, version_minor=version_minor, relax_add_props=relax_add_props): raise error def iter_validate(nbdict=None, ref=None, version=None, version_minor=None, relax_add_props=False, nbjson=None): """Checks whether the given notebook dict-like object conforms to the relevant notebook format schema. Returns a generator of all ValidationErrors if not valid. """ # backwards compatibility for nbjson argument if nbdict is not None: pass elif nbjson is not None: nbdict = nbjson else: raise TypeError("iter_validate() missing 1 required argument: 'nbdict'") if version is None: version, version_minor = get_version(nbdict) validator = get_validator(version, version_minor, relax_add_props=relax_add_props) if validator is None: # no validator yield ValidationError("No schema for validating v%s notebooks" % version) return if ref: errors = validator.iter_errors(nbdict, {'$ref' : '#/definitions/%s' % ref}) else: errors = validator.iter_errors(nbdict) for error in errors: yield better_validation_error(error, version, version_minor) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/package.json�������������������������������������������������������������������������0000664�0000000�0000000�00000001142�13612140577�0015622�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "name": "nbformat-schema", "version": "5.0.4", "description": "JSON schemata for Jupyter notebook formats", "main": "index.js", "files": [ "nbformat/v3/nbformat.v3.schema.json", "nbformat/v4/nbformat.v4.schema.json" ], "repository": { "type": "git", "url": "git+https://github.com/jupyter/nbformat.git" }, "keywords": [ "jupyter", "notebook", "json-schema" ], "author": "Project Jupyter Contributors", "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/jupyter/nbformat/issues" }, "homepage": "https://nbformat.readthedocs.io" } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/scripts/�����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13612140577�0015025�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/scripts/jupyter-trust����������������������������������������������������������������0000775�0000000�0000000�00000000240�13612140577�0017630�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python def main(): from nbformat.sign import TrustNotebookApp TrustNotebookApp.launch_instance() if __name__ == '__main__': main() ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/setup.cfg����������������������������������������������������������������������������0000664�0000000�0000000�00000000100�13612140577�0015146�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[bdist_wheel] universal=0 [metadata] license_file = COPYING.md ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nbformat-5.0.4/setup.py�����������������������������������������������������������������������������0000664�0000000�0000000�00000006151�13612140577�0015053�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python # coding: utf-8 # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function # the name of the project name = 'nbformat' #----------------------------------------------------------------------------- # Minimal Python version sanity check #----------------------------------------------------------------------------- import sys #----------------------------------------------------------------------------- # get on with it #----------------------------------------------------------------------------- import os from glob import glob from distutils.core import setup pjoin = os.path.join here = os.path.abspath(os.path.dirname(__file__)) pkg_root = pjoin(here, name) packages = [] for d, _, _ in os.walk(pjoin(here, name)): if os.path.exists(pjoin(d, '__init__.py')): packages.append(d[len(here)+1:].replace(os.path.sep, '.')) package_data = { 'nbformat' : [ 'tests/*.ipynb', 'v3/nbformat.v3*.schema.json', 'v4/nbformat.v4*.schema.json', ], } version_ns = {} with open(pjoin(here, name, '_version.py')) as f: exec(f.read(), {}, version_ns) setup_args = dict( name = name, version = version_ns['__version__'], scripts = glob(pjoin('scripts', '*')), packages = packages, package_data = package_data, description = "The Jupyter Notebook format", long_description= """ This package contains the base implementation of the Jupyter Notebook format, and Python APIs for working with notebooks. """, author = 'Jupyter Development Team', author_email = 'jupyter@googlegroups.com', url = 'http://jupyter.org', license = 'BSD', python_requires = '>=3.5', platforms = "Linux, Mac OS X, Windows", keywords = ['Interactive', 'Interpreter', 'Shell', 'Web'], classifiers = [ 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', ], ) if 'develop' in sys.argv or any(a.startswith('bdist') for a in sys.argv): import setuptools setuptools_args = {} install_requires = setuptools_args['install_requires'] = [ 'ipython_genutils', 'traitlets>=4.1', 'jsonschema>=2.4,!=2.5.0', 'jupyter_core', ] extras_require = setuptools_args['extras_require'] = { 'test': ['testpath', 'pytest', 'pytest-cov'], } if 'setuptools' in sys.modules: setup_args.update(setuptools_args) setup_args['entry_points'] = { 'console_scripts': [ 'jupyter-trust = nbformat.sign:TrustNotebookApp.launch_instance', ] } setup_args.pop('scripts', None) if __name__ == '__main__': setup(**setup_args) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������