iruby 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +75 -2
- data/iruby.gemspec +0 -1
- data/lib/iruby.rb +11 -2
- data/lib/iruby/command.rb +8 -1
- data/lib/iruby/kernel.rb +1 -1
- data/lib/iruby/session/ffi_rzmq.rb +74 -0
- data/lib/iruby/session/mixin.rb +47 -0
- data/lib/iruby/{session.rb → session/rbczmq.rb} +4 -44
- data/lib/iruby/version.rb +1 -1
- metadata +5 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3315e60fa2fabec2327df00d481249757ce9c199
|
4
|
+
data.tar.gz: 33f5306f10e6f51f64483e63b96cc3055f75e118
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d314e35b4f4331892cb7bee54c6ca5aab5a3d86f058c8b34472672831da21d37e88093babeabb8d0daaadd1dc2ac5508310c3c3b5767c98b7ccee7d5d7335510
|
7
|
+
data.tar.gz: f3543ff4d8c01cddc5c9091ffd4d78d95c3a74b5baba7efd4dc0c122487048de55f84b117d077bdde4bc3e9a90ad4db484087df0ab246b1bddd359d4ffa10b42
|
data/README.md
CHANGED
@@ -7,7 +7,9 @@ This is a Ruby kernel for IPython/Jupyter and is part of [SciRuby](http://scirub
|
|
7
7
|

|
8
8
|
|
9
9
|
### Quick start
|
10
|
+
The installation instructions are divided according to environments mainly because of ZeroMQ.
|
10
11
|
|
12
|
+
#### Ubuntu/Debian
|
11
13
|
At first install IPython/Jupyter. I recommend an installation using virtualenv.
|
12
14
|
|
13
15
|
apt-get install python3-dev virtualenv libzmq3-dev
|
@@ -17,13 +19,83 @@ At first install IPython/Jupyter. I recommend an installation using virtualenv.
|
|
17
19
|
|
18
20
|
After that, install the Ruby gem.
|
19
21
|
|
22
|
+
gem install rbczmq
|
20
23
|
gem install iruby
|
21
24
|
|
22
25
|
Now you can run iruby with:
|
23
26
|
|
24
|
-
iruby
|
25
27
|
iruby notebook
|
26
28
|
|
29
|
+
#### Windows
|
30
|
+
At first install IPython/Jupyter. I recommend an installation using [Enthought Canopy](https://www.enthought.com/).
|
31
|
+
|
32
|
+
After that install libzmq.dll (v3.2.x, x86) from [the website of ZeroMQ](http://zeromq.org/area:download).
|
33
|
+
|
34
|
+
Rename `libzmq-v100-mt-3_x_x.dll` to `libzmq.dll`.
|
35
|
+
|
36
|
+
Add the path to /bin to the PATH system variable.
|
37
|
+
|
38
|
+
Run two commands below:
|
39
|
+
|
40
|
+
gem install ffi-rzmq
|
41
|
+
gem install iruby
|
42
|
+
|
43
|
+
Now you can run iruby with:
|
44
|
+
|
45
|
+
iruby notebook
|
46
|
+
|
47
|
+
#### Mac
|
48
|
+
I recommend an installation using [Anaconda](https://store.continuum.io/cshop/anaconda/).
|
49
|
+
I have not checked the installation to MacOS X, but four lines below were necessary in v0.1.x.
|
50
|
+
|
51
|
+
conda remove zeromq (If you installed anaconda)
|
52
|
+
brew install zeromq
|
53
|
+
gem install ffi-rzmq
|
54
|
+
gem install iruby
|
55
|
+
|
56
|
+
Send us pull-request if you Mac users successed in installing IRuby in another way.
|
57
|
+
|
58
|
+
#### FreeBSD
|
59
|
+
|
60
|
+
At first install IPython/Jupyter.
|
61
|
+
There is a pyzmq ports (ports/net/py-pyzmq) which depends on libzmq4, however, it doesn't works with ipython.
|
62
|
+
Therefore we use libzmq3 like the following:
|
63
|
+
|
64
|
+
1. make your ports tree up-to-date.
|
65
|
+
2. replace LIBDEPENDS line in ports/net/py-pyzmq/Makefile
|
66
|
+
|
67
|
+
```shell
|
68
|
+
LIB_DEPENDS= libzmq.so:${PORTSDIR}/net/libzmq4
|
69
|
+
```
|
70
|
+
with
|
71
|
+
```shell
|
72
|
+
LIB_DEPENDS= libzmq.so:${PORTSDIR}/net/libzmq3
|
73
|
+
```
|
74
|
+
3. install related packages
|
75
|
+
|
76
|
+
```shell
|
77
|
+
$ sudo pkg install libzmq3 py27-qt4-gui py27-pexpect-3.3 py27-qt4-svg py27-pygments py27-Jinja2 py27-tornado py27-jsonschema
|
78
|
+
```
|
79
|
+
4. make install using ports
|
80
|
+
|
81
|
+
```shell
|
82
|
+
$ cd /usr/ports/net/py-pyzmq
|
83
|
+
$ sudo make install
|
84
|
+
$ cd /usr/ports/devel/ipython
|
85
|
+
$ sudo make install
|
86
|
+
```
|
87
|
+
Then, install iruby and related ports and gems.
|
88
|
+
```shell
|
89
|
+
$ sudo pkg install rubygem-mimemagic
|
90
|
+
$ sudo gem install ffi-rzmq # install ffi, ffi-rzmq-core and ffi-rzmq
|
91
|
+
$ git clone https://github.com/SciRuby/iruby.git
|
92
|
+
$ cd iruby
|
93
|
+
$ gem build iruby.gemspec
|
94
|
+
$ sudo gem install iruby-0.2.7.gem
|
95
|
+
```
|
96
|
+
|
97
|
+
### After the installation
|
98
|
+
|
27
99
|
Take a look at the [example notebook](http://nbviewer.ipython.org/urls/raw.github.com/SciRuby/sciruby-notebooks/master/getting_started.ipynb)
|
28
100
|
and the [collection of notebooks](https://github.com/SciRuby/sciruby-notebooks/) which includes a Dockerfile to create a containerized installation of iruby
|
29
101
|
and other scientific gems. You can find the prebuild image at [dockerhub](https://registry.hub.docker.com/u/minad/sciruby-notebooks/).
|
@@ -32,9 +104,10 @@ and other scientific gems. You can find the prebuild image at [dockerhub](https:
|
|
32
104
|
### Required dependencies
|
33
105
|
|
34
106
|
* IPython/Jupyter >= 3.0.0
|
35
|
-
* libzmq >= 3.2
|
36
107
|
* Ruby >= 2.1.0
|
37
108
|
|
109
|
+
If you install IRuby with ffi-rzmq instead of rbczmq, libzmq >= 3.2 is added to the list above.
|
110
|
+
|
38
111
|
### Authors
|
39
112
|
|
40
113
|
See the [CONTRIBUTORS](CONTRIBUTORS) file.
|
data/iruby.gemspec
CHANGED
@@ -28,7 +28,6 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_development_dependency 'minitest', '~> 5.6'
|
29
29
|
|
30
30
|
s.add_runtime_dependency 'bond', '~> 0.5'
|
31
|
-
s.add_runtime_dependency 'rbczmq', '~> 1.7'
|
32
31
|
s.add_runtime_dependency 'multi_json', '~> 1.11'
|
33
32
|
s.add_runtime_dependency 'mimemagic', '~> 0.3'
|
34
33
|
end
|
data/lib/iruby.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'rbczmq'
|
2
1
|
require 'mimemagic'
|
3
2
|
require 'multi_json'
|
4
3
|
require 'securerandom'
|
@@ -8,9 +7,19 @@ require 'set'
|
|
8
7
|
require 'iruby/version'
|
9
8
|
require 'iruby/kernel'
|
10
9
|
require 'iruby/backend'
|
11
|
-
require 'iruby/session'
|
12
10
|
require 'iruby/ostream'
|
13
11
|
require 'iruby/formatter'
|
14
12
|
require 'iruby/utils'
|
15
13
|
require 'iruby/display'
|
16
14
|
require 'iruby/comm'
|
15
|
+
require 'iruby/session/mixin'
|
16
|
+
|
17
|
+
begin
|
18
|
+
require 'iruby/session/rbczmq'
|
19
|
+
rescue LoadError
|
20
|
+
begin
|
21
|
+
require 'iruby/session/ffi_rzmq'
|
22
|
+
rescue LoadError
|
23
|
+
STDERR.puts "You should install rbczmq or ffi_rzmq before running iruby notebook. See README."
|
24
|
+
end
|
25
|
+
end
|
data/lib/iruby/command.rb
CHANGED
@@ -115,8 +115,15 @@ Add `gem 'iruby'` to your Gemfile to fix it.} unless Bundler.definition.dependen
|
|
115
115
|
|
116
116
|
def register_kernel
|
117
117
|
FileUtils.mkpath(@kernel_dir)
|
118
|
-
|
118
|
+
unless RUBY_PLATFORM =~ /mswin(?!ce)|mingw|cygwin/
|
119
|
+
File.write(@kernel_file, MultiJson.dump(argv: [ @iruby_path, 'kernel', '{connection_file}' ],
|
119
120
|
display_name: "Ruby #{RUBY_VERSION}", language: 'ruby'))
|
121
|
+
else
|
122
|
+
ruby_path, iruby_path = [RbConfig.ruby, @iruby_path].map{|path| path.gsub('/', '\\\\')}
|
123
|
+
File.write(@kernel_file, MultiJson.dump(argv: [ ruby_path, iruby_path, 'kernel', '{connection_file}' ],
|
124
|
+
display_name: "Ruby #{RUBY_VERSION}", language: 'ruby'))
|
125
|
+
end
|
126
|
+
|
120
127
|
FileUtils.copy(Dir[File.join(__dir__, 'assets', '*')], @kernel_dir) rescue nil
|
121
128
|
end
|
122
129
|
|
data/lib/iruby/kernel.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'ffi-rzmq'
|
2
|
+
|
3
|
+
module IRuby
|
4
|
+
class Session
|
5
|
+
include SessionSerialize
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
c = ZMQ::Context.new
|
9
|
+
|
10
|
+
connection = "#{config['transport']}://#{config['ip']}:%d"
|
11
|
+
reply_socket = c.socket(ZMQ::XREP)
|
12
|
+
reply_socket.bind(connection % config['shell_port'])
|
13
|
+
|
14
|
+
pub_socket = c.socket(ZMQ::PUB)
|
15
|
+
pub_socket.bind(connection % config['iopub_port'])
|
16
|
+
|
17
|
+
Thread.new do
|
18
|
+
begin
|
19
|
+
hb_socket = c.socket(ZMQ::REP)
|
20
|
+
hb_socket.bind(connection % config['hb_port'])
|
21
|
+
ZMQ::Device.new(hb_socket, hb_socket)
|
22
|
+
rescue Exception => e
|
23
|
+
IRuby.logger.fatal "Kernel heartbeat died: #{e.message}\n#{e.backtrace.join("\n")}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@sockets = { publish: pub_socket, reply: reply_socket }
|
28
|
+
@session = SecureRandom.uuid
|
29
|
+
unless config['key'].to_s.empty? || config['signature_scheme'].to_s.empty?
|
30
|
+
raise 'Unknown signature scheme' unless config['signature_scheme'] =~ /\Ahmac-(.*)\Z/
|
31
|
+
@hmac = OpenSSL::HMAC.new(config['key'], OpenSSL::Digest.new($1))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Build and send a message
|
36
|
+
def send(socket, type, content)
|
37
|
+
idents =
|
38
|
+
if socket == :reply && @last_recvd_msg
|
39
|
+
@last_recvd_msg[:idents]
|
40
|
+
else
|
41
|
+
type == :stream ? "stream.#{content[:name]}" : type
|
42
|
+
end
|
43
|
+
header = {
|
44
|
+
msg_type: type,
|
45
|
+
msg_id: SecureRandom.uuid,
|
46
|
+
username: 'kernel',
|
47
|
+
session: @session,
|
48
|
+
version: '5.0'
|
49
|
+
}
|
50
|
+
socket = @sockets[socket]
|
51
|
+
list = serialize(idents, header, content)
|
52
|
+
list.each_with_index do |part, i|
|
53
|
+
socket.send_string(part, i == list.size - 1 ? 0 : ZMQ::SNDMORE)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Receive a message and decode it
|
58
|
+
def recv(socket)
|
59
|
+
socket = @sockets[socket]
|
60
|
+
msg = []
|
61
|
+
while msg.empty? || socket.more_parts?
|
62
|
+
begin
|
63
|
+
frame = ''
|
64
|
+
rc = socket.recv_string(frame, 1)
|
65
|
+
ZMQ::Util.error_check('zmq_msg_send', rc)
|
66
|
+
msg << frame
|
67
|
+
rescue
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
@last_recvd_msg = unserialize(msg)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module IRuby
|
2
|
+
module SessionSerialize
|
3
|
+
DELIM = '<IDS|MSG>'
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def serialize(idents, header, content)
|
8
|
+
msg = [MultiJson.dump(header),
|
9
|
+
MultiJson.dump(@last_recvd_msg ? @last_recvd_msg[:header] : {}),
|
10
|
+
'{}',
|
11
|
+
MultiJson.dump(content || {})]
|
12
|
+
frames = ([*idents].compact.map(&:to_s) << DELIM << sign(msg)) + msg
|
13
|
+
IRuby.logger.debug "Sent #{frames.inspect}"
|
14
|
+
frames
|
15
|
+
end
|
16
|
+
|
17
|
+
def unserialize(msg)
|
18
|
+
raise 'no message received' unless msg
|
19
|
+
frames = msg.to_a.map(&:to_s)
|
20
|
+
IRuby.logger.debug "Received #{frames.inspect}"
|
21
|
+
|
22
|
+
i = frames.index(DELIM)
|
23
|
+
idents, msg_list = frames[0..i-1], frames[i+1..-1]
|
24
|
+
|
25
|
+
minlen = 5
|
26
|
+
raise 'malformed message, must have at least #{minlen} elements' unless msg_list.length >= minlen
|
27
|
+
s, header, parent_header, metadata, content, buffers = *msg_list
|
28
|
+
raise 'Invalid signature' unless s == sign(msg_list[1..-1])
|
29
|
+
{
|
30
|
+
idents: idents,
|
31
|
+
header: MultiJson.load(header),
|
32
|
+
parent_header: MultiJson.load(parent_header),
|
33
|
+
metadata: MultiJson.load(metadata),
|
34
|
+
content: MultiJson.load(content),
|
35
|
+
buffers: buffers
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
# Sign using HMAC
|
40
|
+
def sign(list)
|
41
|
+
return '' unless @hmac
|
42
|
+
@hmac.reset
|
43
|
+
list.each {|m| @hmac.update(m) }
|
44
|
+
@hmac.hexdigest
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'rbczmq'
|
2
|
+
|
1
3
|
module IRuby
|
2
4
|
class Session
|
3
|
-
|
5
|
+
include SessionSerialize
|
4
6
|
|
5
7
|
def initialize(config)
|
6
8
|
c = ZMQ::Context.new
|
@@ -45,54 +47,12 @@ module IRuby
|
|
45
47
|
session: @session,
|
46
48
|
version: '5.0'
|
47
49
|
}
|
48
|
-
@sockets[socket].send_message(serialize(idents, header, content))
|
50
|
+
@sockets[socket].send_message(ZMQ::Message(*serialize(idents, header, content)))
|
49
51
|
end
|
50
52
|
|
51
53
|
# Receive a message and decode it
|
52
54
|
def recv(socket)
|
53
55
|
@last_recvd_msg = unserialize(@sockets[socket].recv_message)
|
54
56
|
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def serialize(idents, header, content)
|
59
|
-
msg = [MultiJson.dump(header),
|
60
|
-
MultiJson.dump(@last_recvd_msg ? @last_recvd_msg[:header] : {}),
|
61
|
-
'{}',
|
62
|
-
MultiJson.dump(content || {})]
|
63
|
-
frames = ([*idents].compact.map(&:to_s) << DELIM << sign(msg)) + msg
|
64
|
-
IRuby.logger.debug "Sent #{frames.inspect}"
|
65
|
-
ZMQ::Message(*frames)
|
66
|
-
end
|
67
|
-
|
68
|
-
def unserialize(msg)
|
69
|
-
raise 'no message received' unless msg
|
70
|
-
frames = msg.to_a.map(&:to_s)
|
71
|
-
IRuby.logger.debug "Received #{frames.inspect}"
|
72
|
-
|
73
|
-
i = frames.index(DELIM)
|
74
|
-
idents, msg_list = frames[0..i-1], frames[i+1..-1]
|
75
|
-
|
76
|
-
minlen = 5
|
77
|
-
raise 'malformed message, must have at least #{minlen} elements' unless msg_list.length >= minlen
|
78
|
-
s, header, parent_header, metadata, content, buffers = *msg_list
|
79
|
-
raise 'Invalid signature' unless s == sign(msg_list[1..-1])
|
80
|
-
{
|
81
|
-
idents: idents,
|
82
|
-
header: MultiJson.load(header),
|
83
|
-
parent_header: MultiJson.load(parent_header),
|
84
|
-
metadata: MultiJson.load(metadata),
|
85
|
-
content: MultiJson.load(content),
|
86
|
-
buffers: buffers
|
87
|
-
}
|
88
|
-
end
|
89
|
-
|
90
|
-
# Sign using HMAC
|
91
|
-
def sign(list)
|
92
|
-
return '' unless @hmac
|
93
|
-
@hmac.reset
|
94
|
-
list.each {|m| @hmac.update(m) }
|
95
|
-
@hmac.hexdigest
|
96
|
-
end
|
97
57
|
end
|
98
58
|
end
|
data/lib/iruby/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Mendler
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-12-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -53,20 +53,6 @@ dependencies:
|
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0.5'
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
name: rbczmq
|
58
|
-
requirement: !ruby/object:Gem::Requirement
|
59
|
-
requirements:
|
60
|
-
- - "~>"
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '1.7'
|
63
|
-
type: :runtime
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - "~>"
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '1.7'
|
70
56
|
- !ruby/object:Gem::Dependency
|
71
57
|
name: multi_json
|
72
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -127,7 +113,9 @@ files:
|
|
127
113
|
- lib/iruby/kernel.rb
|
128
114
|
- lib/iruby/logger.rb
|
129
115
|
- lib/iruby/ostream.rb
|
130
|
-
- lib/iruby/session.rb
|
116
|
+
- lib/iruby/session/ffi_rzmq.rb
|
117
|
+
- lib/iruby/session/mixin.rb
|
118
|
+
- lib/iruby/session/rbczmq.rb
|
131
119
|
- lib/iruby/utils.rb
|
132
120
|
- lib/iruby/version.rb
|
133
121
|
- logo/logo-32x32.png
|
@@ -172,4 +160,3 @@ test_files:
|
|
172
160
|
- test/integration_test.rb
|
173
161
|
- test/iruby/multi_logger_test.rb
|
174
162
|
- test/test_helper.rb
|
175
|
-
has_rdoc:
|