solvebio 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.travis.yml +13 -0
- data/Gemfile +4 -0
- data/Gemspec +3 -0
- data/LICENSE +21 -0
- data/Makefile +17 -0
- data/README.md +64 -0
- data/Rakefile +59 -0
- data/bin/solvebio.rb +36 -0
- data/demo/README.md +14 -0
- data/demo/dataset/facets.rb +13 -0
- data/demo/dataset/field.rb +13 -0
- data/demo/depository/README.md +24 -0
- data/demo/depository/all.rb +13 -0
- data/demo/depository/retrieve.rb +13 -0
- data/demo/depository/versions-all.rb +13 -0
- data/demo/query/query-filter.rb +30 -0
- data/demo/query/query.rb +13 -0
- data/demo/query/range-filter.rb +18 -0
- data/demo/test-api.rb +98 -0
- data/lib/apiresource.rb +130 -0
- data/lib/cli/auth.rb +122 -0
- data/lib/cli/help.rb +13 -0
- data/lib/cli/irb.rb +58 -0
- data/lib/cli/irbrc.rb +53 -0
- data/lib/cli/options.rb +75 -0
- data/lib/client.rb +152 -0
- data/lib/credentials.rb +67 -0
- data/lib/errors.rb +81 -0
- data/lib/filter.rb +312 -0
- data/lib/help.rb +46 -0
- data/lib/locale.rb +47 -0
- data/lib/main.rb +37 -0
- data/lib/query.rb +415 -0
- data/lib/resource.rb +414 -0
- data/lib/solvebio.rb +14 -0
- data/lib/solveobject.rb +101 -0
- data/lib/tabulate.rb +706 -0
- data/solvebio.gemspec +75 -0
- data/test/data/netrc-save +6 -0
- data/test/helper.rb +3 -0
- data/test/test-auth.rb +54 -0
- data/test/test-client.rb +27 -0
- data/test/test-error.rb +36 -0
- data/test/test-filter.rb +70 -0
- data/test/test-netrc.rb +42 -0
- data/test/test-query-batch.rb +60 -0
- data/test/test-query-init.rb +29 -0
- data/test/test-query-paging.rb +123 -0
- data/test/test-query.rb +88 -0
- data/test/test-resource.rb +47 -0
- data/test/test-solveobject.rb +27 -0
- data/test/test-tabulate.rb +127 -0
- metadata +158 -0
data/lib/apiresource.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require_relative 'solveobject'
|
3
|
+
require_relative 'client'
|
4
|
+
|
5
|
+
class SolveBio::APIResource < SolveBio::SolveObject
|
6
|
+
|
7
|
+
def self.retrieve(cls, id, params={})
|
8
|
+
instance = cls.new(id, params)
|
9
|
+
instance.refresh()
|
10
|
+
return instance
|
11
|
+
end
|
12
|
+
|
13
|
+
def refresh
|
14
|
+
refresh_from request('get', instance_url)
|
15
|
+
return self
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.class_url(cls)
|
19
|
+
# cls_name = cls.class_name()
|
20
|
+
cls_name = cls.to_s.sub('SolveBio::', '')
|
21
|
+
# pluralize
|
22
|
+
if cls_name.end_with?('y')
|
23
|
+
cls_name = cls_name[0..-2] + 'ie'
|
24
|
+
end
|
25
|
+
cls_name = camelcase_to_underscore(cls_name)
|
26
|
+
return "/v1/#{cls_name}s"
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# Get instance URL by ID or full name (if available)
|
31
|
+
def instance_url
|
32
|
+
id = self['id']
|
33
|
+
base = SolveBio::APIResource.class_url(self.class)
|
34
|
+
|
35
|
+
if id
|
36
|
+
return "#{base}/#{id}"
|
37
|
+
else
|
38
|
+
msg = 'Could not determine which URL to request: %s instance ' +
|
39
|
+
'has invalid ID: %s' % [self.class, id]
|
40
|
+
raise Exception, msg
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module SolveBio::ListableAPIResource
|
46
|
+
|
47
|
+
def self.included base
|
48
|
+
base.extend ClassMethods
|
49
|
+
end
|
50
|
+
|
51
|
+
module ClassMethods
|
52
|
+
def all(params={})
|
53
|
+
url = SolveBio::APIResource.class_url(self)
|
54
|
+
response = SolveBio::Client.client.request('get', url, params)
|
55
|
+
return response.to_solvebio
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
module SolveBio::SearchableAPIResource
|
62
|
+
|
63
|
+
def self.included base
|
64
|
+
base.extend ClassMethods
|
65
|
+
end
|
66
|
+
|
67
|
+
module ClassMethods
|
68
|
+
def search(query='', params={})
|
69
|
+
params['q'] = query
|
70
|
+
url = SolveBio::APIResource.class_url(self)
|
71
|
+
response = SolveBio::Client.client.request('get', url, params)
|
72
|
+
return response.to_solvebio
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module SolveBio::CreateableAPIResource
|
78
|
+
|
79
|
+
def self.included base
|
80
|
+
base.extend ClassMethods
|
81
|
+
end
|
82
|
+
|
83
|
+
module ClassMethods
|
84
|
+
def create(params={})
|
85
|
+
url = SolveBio::APIResource.class_url(self)
|
86
|
+
response = SolveBio::Client.client.request('post', url, params)
|
87
|
+
return to_solve_object(response)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
module SolveBio::UpdateableAPIResource
|
93
|
+
|
94
|
+
def self.included base
|
95
|
+
base.extend ClassMethods
|
96
|
+
end
|
97
|
+
|
98
|
+
module ClassMethods
|
99
|
+
def save
|
100
|
+
refresh_from(request('patch', instance_url(),
|
101
|
+
serialize(self)))
|
102
|
+
return self
|
103
|
+
end
|
104
|
+
|
105
|
+
def serialize(obj)
|
106
|
+
params = {}
|
107
|
+
if obj.unsaved_values
|
108
|
+
obj.unsaved_values.each do |k|
|
109
|
+
next if k == 'id'
|
110
|
+
params[k] = getattr(obj, k) or ''
|
111
|
+
end
|
112
|
+
end
|
113
|
+
return params
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class SolveBio::DeletableAPIResource
|
119
|
+
def self.included base
|
120
|
+
base.extend ClassMethods
|
121
|
+
end
|
122
|
+
|
123
|
+
module ClassMethods
|
124
|
+
|
125
|
+
def delete(params={})
|
126
|
+
refresh_from(request('delete', instance_url(), params))
|
127
|
+
return self
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
data/lib/cli/auth.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'readline'
|
5
|
+
require 'io/console'
|
6
|
+
|
7
|
+
require_relative '../errors'
|
8
|
+
require_relative '../credentials'
|
9
|
+
require_relative '../client'
|
10
|
+
|
11
|
+
module SolveBio::Auth
|
12
|
+
|
13
|
+
def ask_for_credentials(email=nil)
|
14
|
+
while true
|
15
|
+
email ||= Readline.readline('Email address: ', true)
|
16
|
+
print 'Password (typing will be hidden): '
|
17
|
+
password = STDIN.noecho(&:gets).chomp
|
18
|
+
puts
|
19
|
+
# FIXME: validate email address?
|
20
|
+
if email and password
|
21
|
+
return email, password
|
22
|
+
else
|
23
|
+
# FIXME: could say which one is needed.
|
24
|
+
print 'Email and password are both required.'
|
25
|
+
return nil, nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def send_install_report
|
31
|
+
require 'socket';
|
32
|
+
data = {
|
33
|
+
:hostname => Socket.gethostname(),
|
34
|
+
:ruby_version => SolveBio::RUBY_VERSION,
|
35
|
+
:ruby_implementation => SolveBio::RUBY_IMPLEMENTATION,
|
36
|
+
# :platform => platform(),
|
37
|
+
:architecture => SolveBio::ARCHITECTURE,
|
38
|
+
# :processor => processor(),
|
39
|
+
}
|
40
|
+
SolveBio::Client.client.request('post',
|
41
|
+
'/v1/reports/install',
|
42
|
+
data) rescue nil
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
include SolveBio::Credentials
|
47
|
+
|
48
|
+
module_function
|
49
|
+
|
50
|
+
#
|
51
|
+
# Prompt user for login information (email/password).
|
52
|
+
# Email and password are used to get the user's auth_token key.
|
53
|
+
#
|
54
|
+
def login(email=nil, password=nil)
|
55
|
+
delete_credentials
|
56
|
+
|
57
|
+
email, password = ask_for_credentials email unless
|
58
|
+
email and password
|
59
|
+
data = {
|
60
|
+
:email => email,
|
61
|
+
:password => password
|
62
|
+
}
|
63
|
+
|
64
|
+
# FIXME: begin/rescue is a direct translation of the Python
|
65
|
+
# code. Not sure if it's valid here, or what the equivalent
|
66
|
+
# is.
|
67
|
+
begin
|
68
|
+
response = SolveBio::Client.
|
69
|
+
client.request('post', '/v1/auth/token', data)
|
70
|
+
rescue SolveBio::Error => e
|
71
|
+
puts "Login failed: #{e.to_s}"
|
72
|
+
return false
|
73
|
+
else
|
74
|
+
save_credentials(email.downcase, response['token'])
|
75
|
+
# reset the default client's auth token
|
76
|
+
SolveBio::Client.client.api_key = response['token']
|
77
|
+
send_install_report
|
78
|
+
puts 'You are now logged-in.'
|
79
|
+
return true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def logout
|
84
|
+
if get_credentials()
|
85
|
+
delete_credentials()
|
86
|
+
SolveBio::Client.client.api_key = nil
|
87
|
+
puts 'You have been logged out.'
|
88
|
+
return true
|
89
|
+
else
|
90
|
+
puts 'You are not logged-in.'
|
91
|
+
return false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def whoami
|
96
|
+
creds = get_credentials()
|
97
|
+
if creds
|
98
|
+
puts creds[0]
|
99
|
+
return creds[0]
|
100
|
+
else
|
101
|
+
puts 'You are not logged-in.'
|
102
|
+
return nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end # SolveBio::Auth
|
107
|
+
|
108
|
+
# Demo code
|
109
|
+
if __FILE__ == $0
|
110
|
+
include SolveBio::Auth
|
111
|
+
case ARGV[0]
|
112
|
+
when 'password'
|
113
|
+
email, password = ask_for_credentials
|
114
|
+
puts email, password
|
115
|
+
when 'login'
|
116
|
+
login
|
117
|
+
when 'logout'
|
118
|
+
logout
|
119
|
+
when 'whoami'
|
120
|
+
whoami
|
121
|
+
end
|
122
|
+
end
|
data/lib/cli/help.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module SolveBio
|
2
|
+
# Shell help
|
3
|
+
def help
|
4
|
+
puts <<-HELP
|
5
|
+
Constants SAMPLE_DEPO, SAMPLE_DEPO_VERSION, and SAMPLE_DATASET are
|
6
|
+
available for and example depository, depository_versions or dataset.
|
7
|
+
|
8
|
+
By setting environment variable SOLVEBIO_IRBRC, you can add your own
|
9
|
+
custom irb profile.
|
10
|
+
HELP
|
11
|
+
end
|
12
|
+
module_function :help
|
13
|
+
end
|
data/lib/cli/irb.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# Open the SolveBio shell, an IRB wrapper
|
4
|
+
require 'irb'
|
5
|
+
require_relative 'help'
|
6
|
+
|
7
|
+
module IRB
|
8
|
+
|
9
|
+
# Stuff to add IRB commands goes here
|
10
|
+
# module ExtendCommand
|
11
|
+
# class SolveHelp
|
12
|
+
# def self.execute(conf, *opts)
|
13
|
+
# SolveBio::help
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
|
17
|
+
# end
|
18
|
+
|
19
|
+
module_function
|
20
|
+
|
21
|
+
# ExtendCommandBundle.def_extend_command 'solvehelp', :SolveHelp
|
22
|
+
|
23
|
+
def shell
|
24
|
+
|
25
|
+
# Set to run the standard trepan IRB profile
|
26
|
+
irbrc = File.
|
27
|
+
expand_path(File.join(File.dirname(__FILE__), 'irbrc.rb'))
|
28
|
+
|
29
|
+
# Start out with our custom profile
|
30
|
+
old_irbrc = ENV['IRBRC']
|
31
|
+
ENV['IRBRC'] = irbrc
|
32
|
+
IRB.setup(nil)
|
33
|
+
|
34
|
+
# If the user has an IRB profile or SolveBio IRB profile, run
|
35
|
+
# that now.
|
36
|
+
ENV['IRBRC'] = ENV['SOLVEBIO_IRBRC'] || old_irbrc
|
37
|
+
if ENV['IRBRC']
|
38
|
+
@CONF[:RC_NAME_GENERATOR]=nil
|
39
|
+
IRB.run_config
|
40
|
+
end
|
41
|
+
|
42
|
+
@CONF[:AUTO_INDENT] = true
|
43
|
+
workspace = IRB::WorkSpace.new
|
44
|
+
irb = IRB::Irb.new(workspace)
|
45
|
+
|
46
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
47
|
+
@CONF[:MAIN_CONTEXT] = irb.context
|
48
|
+
|
49
|
+
catch(:IRB_EXIT) do
|
50
|
+
irb.eval_input
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Demo it.
|
56
|
+
if __FILE__ == $0
|
57
|
+
IRB::shell
|
58
|
+
end
|
data/lib/cli/irbrc.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# irbrc profile for SolveBio
|
3
|
+
IRB.conf[:PROMPT_MODE] = :SIMPLE
|
4
|
+
IRB.conf[:PROMPT][:SIMPLE] = {
|
5
|
+
:PROMPT_C => '[SolveBio] In ?: ', # Prompt when continuing a statement
|
6
|
+
:PROMPT_I => '[SolveBio] In : ', # Normal prompt
|
7
|
+
:PROMPT_N => '[SolveBio] In +: ', # Prompt when indenting code
|
8
|
+
:PROMPT_S => '[SolveBio] In %l: ', # Prompt when continuing a string
|
9
|
+
:RETURN => "[SolveBio] Out : %s\n"
|
10
|
+
}
|
11
|
+
|
12
|
+
require_relative '../solvebio'
|
13
|
+
include SolveBio::Auth
|
14
|
+
|
15
|
+
# Set some demo names that can be used.
|
16
|
+
SAMPLE_DEPO = 'ClinVar'
|
17
|
+
SAMPLE_DEPO_VERSION = "#{SAMPLE_DEPO}/2.0.0-1"
|
18
|
+
SAMPLE_DATASET = "#{SAMPLE_DEPO_VERSION}/Variants"
|
19
|
+
|
20
|
+
have_completion = nil
|
21
|
+
begin
|
22
|
+
require 'bond' and require 'bond/completion'
|
23
|
+
have_completion = 'bond'
|
24
|
+
rescue LoadError
|
25
|
+
begin
|
26
|
+
have_completion = require 'irb/completion'
|
27
|
+
rescue LoadError
|
28
|
+
have_completion = false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
'irb/completion'
|
32
|
+
'bond' 'bond/completion'
|
33
|
+
|
34
|
+
puts <<-INTRO
|
35
|
+
You are in a SolveBio Interactive Ruby (irb) session...
|
36
|
+
Type SolveBio::help for help on SolveBio.
|
37
|
+
INTRO
|
38
|
+
|
39
|
+
unless have_completion
|
40
|
+
if have_completion != 'bond'
|
41
|
+
puts "You might get better completion using the 'bond' gem"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Report whether we are logged in.
|
46
|
+
include SolveBio::Credentials
|
47
|
+
creds = get_credentials()
|
48
|
+
if creds
|
49
|
+
puts "You are logged in as #{creds[0]}"
|
50
|
+
else
|
51
|
+
puts 'You are not logged in yet. Login using "login [email [, password]]"'
|
52
|
+
|
53
|
+
end
|
data/lib/cli/options.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# SolveBio Ruby command-line option processing
|
5
|
+
|
6
|
+
require 'optparse'
|
7
|
+
require_relative '../client'
|
8
|
+
|
9
|
+
module SolveBio::CLIOptions
|
10
|
+
|
11
|
+
PROGRAM = 'solvebio.rb'
|
12
|
+
|
13
|
+
def show_version
|
14
|
+
"#{PROGRAM}, version #{SolveBio::VERSION}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Main parser for the SolveBio command line client
|
18
|
+
def setup_options(options, stdout=$stdout, stderr=$stderr)
|
19
|
+
|
20
|
+
OptionParser.new do |opts|
|
21
|
+
opts.banner = "Usage: solvebio.rb [options] <command> [<args>]"
|
22
|
+
opts.on_tail('-v', '--version',
|
23
|
+
'print the version') do
|
24
|
+
options[:version] = true
|
25
|
+
stdout.puts "#{PROGRAM}, version #{SolveBio::VERSION}"
|
26
|
+
exit 0
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('--api-host NAME', String,
|
30
|
+
'Override the default SolveBio API host') do
|
31
|
+
|api_host|
|
32
|
+
options[:api_host] = api_host
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on('--api-key STRING', String,
|
36
|
+
'Manually provide a SolveBio API key') do
|
37
|
+
|api_key|
|
38
|
+
options[:api_key] = api_key
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on('-h', '--help', 'Display this screen') do
|
42
|
+
puts opts
|
43
|
+
puts <<-EOH
|
44
|
+
|
45
|
+
SolveBio Commands:
|
46
|
+
login [email] Login and save credentials. Use email if provided.
|
47
|
+
logout Logout and delete saved credentials
|
48
|
+
whoami Show your SolveBio email address
|
49
|
+
shell Open the SolveBio Python shell
|
50
|
+
test Make sure the SolveBio API is working correctly
|
51
|
+
EOH
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def process_options(argv)
|
60
|
+
options = {}
|
61
|
+
args = setup_options(options)
|
62
|
+
rest = args.parse argv
|
63
|
+
|
64
|
+
SolveBio::Client.client.api_host = options[:api_host] if
|
65
|
+
options[:api_host]
|
66
|
+
SolveBio::Client.client.api_key = options[:api_key] if
|
67
|
+
options[:api_key]
|
68
|
+
return options, rest, args
|
69
|
+
end
|
70
|
+
|
71
|
+
if __FILE__ == $0
|
72
|
+
include SolveBio::CLIOptions
|
73
|
+
options, rest, parser = process_options(ARGV)
|
74
|
+
p options, rest, parser
|
75
|
+
end
|