Topic has a solution
Log in or register to post comments

Cloud Recognition & Rails

August 6, 2021 - 9:00pm #1
Topic solved

I'm struggling to encode the body of my Image Recognition query with Ruby on Rails.  Has anyone done this and can you help? 

I have been successful with Python and even copied the signatures and encoded file from Python and successfully made a query from Rails - I just can't get the encoding to work.

Thanks!

Cloud Recognition & Rails

August 9, 2021 - 11:53pm #2

Answering my own question, based on Python solution on this site.

module VwsQuery

  class Api

    def initialize(accesskey = nil, secretkey = nil)

      @accesskey = accesskey || Rails.application.credentials.VWS_CLIENT_ACCESS_KEY

      @secretkey = secretkey || Rails.application.credentials.VWS_CLIENT_SECRET

      @boundary = '----------ThIs_Is_tHe_bouNdaRY_$'

    end

    def build_signature(body_hash, timestamp)

      content_type = 'multipart/form-data'

      # the request should have a request body, so create an md5 hash of that

      # json body data

      hex_digest = Digest::MD5.hexdigest(body_hash)

      string_to_sign = "POST\n" +

                       hex_digest + "\n" +

                       content_type + "\n" +

                       timestamp + "\n" \

                       '/v1/query'

      # Rails.logger.debug "STRING_TO_SIGN: \n#{string_to_sign}"

      Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new,

                                           @secretkey, string_to_sign))

    end

    def encode_multipart_formdata(fields, filename)

      crlf = 13.chr + 10.chr

      lines = []

      fields.each do |key, value|

        lines << '--' + @boundary

        lines << "Content-Disposition: form-data; name=\"#{key}\""

        lines << ''

        lines << value

      end

      lines << '--' + @boundary

      lines << "Content-Disposition: form-data; name=\"image\"; filename=\"#{filename}\""

      lines << 'Content-Type: image/jpeg'

      lines << ''

      lines << File.open(filename, 'r:UTF-8', &:read)

      lines << '--' + @boundary + '--'

      lines << ''

      body = lines.join(crlf)

      body

    end

    def query_targets(file_path, target_data, max_results)

      date_timestamp = Time.now.httpdate

      query_url = 'https://cloudreco.vuforia.com/v1/query'

      body_hash = encode_multipart_formdata({ 'include_target_data' => target_data, 'max_num_results' => max_results }, file_path)

      signature = build_signature(body_hash, date_timestamp)

      raise ArgumentError, 'Signature returned nil. Aborting...' if signature.nil?

      authorization_header = 'VWS ' + @accesskey + ':' + signature

      content_type = "multipart/form-data; boundary=#{@boundary}"

      headers = {

        'Date' => date_timestamp,

        'Content-Type' => content_type,

        'Authorization' => authorization_header,

        'Accept' => 'application/json'

      }

      begin

        HTTParty.post(query_url,

                      body: body_hash,

                      headers: headers)

      rescue StandardError => e

        Rails.logger.debug 'HTTParty Error:', e

      end

    end

  end

end

Log in or register to post comments