cloudalign-cli 0.1.1

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.
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: []