current.py
238 lines
| 6.6 KiB
| text/x-python
|
PythonLexer
Brian E. Granger
|
r4609 | """The official API for working with notebooks in the current format version. | ||
Authors: | ||||
* Brian Granger | ||||
Jonathan Frederic
|
r12493 | * Jonathan Frederic | ||
Brian E. Granger
|
r4609 | """ | ||
#----------------------------------------------------------------------------- | ||||
# 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 | ||||
#----------------------------------------------------------------------------- | ||||
Brian E. Granger
|
r4637 | from __future__ import print_function | ||
Jonathan Frederic
|
r12493 | |||
Brian E. Granger
|
r4406 | from xml.etree import ElementTree as ET | ||
import re | ||||
Thomas Kluyver
|
r13353 | from IPython.utils.py3compat import unicode_type | ||
Brian Granger
|
r6025 | from IPython.nbformat.v3 import ( | ||
Brian E. Granger
|
r4484 | NotebookNode, | ||
Brian E. Granger
|
r4520 | new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet, | ||
MinRK
|
r7545 | parse_filename, new_metadata, new_author, new_heading_cell, nbformat, | ||
Jessica B. Hamrick
|
r16330 | nbformat_minor, nbformat_schema, to_notebook_json | ||
Brian E. Granger
|
r4484 | ) | ||
Thomas Kluyver
|
r13627 | from IPython.nbformat import v3 as _v_latest | ||
Brian E. Granger
|
r4484 | |||
Jonathan Frederic
|
r12753 | from .reader import reads as reader_reads | ||
from .reader import versions | ||||
Jonathan Frederic
|
r12493 | from .convert import convert | ||
Jessica B. Hamrick
|
r16332 | from .validator import validate | ||
Jonathan Frederic
|
r12493 | |||
Jessica B. Hamrick
|
r16342 | import logging | ||
logger = logging.getLogger('NotebookApp') | ||||
Brian E. Granger
|
r4609 | #----------------------------------------------------------------------------- | ||
# Code | ||||
#----------------------------------------------------------------------------- | ||||
Brian E. Granger
|
r4406 | |||
Brian Granger
|
r6061 | current_nbformat = nbformat | ||
MinRK
|
r7545 | current_nbformat_minor = nbformat_minor | ||
Thomas Kluyver
|
r13627 | current_nbformat_module = _v_latest.__name__ | ||
Jessica B. Hamrick
|
r16330 | |||
Thomas Kluyver
|
r13627 | def docstring_nbformat_mod(func): | ||
"""Decorator for docstrings referring to classes/functions accessed through | ||||
nbformat.current. | ||||
Put {nbformat_mod} in the docstring in place of 'IPython.nbformat.v3'. | ||||
""" | ||||
func.__doc__ = func.__doc__.format(nbformat_mod=current_nbformat_module) | ||||
return func | ||||
MinRK
|
r7545 | |||
Brian E. Granger
|
r4406 | |||
MinRK
|
r11643 | class NBFormatError(ValueError): | ||
pass | ||||
Brian E. Granger
|
r4406 | |||
def parse_py(s, **kwargs): | ||||
"""Parse a string into a (nbformat, string) tuple.""" | ||||
MinRK
|
r7566 | nbf = current_nbformat | ||
nbm = current_nbformat_minor | ||||
pattern = r'# <nbformat>(?P<nbformat>\d+[\.\d+]*)</nbformat>' | ||||
Brian E. Granger
|
r4406 | m = re.search(pattern,s) | ||
if m is not None: | ||||
MinRK
|
r7566 | digits = m.group('nbformat').split('.') | ||
nbf = int(digits[0]) | ||||
if len(digits) > 1: | ||||
nbm = int(digits[1]) | ||||
return nbf, nbm, s | ||||
Brian E. Granger
|
r4406 | |||
Jessica B. Hamrick
|
r16403 | def reads_json(nbjson, **kwargs): | ||
Jessica B. Hamrick
|
r16346 | """Read a JSON notebook from a string and return the NotebookNode | ||
object. Report if any JSON format errors are detected. | ||||
""" | ||||
Jessica B. Hamrick
|
r16403 | nb = reader_reads(nbjson, **kwargs) | ||
nb_current = convert(nb, current_nbformat) | ||||
Jessica B. Hamrick
|
r16407 | errors = validate(nb_current) | ||
Jessica B. Hamrick
|
r16429 | if errors: | ||
Jessica B. Hamrick
|
r16342 | logger.error( | ||
Jessica B. Hamrick
|
r16404 | "Notebook JSON is invalid (%d errors detected during read)", | ||
Jessica B. Hamrick
|
r16407 | len(errors)) | ||
Jessica B. Hamrick
|
r16403 | return nb_current | ||
Brian E. Granger
|
r4406 | |||
def writes_json(nb, **kwargs): | ||||
Jessica B. Hamrick
|
r16346 | """Take a NotebookNode object and write out a JSON string. Report if | ||
any JSON format errors are detected. | ||||
""" | ||||
Jessica B. Hamrick
|
r16407 | errors = validate(nb) | ||
Jessica B. Hamrick
|
r16429 | if errors: | ||
Jessica B. Hamrick
|
r16342 | logger.error( | ||
Jessica B. Hamrick
|
r16404 | "Notebook JSON is invalid (%d errors detected during write)", | ||
Jessica B. Hamrick
|
r16407 | len(errors)) | ||
Jessica B. Hamrick
|
r16403 | nbjson = versions[current_nbformat].writes_json(nb, **kwargs) | ||
Jessica B. Hamrick
|
r16330 | return nbjson | ||
Brian E. Granger
|
r4406 | |||
def reads_py(s, **kwargs): | ||||
"""Read a .py notebook from a string and return the NotebookNode object.""" | ||||
MinRK
|
r7566 | nbf, nbm, s = parse_py(s, **kwargs) | ||
Jonathan Frederic
|
r12755 | if nbf in (2, 3): | ||
Jonathan Frederic
|
r12753 | nb = versions[nbf].to_notebook_py(s, **kwargs) | ||
Brian E. Granger
|
r4406 | else: | ||
Brian Granger
|
r6061 | raise NBFormatError('Unsupported PY nbformat version: %i' % nbf) | ||
Brian E. Granger
|
r4406 | return nb | ||
def writes_py(nb, **kwargs): | ||||
Jonathan Frederic
|
r12493 | # nbformat 3 is the latest format that supports py | ||
Jonathan Frederic
|
r12753 | return versions[3].writes_py(nb, **kwargs) | ||
Brian E. Granger
|
r4406 | |||
# High level API | ||||
def reads(s, format, **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 | ||||
---------- | ||||
Brian E. Granger
|
r4637 | s : unicode | ||
The raw unicode string to read the notebook from. | ||||
format : (u'json', u'ipynb', u'py') | ||||
Brian E. Granger
|
r4406 | The format that the string is in. | ||
Returns | ||||
------- | ||||
nb : NotebookNode | ||||
The notebook that was read. | ||||
""" | ||||
Thomas Kluyver
|
r13353 | format = unicode_type(format) | ||
Brian Granger
|
r6021 | if format == u'json' or format == u'ipynb': | ||
Brian E. Granger
|
r4406 | return reads_json(s, **kwargs) | ||
Brian E. Granger
|
r4637 | elif format == u'py': | ||
Brian E. Granger
|
r4406 | return reads_py(s, **kwargs) | ||
else: | ||||
raise NBFormatError('Unsupported format: %s' % format) | ||||
def writes(nb, format, **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. | ||||
Brian E. Granger
|
r4637 | format : (u'json', u'ipynb', u'py') | ||
Brian E. Granger
|
r4406 | The format to write the notebook in. | ||
Returns | ||||
------- | ||||
Brian E. Granger
|
r4637 | s : unicode | ||
Brian E. Granger
|
r4406 | The notebook string. | ||
""" | ||||
Thomas Kluyver
|
r13353 | format = unicode_type(format) | ||
Brian Granger
|
r6021 | if format == u'json' or format == u'ipynb': | ||
Brian E. Granger
|
r4406 | return writes_json(nb, **kwargs) | ||
Brian E. Granger
|
r4637 | elif format == u'py': | ||
Brian E. Granger
|
r4406 | return writes_py(nb, **kwargs) | ||
else: | ||||
raise NBFormatError('Unsupported format: %s' % format) | ||||
def read(fp, format, **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. | ||||
Brian E. Granger
|
r4637 | format : (u'json', u'ipynb', u'py') | ||
Brian E. Granger
|
r4406 | The format that the string is in. | ||
Returns | ||||
------- | ||||
nb : NotebookNode | ||||
The notebook that was read. | ||||
""" | ||||
return reads(fp.read(), format, **kwargs) | ||||
def write(nb, fp, format, **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. | ||||
Brian E. Granger
|
r4637 | format : (u'json', u'ipynb', u'py') | ||
Brian E. Granger
|
r4406 | The format to write the notebook in. | ||
Returns | ||||
------- | ||||
Brian E. Granger
|
r4637 | s : unicode | ||
Brian E. Granger
|
r4406 | The notebook string. | ||
""" | ||||
return fp.write(writes(nb, format, **kwargs)) | ||||
Brian E. Granger
|
r4637 | def _convert_to_metadata(): | ||
"""Convert to a notebook having notebook metadata.""" | ||||
import glob | ||||
for fname in glob.glob('*.ipynb'): | ||||
print('Converting file:',fname) | ||||
with open(fname,'r') as f: | ||||
nb = read(f,u'json') | ||||
md = new_metadata() | ||||
if u'name' in nb: | ||||
md.name = nb.name | ||||
del nb[u'name'] | ||||
nb.metadata = md | ||||
with open(fname,'w') as f: | ||||
write(nb, f, u'json') | ||||
Brian E. Granger
|
r4406 | |||