algorithmia 0.2.0 → 0.9.0
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/.gitignore +12 -1
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +3 -3
- data/LICENSE +21 -0
- data/README.md +196 -0
- data/Rakefile +6 -63
- data/algorithmia.gemspec +22 -24
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/algorithmia.rb +28 -15
- data/lib/algorithmia/algorithm.rb +49 -0
- data/lib/algorithmia/client.rb +21 -0
- data/lib/algorithmia/data_directory.rb +91 -0
- data/lib/algorithmia/data_file.rb +55 -0
- data/lib/algorithmia/data_object.rb +26 -0
- data/lib/algorithmia/errors.rb +19 -5
- data/lib/algorithmia/requester.rb +104 -0
- data/lib/algorithmia/response.rb +39 -0
- data/lib/algorithmia/unauthenticated_client.rb +7 -0
- data/lib/algorithmia/version.rb +3 -7
- metadata +56 -36
- data/.ruby-version +0 -1
- data/LICENSE.txt +0 -8
- data/algorithmia.png +0 -0
- data/lib/algorithmia/authentication.rb +0 -24
- data/lib/algorithmia/base.rb +0 -14
- data/lib/algorithmia/http.rb +0 -33
- data/lib/algorithmia/result.rb +0 -25
- data/readme.markdown +0 -37
- data/spec/algorithmia_spec.rb +0 -17
    
        data/bin/setup
    ADDED
    
    
    
        data/lib/algorithmia.rb
    CHANGED
    
    | @@ -1,18 +1,31 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 1 | 
            +
            require_relative 'algorithmia/algorithm'
         | 
| 2 | 
            +
            require_relative 'algorithmia/client'
         | 
| 3 | 
            +
            require_relative 'algorithmia/unauthenticated_client'
         | 
| 4 | 
            +
            require_relative 'algorithmia/errors'
         | 
| 5 | 
            +
            require_relative 'algorithmia/requester'
         | 
| 6 | 
            +
            require_relative 'algorithmia/response'
         | 
| 7 | 
            +
            require_relative 'algorithmia/version'
         | 
| 8 | 
            +
            require_relative 'algorithmia/data_object'
         | 
| 9 | 
            +
            require_relative 'algorithmia/data_file'
         | 
| 10 | 
            +
            require_relative 'algorithmia/data_directory'
         | 
| 4 11 |  | 
| 5 | 
            -
             | 
| 12 | 
            +
            module Algorithmia
         | 
| 6 13 |  | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
            require 'algorithmia/result'
         | 
| 12 | 
            -
            require 'algorithmia/http'
         | 
| 14 | 
            +
              class << self
         | 
| 15 | 
            +
                def algo(endpoint)
         | 
| 16 | 
            +
                  Algorithmia::UnauthenticatedClient.new.algo(endpoint)
         | 
| 17 | 
            +
                end
         | 
| 13 18 |  | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            +
                def file(data_uri)
         | 
| 20 | 
            +
                  Algorithmia::UnauthenticatedClient.new.file(data_uri)
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def dir(data_uri)
         | 
| 24 | 
            +
                  Algorithmia::UnauthenticatedClient.new.dir(data_uri)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def client(api_key)
         | 
| 28 | 
            +
                  Algorithmia::Client.new(api_key)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            module Algorithmia
         | 
| 2 | 
            +
              class Algorithm
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def initialize(client, endpoint)
         | 
| 5 | 
            +
                  @client = client
         | 
| 6 | 
            +
                  @endpoint = '/v1/algo/' + endpoint
         | 
| 7 | 
            +
                  @query = {
         | 
| 8 | 
            +
                    timeout: 300,
         | 
| 9 | 
            +
                    stdout: false,
         | 
| 10 | 
            +
                    output: 'default'
         | 
| 11 | 
            +
                  }
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def set_options(options_hash)
         | 
| 15 | 
            +
                  @query_options.update(options_hash)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def set_timeout(timeout)
         | 
| 19 | 
            +
                  @query_options[:timeout] = timeout.to_i
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def enable_stdout
         | 
| 23 | 
            +
                  @query_options[:stdout] = true
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def pipe(input)
         | 
| 27 | 
            +
                  content_type = case
         | 
| 28 | 
            +
                    when input.kind_of?(String) && input.encoding == Encoding::ASCII_8BIT
         | 
| 29 | 
            +
                      'application/octet-stream'
         | 
| 30 | 
            +
                    when input.kind_of?(String)
         | 
| 31 | 
            +
                      'text/plain'
         | 
| 32 | 
            +
                    else
         | 
| 33 | 
            +
                      'application/json'
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  headers = {
         | 
| 37 | 
            +
                    'Content-Type' => content_type
         | 
| 38 | 
            +
                  }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  response = Algorithmia::Requester.new(@client).post(@endpoint, input, query: @query, headers: headers)
         | 
| 41 | 
            +
                  Algorithmia::Response.new(response.parsed_response)
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def pipe_json(input)
         | 
| 45 | 
            +
                  response = Algorithmia::Requester.new(@client).post(@endpoint, input, query: @query, headers: {})
         | 
| 46 | 
            +
                  Algorithmia::Response.new(response.parsed_response)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            module Algorithmia
         | 
| 2 | 
            +
              class Client
         | 
| 3 | 
            +
                attr_reader :api_key
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(api_key)
         | 
| 6 | 
            +
                  @api_key = api_key
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def algo(endpoint)
         | 
| 10 | 
            +
                  Algorithmia::Algorithm.new(self, endpoint)
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def file(endpoint)
         | 
| 14 | 
            +
                  Algorithmia::DataFile.new(self, endpoint)
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def dir(endpoint)
         | 
| 18 | 
            +
                  Algorithmia::DataDirectory.new(self, endpoint)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,91 @@ | |
| 1 | 
            +
            require 'uri'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Algorithmia
         | 
| 4 | 
            +
              class DataDirectory < DataObject
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def exists?
         | 
| 7 | 
            +
                  Algorithmia::Requester.new(@client).get(@url)
         | 
| 8 | 
            +
                  true
         | 
| 9 | 
            +
                rescue Errors::NotFoundError
         | 
| 10 | 
            +
                  false
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def create
         | 
| 14 | 
            +
                  parent, name = File.split(@url)
         | 
| 15 | 
            +
                  Algorithmia::Requester.new(@client).post(parent, name: name)
         | 
| 16 | 
            +
                  true
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def delete(force = false)
         | 
| 20 | 
            +
                  query = {}
         | 
| 21 | 
            +
                  query[:force] = true if force
         | 
| 22 | 
            +
                  Algorithmia::Requester.new(@client).delete(@url, query: query)
         | 
| 23 | 
            +
                  true
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def each(&block)
         | 
| 27 | 
            +
                  return enum_for(:each) unless block_given?
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  list(block) do |dir|
         | 
| 30 | 
            +
                    extract_files(dir) + extract_folders(dir)
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def each_file(&block)
         | 
| 35 | 
            +
                  return enum_for(:each_file) unless block_given?
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  list(block) do |dir|
         | 
| 38 | 
            +
                    extract_files(dir)
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def each_dir(&block)
         | 
| 43 | 
            +
                  return enum_for(:each_dir) unless block_given?
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  list(block) do |dir|
         | 
| 46 | 
            +
                    extract_folders(dir)
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def file(file_name)
         | 
| 51 | 
            +
                  @client.file(URI.encode(File.join(@data_uri, file_name)))
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def put_file(file_path)
         | 
| 55 | 
            +
                  file(File.basename(file_path)).put_file(file_path)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                private
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def extract_files(dir)
         | 
| 61 | 
            +
                  files = dir.parsed_response['files'] || []
         | 
| 62 | 
            +
                  files.map do |f|
         | 
| 63 | 
            +
                    file(f['filename'])
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def extract_folders(dir)
         | 
| 68 | 
            +
                  folders = dir.parsed_response['folders'] || []
         | 
| 69 | 
            +
                  folders.map do |f|
         | 
| 70 | 
            +
                    @client.dir(URI.encode(File.join(@data_uri, f['name'])))
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def list(each_proc)
         | 
| 75 | 
            +
                  marker = nil
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  loop do
         | 
| 78 | 
            +
                    query = {}
         | 
| 79 | 
            +
                    query[:marker] = marker if marker
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                    dir = Algorithmia::Requester.new(@client).get(@url, query: query)
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    items = yield dir
         | 
| 84 | 
            +
                    items.each(&each_proc)
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    marker = dir.parsed_response['marker']
         | 
| 87 | 
            +
                    break unless marker && !marker.empty?
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            require 'tempfile'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Algorithmia
         | 
| 4 | 
            +
              class DataFile < DataObject
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def exists?
         | 
| 7 | 
            +
                  Algorithmia::Requester.new(@client).head(@url)
         | 
| 8 | 
            +
                  true
         | 
| 9 | 
            +
                rescue Errors::NotFoundError
         | 
| 10 | 
            +
                  false
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def get_file
         | 
| 14 | 
            +
                  response = get
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  tempfile = Tempfile.open(File.basename(@url)) do |f|
         | 
| 17 | 
            +
                    f.write response
         | 
| 18 | 
            +
                    f
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  File.new(tempfile.path)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def get
         | 
| 25 | 
            +
                  Algorithmia::Requester.new(@client).get(@url).body
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def put(data)
         | 
| 29 | 
            +
                  content_type = case
         | 
| 30 | 
            +
                    when data.kind_of?(String) && data.encoding == Encoding::ASCII_8BIT
         | 
| 31 | 
            +
                      'application/octet-stream'
         | 
| 32 | 
            +
                    when data.kind_of?(String)
         | 
| 33 | 
            +
                      'text/plain'
         | 
| 34 | 
            +
                    else
         | 
| 35 | 
            +
                      'application/json'
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  headers = {'Content-Type' => content_type }
         | 
| 39 | 
            +
                  Algorithmia::Requester.new(@client).put(@url, data, headers: headers)
         | 
| 40 | 
            +
                  true
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                alias_method :put_json, :put
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def put_file(file_path)
         | 
| 46 | 
            +
                  data = File.binread(file_path)
         | 
| 47 | 
            +
                  put(data)
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def delete
         | 
| 51 | 
            +
                  Algorithmia::Requester.new(@client).delete(@url)
         | 
| 52 | 
            +
                  true
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            module Algorithmia
         | 
| 2 | 
            +
              class DataObject
         | 
| 3 | 
            +
                attr_reader :data_uri
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(client, data_uri)
         | 
| 6 | 
            +
                  @client = client
         | 
| 7 | 
            +
                  @data_uri = data_uri
         | 
| 8 | 
            +
                  sanitize_data_uri
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def basename
         | 
| 12 | 
            +
                  File.basename(@url)
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def parent
         | 
| 16 | 
            +
                  @client.dir(File.split(@data_uri).first)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                private
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def sanitize_data_uri
         | 
| 22 | 
            +
                  file_path = @data_uri.gsub('data://', '')
         | 
| 23 | 
            +
                  @url = File.join('/v1/data/', file_path)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
    
        data/lib/algorithmia/errors.rb
    CHANGED
    
    | @@ -1,6 +1,20 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 1 | 
            +
            module Algorithmia
         | 
| 2 | 
            +
              module Errors
         | 
| 3 | 
            +
                class Error < StandardError
         | 
| 4 | 
            +
                  attr_reader :response
         | 
| 4 5 |  | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 6 | 
            +
                  def initialize(message, response)
         | 
| 7 | 
            +
                    super(message)
         | 
| 8 | 
            +
                    @response = response
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                class ApiKeyEmptyError < Error; end
         | 
| 13 | 
            +
                class ApiKeyInvalidError < Error; end
         | 
| 14 | 
            +
                class InternalServerError < Error; end
         | 
| 15 | 
            +
                class JsonParseError < Error; end
         | 
| 16 | 
            +
                class NotFoundError < Error; end
         | 
| 17 | 
            +
                class UnauthorizedError < Error; end
         | 
| 18 | 
            +
                class UnknownError < Error; end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,104 @@ | |
| 1 | 
            +
            require 'httparty'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Algorithmia
         | 
| 4 | 
            +
              class Requester
         | 
| 5 | 
            +
                include HTTParty
         | 
| 6 | 
            +
                base_uri "https://api.algorithmia.com"
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def initialize(client)
         | 
| 9 | 
            +
                  @client = client
         | 
| 10 | 
            +
                  @default_headers = {
         | 
| 11 | 
            +
                    'Authorization' => @client.api_key || '',
         | 
| 12 | 
            +
                    'Content-Type' => 'application/json',
         | 
| 13 | 
            +
                    'User-Agent' => 'Algorithmia Ruby Client'
         | 
| 14 | 
            +
                  }
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def get(endpoint, query: {}, headers: {})
         | 
| 18 | 
            +
                  headers = merge_headers(headers)
         | 
| 19 | 
            +
                  response = self.class.get(endpoint, query: query, headers: headers)
         | 
| 20 | 
            +
                  check_for_errors(response)
         | 
| 21 | 
            +
                  response
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def post(endpoint, body, query: {}, headers: {})
         | 
| 25 | 
            +
                  headers = merge_headers(headers)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  if headers['Content-Type'] == 'application/json'
         | 
| 28 | 
            +
                    body = body.to_json
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  response = self.class.post(endpoint, body: body, query: query, headers: headers)
         | 
| 32 | 
            +
                  check_for_errors(response)
         | 
| 33 | 
            +
                  response
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def put(endpoint, body, query: {}, headers: {})
         | 
| 37 | 
            +
                  headers = merge_headers(headers)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  if headers['Content-Type'] == 'application/json'
         | 
| 40 | 
            +
                    body = body.to_json
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  response = self.class.put(endpoint, body: body, query: query, headers: headers)
         | 
| 44 | 
            +
                  check_for_errors(response)
         | 
| 45 | 
            +
                  response
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def head(endpoint)
         | 
| 49 | 
            +
                  response = self.class.head(endpoint, headers: @default_headers)
         | 
| 50 | 
            +
                  check_for_errors(response)
         | 
| 51 | 
            +
                  response
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def delete(endpoint, query: {})
         | 
| 55 | 
            +
                  response = self.class.delete(endpoint, query: query, headers: @default_headers)
         | 
| 56 | 
            +
                  check_for_errors(response)
         | 
| 57 | 
            +
                  response
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                private
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def check_for_errors(response)
         | 
| 63 | 
            +
                  if response.code >= 200 && response.code < 300
         | 
| 64 | 
            +
                    parse_error_message(response) if response['error']
         | 
| 65 | 
            +
                    return
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
             | 
| 69 | 
            +
                  case response.code
         | 
| 70 | 
            +
                  when 401
         | 
| 71 | 
            +
                    raise Errors::UnauthorizedError.new("The request you are making requires authorization. Please check that you have permissions & that you've set your API key.", response)
         | 
| 72 | 
            +
                  when 400
         | 
| 73 | 
            +
                    parse_error_message(response)
         | 
| 74 | 
            +
                  when 404
         | 
| 75 | 
            +
                    raise Errors::NotFoundError.new("The URI requested is invalid or the resource requested does not exist.", response)
         | 
| 76 | 
            +
                  when 500
         | 
| 77 | 
            +
                    raise Errors::InternalServerError.new("Whoops! Something is broken.", response)
         | 
| 78 | 
            +
                  else
         | 
| 79 | 
            +
                    raise Errors::UnknownError.new("The error you encountered returned the message: #{response["error"]["message"]} with stacktrace: #{error["stacktrace"]}", response)
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def parse_error_message(response)
         | 
| 84 | 
            +
                  error = response['error']
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  case error["message"]
         | 
| 87 | 
            +
                  when 'authorization required'
         | 
| 88 | 
            +
                    raise Errors::ApiKeyInvalidError.new("The API key you sent is invalid! Please set `Algorithmia::Client.api_key` with the key provided with your account.", response)
         | 
| 89 | 
            +
                  when 'Failed to parse input, input did not parse as valid json'
         | 
| 90 | 
            +
                    raise Errors::JsonParseError.new("Unable to parse the input. Please make sure it matches the expected input of the algorithm and can be parsed into JSON.", response)
         | 
| 91 | 
            +
                  else
         | 
| 92 | 
            +
                    if error["stacktrace"].nil?
         | 
| 93 | 
            +
                      raise Errors::UnknownError.new("The error you encountered returned the message: #{error["message"]}", response)
         | 
| 94 | 
            +
                    else
         | 
| 95 | 
            +
                      raise Errors::UnknownError.new("The error you encountered returned the message: #{error["message"]} with stacktrace: #{error["stacktrace"]}", response)
         | 
| 96 | 
            +
                    end
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                def merge_headers(headers = {})
         | 
| 101 | 
            +
                  @default_headers.merge(headers)
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
              end
         | 
| 104 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            require "base64"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Algorithmia
         | 
| 4 | 
            +
              class Response
         | 
| 5 | 
            +
                attr_reader :json
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(result)
         | 
| 8 | 
            +
                  @json = result
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def result
         | 
| 12 | 
            +
                  if content_type == 'binary'
         | 
| 13 | 
            +
                    Base64.decode64(@json["result"])
         | 
| 14 | 
            +
                  else
         | 
| 15 | 
            +
                    @json["result"]
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def metadata
         | 
| 20 | 
            +
                  @json["metadata"]
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def duration
         | 
| 24 | 
            +
                  metadata["duration"]
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def content_type
         | 
| 28 | 
            +
                  metadata["content_type"]
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def stdout
         | 
| 32 | 
            +
                  metadata["stdout"]
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def alerts
         | 
| 36 | 
            +
                  metadata["alerts"]
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         |