cloudalign-cli 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Introduction
2
+ This is a Command Line Interface (CLI) to be used for accessing a remote CloudAlign system and interacting with it. This
3
+ tool is useful for creating scripts or other automated processes that one would need to interface with CloudAlign.
4
+
5
+ Also included with this tool is a simple Ruby library for talking to CloudAlign directly.
6
+
7
+ ## Installation
8
+
9
+ ### Dependencies
10
+ - Ruby 1.9.3 or greater
11
+ - RubyGems (http://www.rubygems.org ships with 1.9.x)
12
+ - A Unix like OS (Tested with Ubuntu 12 and Mac OSX)
13
+
14
+ ### Setup
15
+ Simply install the CloudAlign CLI using GEM
16
+ <pre>
17
+ $ gem install cloudalign-cli
18
+ </pre>
19
+
20
+ ### Configuration
21
+ Create a config file
22
+ <pre>
23
+ $ mkdir -p ~/cloudalign
24
+ $ vi ~/cloudalign/config.yml
25
+ </pre>
26
+
27
+ Finally, populate the config file with your credentials
28
+ <pre>
29
+ # File ~/cloudalign/config.yml
30
+ api_url: http://web1.dev.cloudalign.accetia.com
31
+ api_user: jmccaffrey
32
+ api_password: shhhitssecret
33
+ </pre>
34
+
35
+ ## Usage
36
+
37
+ ### Supported Commands
38
+ Here are the supported operations with the current version of the CloudAlign Command Line Interface (CLI). Also listed
39
+ with each operation is a sample of how to use it.
40
+
41
+ #### Access Help Documentation
42
+ <pre>
43
+ $ cloudalign
44
+ Tasks:
45
+ cloudalign artifact <command> # Manipulate artifacts in the CloudAlign system
46
+ cloudalign help [TASK] # Describe available tasks or one specific task
47
+ cloudalign project <command> # Manipulate projects in the CloudAlign system
48
+
49
+ $ cloudalign artifact
50
+ cloudalign artifact align ARTIFACT # ...
51
+ cloudalign artifact compare ARTIFACT REFERENCE # ...
52
+ cloudalign artifact download ARTIFACT FILE # Downloads file FILE ...
53
+ cloudalign artifact help [COMMAND] # Describe subcommands...
54
+ cloudalign artifact list_files ARTIFACT # Lists all files in ...
55
+
56
+ $ cloudalign project
57
+ cloudalign project help [COMMAND] # Describe subcommands or...
58
+ cloudalign project list # Lists all viewable proj...
59
+ cloudalign project list_artifacts PROJECT # Lists all viewable arti...
60
+ cloudalign project upload_file PROJECT PATH # Uploads a file located ...
61
+
62
+ $ cloudalign project help list
63
+ Usage:
64
+ cloudalign list
65
+
66
+ Lists all viewable projects for your user
67
+ </pre>
68
+
69
+ #### List Projects
70
+ <pre>
71
+ $ cloudalign project list
72
+ +----+-----------------+
73
+ | id | name |
74
+ +----+-----------------+
75
+ | 1 | My Test Project |
76
+ +----+-----------------+
77
+ | 2 | asdf |
78
+ +----+-----------------+
79
+
80
+ </pre>
81
+
82
+ #### List Artifacts in a Project
83
+ <pre>
84
+ $ cloudalign project list_artifacts 2
85
+ +----+-----------+
86
+ | id | name |
87
+ +----+-----------+
88
+ | 20 | 40mb_file |
89
+ +----+-----------+
90
+ </pre>
91
+
92
+ #### List Files within an Artifact
93
+ <pre>
94
+ $ cloudalign artifact list_files 20
95
+ +-----+---------------+----------+--------+
96
+ | id | name | size | status |
97
+ +-----+---------------+----------+--------+
98
+ | 137 | 40mb_file.bin | 41943040 | READY |
99
+ +-----+---------------+----------+--------+
100
+ </pre>
101
+
102
+ #### Download a File
103
+ <pre>
104
+ $ cloudalign file download 20 137
105
+ Downloading file 40mb_file.bin from Artifact 20 to ./
106
+ ...
107
+ Done
108
+ </pre>
109
+
110
+ #### Upload a File and Create Artifact
111
+ <pre>
112
+ $ cloudalign project upload 2 test.fastq
113
+ Uploading file test.fastq to project 'asdf'
114
+ ...
115
+ Done
116
+ </pre>
117
+
118
+ #### Run BWA Alignment
119
+ <pre>
120
+ $ cloudalign artifact 20 align
121
+ Running alignment on artifact 'Test Artifact 123', use artifact list_files to see the status.
122
+ </pre>
data/bin/cloudalign ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift 'lib'
3
+ require "cloudalign"
4
+ require "thor"
5
+ require "thor/group"
6
+ require "pp"
7
+ require "formatador"
8
+
9
+ class ProjectTask < Thor
10
+ desc "list", "Lists all viewable projects for your user"
11
+ def list
12
+ projects = CloudAlign::Project.find_all.map do |p|
13
+ {
14
+ :id => p.id,
15
+ :name => p.name
16
+ }
17
+ end
18
+
19
+ Formatador.display_table(projects)
20
+ end
21
+
22
+ desc "list_artifacts PROJECT", "Lists all viewable artifacts in <PROJECT>"
23
+ def list_artifacts(project_id)
24
+ artifacts = CloudAlign::Artifact.find_by_project(project_id).map do |a|
25
+ {
26
+ :id => a.id,
27
+ :name => a.name,
28
+ }
29
+ end
30
+
31
+ Formatador.display_table(artifacts)
32
+ end
33
+
34
+ desc "upload_file PROJECT PATH", "Uploads a file located at PATH to the PROJECT in CloudAlign"
35
+ def upload_file(project_id, path)
36
+ project = CloudAlign::Project.find(project_id)
37
+ puts "Uploading file #{File.basename(path)} to project '#{project.name}'"
38
+ puts "..."
39
+ project.upload_file(path)
40
+ puts "Done"
41
+ end
42
+
43
+ end
44
+
45
+ class ArtifactTask < Thor
46
+ desc "list_files ARTIFACT", "Lists all files in <ARTIFACT>"
47
+ def list_files(artifact_id)
48
+ files = CloudAlign::File.find_by_artifact(artifact_id).map do |f|
49
+ {
50
+ :id => f.id,
51
+ :name => f.name,
52
+ :size => f.size,
53
+ :status => f.status
54
+ }
55
+ end
56
+
57
+ Formatador.display_table(files)
58
+ end
59
+
60
+ desc "download ARTIFACT FILE", "Downloads file FILE from the ARTIFACT in CloudAlign"
61
+ def download(artifact_id, file_id)
62
+ file = CloudAlign::File.find(artifact_id, file_id)
63
+ puts "Downloading file #{file.file_name} from Artifact #{file.artifact_id} to ./"
64
+ puts "..."
65
+ file.download
66
+ puts "Done"
67
+ end
68
+
69
+ desc "align ARTIFACT", "..."
70
+ def align(artifact_id)
71
+ artifact = CloudAlign::Artifact.find(artifact_id)
72
+ artifact.analyze(:bwa_alignment)
73
+ end
74
+
75
+ desc "compare ARTIFACT REFERENCE", "..."
76
+ def compare(artifact_id, reference)
77
+ puts "Not Implemented!"
78
+ end
79
+ end
80
+
81
+ class CLI < Thor
82
+ register(ProjectTask, 'project', 'project <command>', 'Manipulate projects in the CloudAlign system')
83
+ register(ArtifactTask, 'artifact', 'artifact <command>', 'Manipulate artifacts in the CloudAlign system')
84
+ end
85
+
86
+ CLI.start
@@ -0,0 +1,24 @@
1
+ module CloudAlign
2
+ class Artifact < BaseEntity
3
+ attr_accessor :name, :description
4
+
5
+ class << self
6
+
7
+ def find_by_project(project_id)
8
+ Client.get_json("/projects/#{project_id}/artifacts").map do |row|
9
+ Artifact.new(row)
10
+ end
11
+ end
12
+
13
+ end
14
+
15
+ def analyze(analyzer, options = {})
16
+ options[:analyzer] = analyzer
17
+ Client.post("/artifacts/#{@id}/analyze", options)
18
+ end
19
+
20
+ def destroy
21
+ Client.delete("/artifacts/#{@id}")
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ module CloudAlign
2
+ class BaseEntity
3
+ attr_accessor :id, :created_at, :updated_at
4
+
5
+ def initialize(args = {})
6
+ args.each do |k,v|
7
+ instance_variable_set("@#{k}", v) unless v.nil?
8
+ end
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,74 @@
1
+ require 'rest-client'
2
+ require 'cgi'
3
+
4
+ class String
5
+ def starts_with?(prefix)
6
+ prefix = prefix.to_s
7
+ self[0, prefix.length] == prefix
8
+ end
9
+ end
10
+
11
+ module CloudAlign
12
+ class Client
13
+
14
+ class << self
15
+ def get(path)
16
+ RestClient.get(authorized_url(path))
17
+ end
18
+
19
+ def get_json(path)
20
+ uri = URI.parse(path)
21
+ uri.path += '.json' unless uri.path.match(/\.json$|\/$/)
22
+ JSON.parse(get(uri.to_s))
23
+ end
24
+
25
+ def delete(path)
26
+ RestClient.delete(authorized_url(path))
27
+ end
28
+
29
+ def get_file(path, output_path)
30
+ ::File.open(output_path, 'w') do |out|
31
+ process_response = lambda do |response|
32
+ response.read_body do |chunk|
33
+ print "."
34
+ out.write chunk
35
+ end
36
+ end
37
+
38
+ RestClient::Request.execute(:method => :get, :url => authorized_url(path), :block_response => process_response)
39
+ end
40
+ end
41
+
42
+ def post(path, data)
43
+ RestClient.post(authorized_url(path), data)
44
+ end
45
+
46
+ def post_for_upload(path, data)
47
+ pp data
48
+ RestClient.post(authorized_url(path), data) do |response, request, result, &block|
49
+ if [301, 302, 303, 307].include? response.code
50
+ return get_json(response.headers[:location])
51
+ end
52
+ end
53
+ end
54
+
55
+ def authorized_url(path)
56
+ url = CloudAlign.config.get("api_url", "http://api.cloudalign.com").sub(/\/$/, '')
57
+
58
+ if path.starts_with?(url)
59
+ uri = URI.parse(path)
60
+ elsif path.starts_with?('/')
61
+ uri = URI.parse(url)
62
+ uri.path = path
63
+ else
64
+ return path
65
+ end
66
+
67
+ uri.user = CGI.escape(CloudAlign.config.get("api_user"))
68
+ uri.password = CGI.escape(CloudAlign.config.get("api_password"))
69
+
70
+ uri.to_s
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,46 @@
1
+ require 'yaml'
2
+ require 'pathname'
3
+
4
+ module CloudAlign
5
+ class Config
6
+ def initialize(path = nil)
7
+ @config = {}
8
+ load path
9
+ end
10
+
11
+ def set(key, value)
12
+ set_recursive(key, value, @config)
13
+ end
14
+
15
+ def get(key, default = nil)
16
+ p = @config
17
+ key.split('.').each do |part|
18
+ return default unless p.has_key? part
19
+ p = p[part]
20
+ end
21
+
22
+ p
23
+ end
24
+
25
+ def load(path = nil)
26
+ if path.nil?
27
+ config_paths = [Pathname.new(Dir.home).join('.cloudalign', 'config.yml').to_s]
28
+ path = config_paths.detect{|p| ::File.exists?(p)}
29
+ end
30
+
31
+ @config = YAML.load_file(path)
32
+ end
33
+
34
+ private
35
+
36
+ def set_recursive(key, value, array)
37
+ if key.include? '.'
38
+ (part, key) = key.split('.', 2)
39
+ array[part] = {} unless array.has_key? part
40
+ return set_recursive(key, value, array[part])
41
+ end
42
+
43
+ array[key] = value
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,34 @@
1
+ module CloudAlign
2
+ class File < BaseEntity
3
+ attr_accessor :name, :storage_path, :size, :ready
4
+
5
+ def download(output_path = nil)
6
+ output_path = self.file_name if output_path.nil?
7
+ download_info = Client.get_json("/artifacts/#{@artifact_id}/files/#{@id}/download")
8
+ Client.get_file(download_info["download_url"], output_path)
9
+ end
10
+
11
+ def file_name
12
+ ::File.basename(@storage_path)
13
+ end
14
+
15
+ def status
16
+ statuses = %w(READY BUILDING UPLOADING)
17
+ (@status >= 0 && @status < statuses.length) ? statuses[@status] : @status
18
+ end
19
+
20
+ class << self
21
+
22
+ def find(artifact_id, id)
23
+ File.new(Client.get_json("/artifacts/#{artifact_id}/files/#{id}"))
24
+ end
25
+
26
+ def find_by_artifact(artifact_id)
27
+ Client.get_json("/artifacts/#{artifact_id}/files").map do |row|
28
+ File.new(row)
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ module CloudAlign
2
+ class Project < BaseEntity
3
+ attr_accessor :name, :description
4
+
5
+ def self.find(id)
6
+ Project.new(Client.get_json("/projects/#{id}"))
7
+ end
8
+
9
+ def self.find_all
10
+ Client.get_json("/projects").map do |row|
11
+ Project.new(row)
12
+ end
13
+ end
14
+
15
+ def upload_file(path)
16
+ post_data = Client.get_json("/projects/#{@id}/upload_file")
17
+ upload_url = post_data.delete("url")
18
+ post_data[:file] = ::File.new(path, 'rb')
19
+
20
+ Client.post_for_upload(upload_url, post_data)
21
+ end
22
+
23
+ end
24
+ end
data/lib/cloudalign.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'json'
2
+ require 'logger'
3
+ require 'pathname'
4
+
5
+ module CloudAlign
6
+ autoload :BaseEntity, 'cloudalign/base_entity'
7
+ autoload :Client, 'cloudalign/client'
8
+ autoload :Project, 'cloudalign/project'
9
+ autoload :Artifact, 'cloudalign/artifact'
10
+ autoload :File, 'cloudalign/file'
11
+ autoload :Config, 'cloudalign/config'
12
+
13
+ API_VERSION = 1
14
+
15
+ class Error < StandardError; end
16
+
17
+ def self.logger
18
+ @logger ||= Logger.new(STDOUT)
19
+ end
20
+
21
+ def self.logger=(logger)
22
+ @logger = logger
23
+ end
24
+
25
+ def self.config
26
+ @config ||= Config.new
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloudalign-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jonathan McCaffrey
9
+ - Jeffrey Biles
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-08-30 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thor
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: rest-client
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: formatador
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: rspec
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ description: Cloudalign brings the power of the cloud straight to your lab
80
+ email:
81
+ executables:
82
+ - cloudalign
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - bin/cloudalign
87
+ - lib/cloudalign/artifact.rb
88
+ - lib/cloudalign/base_entity.rb
89
+ - lib/cloudalign/client.rb
90
+ - lib/cloudalign/config.rb
91
+ - lib/cloudalign/file.rb
92
+ - lib/cloudalign/project.rb
93
+ - lib/cloudalign.rb
94
+ - README.md
95
+ homepage: http://rubygems.org/gems/cloudalign-cli
96
+ licenses: []
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project: cloudalign-cli
115
+ rubygems_version: 1.8.24
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Access cloudalign from your command line
119
+ test_files: []