forked from kynan/nbstripout
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnbstripout.py
executable file
·152 lines (118 loc) · 4.38 KB
/
nbstripout.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python
"""nbstripout: strip output from Jupyter and IPython notebooks
Opens a notebook, strips its output, and writes the outputless version to the
original file.
Useful mainly as a git filter or pre-commit hook for users who don't want to
track output in VCS.
This does mostly the same thing as the `Clear All Output` command in the
notebook UI.
Usage
=====
Strip output from IPython / Jupyter notebook (modifies the file in-place): ::
nbstripout <file.ipynb>
By default, nbstripout will only modify files ending in '.ipynb', to
process other files us the '-f' flag to force the application.
nbstripout -f <file.ipynb.bak>
Use as part of a shell pipeline: ::
FILE.ipynb | nbstripout > OUT.ipynb
Set up the git filter and attributes as described in the manual installation
instructions below: ::
nbstripout install
Show this help page: ::
nbstripout help
Manual filter installation
==========================
Set up a git filter using nbstripout as follows: ::
git config filter.nbstripout.clean '/path/to/nbstripout'
git config filter.nbstripout.smudge cat
git config filter.nbstripout.required true
Create a file ``.gitattributes`` or ``.git/info/attributes`` with: ::
*.ipynb filter=nbstripout
"""
from __future__ import print_function
import io
import sys
try:
# Jupyter >= 4
from nbformat import read, write, NO_CONVERT
except ImportError:
# IPython 3
try:
from IPython.nbformat import read, write, NO_CONVERT
except ImportError:
# IPython < 3
from IPython.nbformat import current
def read(f, as_version):
return current.read(f, 'json')
def write(nb, f):
return current.write(nb, f, 'json')
def _cells(nb):
"""Yield all cells in an nbformat-insensitive manner"""
if nb.nbformat < 4:
for ws in nb.worksheets:
for cell in ws.cells:
yield cell
else:
for cell in nb.cells:
yield cell
def strip_output(nb):
"""strip the outputs from a notebook object"""
nb.metadata.pop('signature', None)
for cell in _cells(nb):
if 'outputs' in cell:
cell['outputs'] = []
if 'prompt_number' in cell:
cell['prompt_number'] = None
if 'execution_count' in cell:
cell['execution_count'] = None
return nb
def install():
"""Install the git filter and set the git attributes."""
from os import path
from subprocess import check_call, check_output, CalledProcessError
try:
git_dir = check_output(['git', 'rev-parse', '--git-dir']).strip()
except CalledProcessError:
print('Installation failed: not a git repository!', file=sys.stderr)
sys.exit(1)
check_call(['git', 'config', 'filter.nbstripout.clean', '%s %s' %
(sys.executable, path.abspath(__file__))])
check_call(['git', 'config', 'filter.nbstripout.smudge', 'cat'])
check_call(['git', 'config', 'filter.nbstripout.required', 'true'])
attrfile = path.join(git_dir.decode(), 'info', 'attributes')
# Check if there is already a filter for ipynb files
if path.exists(attrfile):
with open(attrfile, 'r') as f:
if '*.ipynb filter' in f.read():
return
with open(attrfile, 'a') as f:
f.write('\n*.ipynb filter=nbstripout')
def main():
if len(sys.argv) > 1:
if sys.argv[1] in ['help', '-h', '--help']:
print(__doc__, file=sys.stderr)
sys.exit(1)
if sys.argv[1] in ['install', '--install']:
sys.exit(install())
force = False
filenames = sys.argv[1:]
if filenames[0] in ['-f', '--force']:
force = True
filenames.pop(0)
for filename in filenames:
if not force and not filename.endswith('.ipynb'):
continue
try:
with io.open(filename, 'r', encoding='utf8') as f:
nb = read(f, as_version=NO_CONVERT)
nb = strip_output(nb)
with io.open(filename, 'w', encoding='utf8') as f:
write(nb, f)
except Exception:
# Ignore exceptions for non-notebook files.
print("Could not strip '{}'".format(filename))
raise
else:
write(strip_output(read(sys.stdin, as_version=NO_CONVERT)), sys.stdout)
if __name__ == '__main__':
main()