ipynbdiff 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c0839dd5e5fbcdf19b5525d859fa7d224ec1bb647d7131f9cc20487190ccea80
4
+ data.tar.gz: ca32de2c784712f66f2f1c8b5642b32fca0078eae0279c8b30f975216101d143
5
+ SHA512:
6
+ metadata.gz: 45353d2e38a4378cb5f785edb6b38d250bf38ce4934f8943dcbe08973e4c187942449d185d4a3af59649d9459c74071475b33f23033c192b4345b24f95a2fd78
7
+ data.tar.gz: 7d8df2c34356018dfe098c0f36e8fb8f3c189c8121411826b9923b406ead730856a9e46ca57124b4e4e23e0409e1fdf83c5785686ab6aa0254bcedca07b95246
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .tool-versions
2
+ .bundle
3
+
4
+
5
+ *.gem
6
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem 'diffy', '3.3.0'
4
+ gem 'json', '2.5.1'
5
+ gem 'rspec', '3.10.0'
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ GEM
2
+ specs:
3
+ diff-lcs (1.4.4)
4
+ diffy (3.3.0)
5
+ json (2.5.1)
6
+ rspec (3.10.0)
7
+ rspec-core (~> 3.10.0)
8
+ rspec-expectations (~> 3.10.0)
9
+ rspec-mocks (~> 3.10.0)
10
+ rspec-core (3.10.1)
11
+ rspec-support (~> 3.10.0)
12
+ rspec-expectations (3.10.1)
13
+ diff-lcs (>= 1.2.0, < 2.0)
14
+ rspec-support (~> 3.10.0)
15
+ rspec-mocks (3.10.2)
16
+ diff-lcs (>= 1.2.0, < 2.0)
17
+ rspec-support (~> 3.10.0)
18
+ rspec-support (3.10.2)
19
+
20
+ PLATFORMS
21
+ x86_64-darwin-20
22
+
23
+ DEPENDENCIES
24
+ diffy (= 3.3.0)
25
+ json (= 2.5.1)
26
+ rspec (= 3.10.0)
27
+
28
+ BUNDLED WITH
29
+ 2.2.28
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # rb-ipynbdiff: Better Jupyter Notebook diffs, in Ruby
2
+
3
+ This is a port of [ipynbdiff](https://gitlab.com/gitlab-org/incubation-engineering/mlops/ipynbdiff)
data/ipynbdiff.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'ipynbdiff'
5
+ s.version = '0.3.1'
6
+ s.summary = 'Human Readble diffs for Jupyter Notebooks'
7
+ s.description = 'A simple hello world gem'
8
+ s.authors = ['Eduardo Bonet']
9
+ s.email = 'ebonet@gitlab.com'
10
+ # Specify which files should be added to the gem when it is released.
11
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
12
+ s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
13
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|example)/}) }
14
+ end
15
+ s.homepage =
16
+ 'https://gitlab.com/gitlab-org/incubation-engineering/mlops/rb-ipynbdiff'
17
+ s.license = 'MIT'
18
+
19
+ s.require_paths = ['lib']
20
+
21
+ s.add_runtime_dependency 'diffy', '3.3.0'
22
+ s.add_runtime_dependency 'json', '2.5.1'
23
+
24
+ s.add_development_dependency 'bundler', '~> 2.2'
25
+ s.add_development_dependency 'guard-rspec'
26
+ s.add_development_dependency 'pry'
27
+ s.add_development_dependency 'rake'
28
+ s.add_development_dependency 'rspec'
29
+ end
data/lib/ipynbdiff.rb ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Human Readable Jupyter Diffs
4
+ module IpynbDiff
5
+ require 'transformer.rb'
6
+ require 'diffy'
7
+
8
+ @default_options = {
9
+ preprocess_input: TRUE,
10
+ write_output_to: nil,
11
+ format: :text,
12
+ sources_are_files: FALSE,
13
+ diff_opts: {
14
+ include_diff_info: FALSE
15
+ }
16
+ }.freeze
17
+
18
+ def self.prepare_input(to_prepare, load_from_file, preprocess)
19
+ prepared = to_prepare
20
+ prepared = File.read(prepared) if load_from_file
21
+ prepared = Transformer.transform(prepared) if preprocess
22
+
23
+ prepared
24
+ end
25
+
26
+ def self.diff(
27
+ from_notebook,
28
+ to_notebook,
29
+ options = {}
30
+ )
31
+ options = @default_options.merge(options)
32
+
33
+ from = prepare_input(from_notebook, options[:sources_are_files], options[:preprocess_input])
34
+ to = prepare_input(to_notebook, options[:sources_are_files], options[:preprocess_input])
35
+
36
+ d = Diffy::Diff.new(from, to, **options[:diff_opts]).to_s(options[:format])
37
+
38
+ File.write(options[:write_output_to], d) if options[:write_output_to]
39
+
40
+ d
41
+ end
42
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IpynbDiff
4
+ # Returns a markdown version of the Jupyter Notebook
5
+ class Transformer
6
+ require 'json'
7
+ require 'yaml'
8
+
9
+ def self.transform(notebook, include_metadata: TRUE)
10
+ notebook_json = JSON.parse(notebook)
11
+ transformed_blocks = notebook_json['cells'].map { |cell| transform_cell(cell, notebook_json) }
12
+ transformed_blocks.prepend(transform_metadata(notebook_json)) if include_metadata
13
+ transformed_blocks.join("\n")
14
+ end
15
+
16
+ def self.transform_cell(cell, notebook)
17
+ cell['cell_type'] == 'code' ? transform_code_cell(cell, notebook) : transform_text_cell(cell)
18
+ end
19
+
20
+ def self.transform_code_cell(cell, notebook)
21
+ tags = cell['metadata'].fetch('tags', []).join(' ')
22
+
23
+ [
24
+ %(<div class="cell code" data-id="#{cell['id']}" data-tags="#{tags}">\n\n),
25
+ %(``` #{notebook['metadata']['kernelspec']['language']}\n),
26
+ *cell['source'],
27
+ "\n```\n",
28
+ *cell['outputs'].map { |output| transform_output(output) },
29
+ "\n</div>\n"
30
+ ].join('')
31
+ end
32
+
33
+ def self.format_traceback(traceback)
34
+ traceback.map do |t|
35
+ t.split("\n").map do |line|
36
+ line.gsub(/\[[0-9][0-9;]*m/, '').sub("\u001B", ' ').gsub(/\u001B/, '').rstrip
37
+ end
38
+ end.join("\n")
39
+ end
40
+
41
+ def self.transform_execute_result(output)
42
+ [
43
+ %(\n<div class="output execute_result">\n\n),
44
+ *output['data']['text/plain'].map { |line| " #{line}" },
45
+ "\n\n</div>\n"
46
+ ].join('')
47
+ end
48
+
49
+ def self.transform_image_result(output)
50
+ if output['data'].key?('image/png')
51
+ [
52
+ %(\n<div class="output display_data">\n\n),
53
+ "![](data:image/png;base64,#{output['data']['image/png'].gsub("\n", '')})",
54
+ "\n\n</div>\n"
55
+ ].join('')
56
+ end
57
+ end
58
+
59
+ def self.transform_error_result(output)
60
+ [
61
+ %(\n<div class="output error">\n\n),
62
+ format_traceback(output['traceback']),
63
+ "\n\n</div>\n"
64
+ ].join('')
65
+ end
66
+
67
+ def self.transform_output(output)
68
+ case output['output_type']
69
+ when 'execute_result'
70
+ transform_execute_result(output)
71
+ when 'display_data'
72
+ transform_image_result(output)
73
+ when 'error'
74
+ transform_error_result(output)
75
+ end
76
+ end
77
+
78
+ def self.transform_text_cell(cell)
79
+ tags = cell['metadata'].fetch('tags', []).join(' ')
80
+ id = cell['id']
81
+ cell_type = cell['cell_type']
82
+
83
+ [
84
+ %(<div class="cell #{cell_type}" data-id="#{id}" data-tags="#{tags}">\n\n),
85
+ *cell['source'],
86
+ "\n\n</div>\n"
87
+ ].join('')
88
+ end
89
+
90
+ def self.transform_metadata(notebook_json)
91
+ {
92
+ 'jupyter' => {
93
+ 'kernelspec' => notebook_json['metadata']['kernelspec'],
94
+ 'language_info' => notebook_json['metadata']['language_info'],
95
+ 'nbformat' => notebook_json['nbformat'],
96
+ 'nbformat_minor' => notebook_json['nbformat_minor']
97
+ }
98
+ }.to_yaml + "---\n"
99
+ end
100
+ end
101
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ipynbdiff
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ platform: ruby
6
+ authors:
7
+ - Eduardo Bonet
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-10-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: diffy
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 2.5.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 2.5.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A simple hello world gem
112
+ email: ebonet@gitlab.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - ".gitignore"
118
+ - Gemfile
119
+ - Gemfile.lock
120
+ - README.md
121
+ - ipynbdiff.gemspec
122
+ - lib/ipynbdiff.rb
123
+ - lib/transformer.rb
124
+ homepage: https://gitlab.com/gitlab-org/incubation-engineering/mlops/rb-ipynbdiff
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubygems_version: 3.1.6
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Human Readble diffs for Jupyter Notebooks
147
+ test_files: []