rosette_api 1.14.4 → 1.37.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +23 -16
  4. data/examples/README.md +2 -2
  5. data/examples/address_similarity.rb +7 -6
  6. data/examples/categories.rb +9 -8
  7. data/examples/entities.rb +8 -8
  8. data/examples/events.rb +23 -0
  9. data/examples/info.rb +7 -6
  10. data/examples/language.rb +7 -6
  11. data/examples/language_multilingual.rb +7 -6
  12. data/examples/morphology_complete.rb +7 -6
  13. data/examples/morphology_compound-components.rb +7 -6
  14. data/examples/morphology_han-readings.rb +7 -6
  15. data/examples/morphology_lemmas.rb +7 -6
  16. data/examples/morphology_parts-of-speech.rb +7 -6
  17. data/examples/multipart_language_file.rb +29 -0
  18. data/examples/name_deduplication.rb +7 -6
  19. data/examples/name_similarity.rb +9 -7
  20. data/examples/name_translation.rb +7 -6
  21. data/examples/ping.rb +7 -6
  22. data/examples/record_similarity.rb +114 -0
  23. data/examples/relationships.rb +7 -6
  24. data/examples/semantic_vectors.rb +7 -6
  25. data/examples/sentences.rb +7 -6
  26. data/examples/sentiment.rb +8 -7
  27. data/examples/similar_terms.rb +7 -6
  28. data/examples/syntax_dependencies.rb +7 -6
  29. data/examples/tokens.rb +7 -6
  30. data/examples/topics.rb +7 -6
  31. data/examples/transliteration.rb +7 -6
  32. data/lib/address_parameter.rb +3 -4
  33. data/lib/address_similarity_parameters.rb +13 -6
  34. data/lib/bad_request_error.rb +3 -3
  35. data/lib/bad_request_format_error.rb +3 -3
  36. data/lib/document_parameters.rb +10 -12
  37. data/lib/name_deduplication_parameters.rb +5 -8
  38. data/lib/name_parameter.rb +22 -5
  39. data/lib/name_similarity_parameters.rb +51 -21
  40. data/lib/name_translation_parameters.rb +17 -10
  41. data/lib/record_similarity_parameters.rb +68 -0
  42. data/lib/request_builder.rb +94 -54
  43. data/lib/rosette_api.rb +90 -50
  44. data/lib/rosette_api_error.rb +5 -4
  45. metadata +28 -33
@@ -4,26 +4,28 @@ require_relative 'bad_request_error'
4
4
  require_relative 'name_parameter'
5
5
 
6
6
  # This class encapsulates parameters that are needed for name-similarity in
7
- # Rosette API.
7
+ # Analytics API.
8
8
  class NameSimilarityParameters
9
9
  # genre to categorize the input data
10
10
  attr_accessor :genre
11
+ # Deprecated: Retained for backward compatibility. Use 'parameters' instead.
11
12
  # Rosette API options (optional, should be a hash)
12
13
  attr_accessor :rosette_options
14
+ # Parameters map sent to the API (optional, should be a hash)
15
+ attr_accessor :parameters
13
16
  # Name to be compared to name2
14
17
  attr_accessor :name1
15
18
  # Name to be compared to name1
16
19
  attr_accessor :name2
17
20
 
18
- def initialize(name1, name2, options = {}) #:notnew:
19
- options = {
20
- genre: nil,
21
- rosette_options: nil
22
- }.update options
23
- @genre = options[:genre]
21
+ def initialize(name1, name2, match_parameters = nil) # :notnew:
24
22
  @name1 = name1
25
23
  @name2 = name2
26
- @rosette_options = options[:rosette_options]
24
+ @genre = nil
25
+ @parameters = nil
26
+ @rosette_options = nil
27
+
28
+ handle_match_parameters(match_parameters) if match_parameters
27
29
  end
28
30
 
29
31
  # Validates the parameters by checking if name1 and name2 are instances of
@@ -35,10 +37,11 @@ class NameSimilarityParameters
35
37
  n2_msg = 'name2 option can only be an instance of a String or NameParameter'
36
38
  raise BadRequestError.new(n2_msg) if [String, NameParameter].none? { |clazz| @name2.is_a? clazz }
37
39
 
38
- opt_msg = 'rosette_options can only be an instance of a Hash'
39
- if @rosette_options
40
- raise BadRequestError.new(opt_msg) unless @rosette_options.is_a? Hash
41
- end
40
+ opt_msg = 'parameters can only be an instance of a Hash'
41
+ raise BadRequestError.new(opt_msg) if @parameters && !(@parameters.is_a? Hash)
42
+
43
+ rosette_opt_msg = 'rosette_options can only be an instance of a Hash'
44
+ raise BadRequestError.new(rosette_opt_msg) if @rosette_options && !(@rosette_options.is_a? Hash)
42
45
  end
43
46
 
44
47
  # Converts this class to Hash with its keys in lower CamelCase.
@@ -47,20 +50,47 @@ class NameSimilarityParameters
47
50
  def load_params
48
51
  validate_params
49
52
  to_hash
50
- .reject { |_key, value| value.nil? }
51
- .map { |key, value| [key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase), value] }
52
- .to_h
53
+ .compact
54
+ .transform_keys { |key| key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase) }
53
55
  end
54
56
 
55
57
  # Converts this class to Hash.
56
58
  #
57
59
  # Returns the new Hash.
58
60
  def to_hash
59
- {
60
- genre: @genre,
61
- name1: @name1.is_a?(NameParameter) ? @name1.load_param : @name1,
62
- name2: @name2.is_a?(NameParameter) ? @name2.load_param : @name2,
63
- options: @rosette_options
64
- }
61
+ if @parameters
62
+ {
63
+ name1: @name1.is_a?(NameParameter) ? @name1.load_param : @name1,
64
+ name2: @name2.is_a?(NameParameter) ? @name2.load_param : @name2,
65
+ parameters: @parameters
66
+ }
67
+ else
68
+ {
69
+ genre: @genre,
70
+ name1: @name1.is_a?(NameParameter) ? @name1.load_param : @name1,
71
+ name2: @name2.is_a?(NameParameter) ? @name2.load_param : @name2,
72
+ options: @rosette_options
73
+ }
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ # Processes the 3rd argument to determine if it is using the legacy 'options' signature
80
+ # or the new 'match_parameters' signature, and assigns instance variables accordingly.
81
+ def handle_match_parameters(match_parameters)
82
+ if legacy_options?(match_parameters)
83
+ warn 'DEPRECATION WARNING: Passing `options` dynamically via NameSimilarityParameters.new is deprecated. Please pass `parameters` instead.'
84
+ @genre = match_parameters[:genre] || match_parameters['genre']
85
+ @rosette_options = match_parameters[:rosette_options] || match_parameters['rosette_options']
86
+ else
87
+ @parameters = match_parameters
88
+ end
89
+ end
90
+
91
+ def legacy_options?(params)
92
+ return false unless params.is_a?(Hash)
93
+
94
+ params.key?(:genre) || params.key?('genre') || params.key?(:rosette_options) || params.key?('rosette_options')
65
95
  end
66
96
  end
@@ -3,7 +3,7 @@
3
3
  require_relative 'rosette_api_error'
4
4
 
5
5
  # This class encapsulates parameters that are needed for name-translation in
6
- # Rosette API.
6
+ # Analytics API.
7
7
  class NameTranslationParameters
8
8
  # Name's entity type (PERSON, LOCATION, ORGANIZATION) (optional)
9
9
  attr_accessor :entity_type
@@ -11,7 +11,7 @@ class NameTranslationParameters
11
11
  attr_accessor :genre
12
12
  # Name to translate
13
13
  attr_accessor :name
14
- # Rosette API options (optional, should be a hash)
14
+ # API options (optional, should be a hash)
15
15
  attr_accessor :rosette_options
16
16
  # ISO 693-3 code of the name's native language the name originates in
17
17
  # (optional)
@@ -26,11 +26,14 @@ class NameTranslationParameters
26
26
  attr_accessor :target_scheme
27
27
  # ISO 15924 code of name's script (optional)
28
28
  attr_accessor :target_script
29
+ # Maximum number of results to return (optional)
30
+ attr_accessor :maximum_results
29
31
 
30
- def initialize(name, target_language, options = {}) #:notnew:
32
+ def initialize(name, target_language, options = {}) # :notnew:
31
33
  options = {
32
34
  entity_type: nil,
33
35
  genre: nil,
36
+ maximum_results: nil,
34
37
  rosette_options: nil,
35
38
  source_language_of_origin: nil,
36
39
  source_language_of_use: nil,
@@ -41,6 +44,7 @@ class NameTranslationParameters
41
44
  @name = name
42
45
  @entity_type = options[:entity_type]
43
46
  @genre = options[:genre]
47
+ @maximum_results = options[:maximum_results]
44
48
  @rosette_options = options[:rosette_options]
45
49
  @source_language_of_origin = options[:source_language_of_origin]
46
50
  @source_language_of_use = options[:source_language_of_use]
@@ -54,9 +58,13 @@ class NameTranslationParameters
54
58
  # of a Hash.
55
59
  def validate_params
56
60
  msg = 'rosette_options can only be an instance of a Hash'
57
- if @rosette_options
58
- raise BadRequestError.new(msg) unless @rosette_options.is_a? Hash
59
- end
61
+ raise BadRequestError.new(msg) if @rosette_options && !(@rosette_options.is_a? Hash)
62
+
63
+ max_msg = 'maximum_results can only be an instance of an Integer'
64
+ raise BadRequestError.new(max_msg) if @maximum_results && !(@maximum_results.is_a? Integer)
65
+
66
+ max_range_msg = 'maximum_results must be greater than or equal to 0'
67
+ raise BadRequestError.new(max_range_msg) if @maximum_results&.negative?
60
68
  end
61
69
 
62
70
  # Converts this class to Hash with its keys in lower CamelCase.
@@ -66,8 +74,7 @@ class NameTranslationParameters
66
74
  validate_params
67
75
  to_hash
68
76
  .select { |_key, value| value }
69
- .map { |key, value| [key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase), value] }
70
- .to_h
77
+ .transform_keys { |key| key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase) }
71
78
  end
72
79
 
73
80
  # Converts this class to Hash.
@@ -76,7 +83,6 @@ class NameTranslationParameters
76
83
  def to_hash
77
84
  {
78
85
  entity_type: @entity_type,
79
- genre: @genre,
80
86
  name: @name,
81
87
  options: @rosette_options,
82
88
  source_language_of_origin: @source_language_of_origin,
@@ -84,7 +90,8 @@ class NameTranslationParameters
84
90
  source_script: @source_script,
85
91
  target_language: @target_language,
86
92
  target_scheme: @target_scheme,
87
- target_script: @target_script
93
+ target_script: @target_script,
94
+ maximum_results: @maximum_results
88
95
  }
89
96
  end
90
97
  end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'bad_request_error'
4
+
5
+ # This class encapsulates parameters that are needed for record-similarity in
6
+ # Analytics API.
7
+ class RecordSimilarityParameters
8
+ # Records to be compared (required)
9
+ attr_accessor :records
10
+
11
+ # Field names/definitions used for similarity scoring (required)
12
+ attr_accessor :fields
13
+
14
+ # Optional properties map sent to the API (optional, should be a hash)
15
+ attr_accessor :properties
16
+
17
+ def initialize(fields, records, properties = nil) # :notnew:
18
+ @fields = fields
19
+ @records = records
20
+ @properties = properties
21
+ end
22
+
23
+ # Validates the parameters by checking if required fields are present and
24
+ # optional properties is a Hash if provided.
25
+ def validate_params
26
+ f_msg = 'fields option is required'
27
+ raise BadRequestError.new(f_msg) if @fields.nil?
28
+
29
+ f_type_msg = 'fields can only be an instance of a Hash'
30
+ raise BadRequestError.new(f_type_msg) unless @fields.is_a? Hash
31
+
32
+ f_empty_msg = 'fields must not be empty'
33
+ raise BadRequestError.new(f_empty_msg) if @fields.empty?
34
+
35
+ r_msg = 'records option is required'
36
+ raise BadRequestError.new(r_msg) if @records.nil?
37
+
38
+ r_type_msg = 'records can only be an instance of a Hash'
39
+ raise BadRequestError.new(r_type_msg) unless @records.is_a? Hash
40
+
41
+ r_empty_msg = 'records must not be empty'
42
+ raise BadRequestError.new(r_empty_msg) if @records.empty?
43
+
44
+ p_msg = 'properties can only be an instance of a Hash'
45
+ raise BadRequestError.new(p_msg) if @properties && !(@properties.is_a? Hash)
46
+ end
47
+
48
+ # Converts this class to Hash with its keys in lower CamelCase.
49
+ #
50
+ # Returns the new Hash.
51
+ def load_params
52
+ validate_params
53
+ to_hash
54
+ .compact
55
+ .transform_keys { |key| key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase) }
56
+ end
57
+
58
+ # Converts this class to Hash.
59
+ #
60
+ # Returns the new Hash.
61
+ def to_hash
62
+ {
63
+ fields: @fields,
64
+ records: @records,
65
+ properties: @properties
66
+ }
67
+ end
68
+ end
@@ -6,17 +6,45 @@ require 'json'
6
6
  require 'securerandom'
7
7
  require_relative 'rosette_api_error'
8
8
 
9
- # This class handles all Rosette API requests.
9
+ # This class handles all Analytics API requests.
10
10
  class RequestBuilder
11
- # Alternate Rosette API URL
11
+ CONNECTION_ERROR_CODE = 'connectionError'
12
+ CONNECTION_ERROR_MESSAGE = 'Failed to establish connection with Analytics server.'
13
+
14
+ INVALID_HEADER_CODE = 'invalidHeader'
15
+ INVALID_HEADER_MESSAGE = 'Custom header must begin with "X-RosetteAPI-" or "X-BabelStreetAPI-"'
16
+
17
+ READ_MULTIPART_ERROR_CODE = 'readMultipartError'
18
+
19
+ HEADER_API_KEY = 'X-BabelStreetAPI-Key'
20
+ HEADER_CONTENT_TYPE = 'Content-Type'
21
+ HEADER_ACCEPT = 'Accept'
22
+ HEADER_USER_AGENT = 'User-Agent'
23
+ HEADER_BINDING_LEGACY = 'X-RosetteAPI-Binding'
24
+ HEADER_BINDING = 'X-BabelStreetAPI-Binding'
25
+ HEADER_BINDING_VERSION_LEGACY = 'X-RosetteAPI-Binding-Version'
26
+ HEADER_BINDING_VERSION = 'X-BabelStreetAPI-Binding-Version'
27
+
28
+ BINDING_NAME = 'ruby'
29
+
30
+ CONTENT_TYPE_JSON = 'application/json'
31
+ CONTENT_TYPE_TEXT_PLAIN = 'text/plain'
32
+ ACCEPT_JSON = 'application/json'
33
+
34
+ MULTIPART_FORM_DATA = 'multipart/form-data'
35
+
36
+ CUSTOM_HEADER_PREFIX_ROSETTE = /^X-RosetteAPI-/
37
+ CUSTOM_HEADER_PREFIX_BABELSTREET = /^X-BabelStreetAPI-/
38
+
39
+ # Alternate API URL
12
40
  attr_reader :alternate_url
13
- # Rosette API HTTP client
41
+ # API HTTP client
14
42
  attr_reader :http_client
15
43
  # Parameters to build the body of the request from
16
44
  attr_accessor :params
17
- # Rosette API key
45
+ # API key
18
46
  attr_accessor :user_key
19
- # Rosette API binding version
47
+ # API binding version
20
48
  attr_accessor :binding_version
21
49
  # User-Agent string
22
50
  attr_reader :user_agent
@@ -28,14 +56,14 @@ class RequestBuilder
28
56
  @http_client = http_client
29
57
  @binding_version = binding_version
30
58
  @params = params
31
- @user_agent = 'Ruby/' + binding_version + '/' + RUBY_VERSION
59
+ @user_agent = "Ruby/#{binding_version}/#{RUBY_VERSION}"
32
60
 
33
61
  return unless url_parameters
34
62
 
35
- @alternate_url = @alternate_url + '?' + URI.encode_www_form(url_parameters)
63
+ @alternate_url = "#{@alternate_url}?#{URI.encode_www_form(url_parameters)}"
36
64
  end
37
65
 
38
- # Prepares a plain POST request for Rosette API.
66
+ # Prepares a plain POST request for Analytics API.
39
67
  #
40
68
  # ==== Attributes
41
69
  #
@@ -50,8 +78,8 @@ class RequestBuilder
50
78
  # Not ideal. Consider switching to a different library.
51
79
  # https://stackoverflow.com/a/11802674
52
80
  raise RosetteAPIError.new(
53
- 'connectionError',
54
- 'Failed to establish connection with Rosette server.'
81
+ CONNECTION_ERROR_CODE,
82
+ CONNECTION_ERROR_MESSAGE
55
83
  )
56
84
  end
57
85
 
@@ -60,30 +88,32 @@ class RequestBuilder
60
88
  if custom_headers
61
89
  keys_array = custom_headers.keys
62
90
  keys_array.each do |key|
63
- if key.to_s =~ /^X-RosetteAPI-/
91
+ if key.to_s =~ CUSTOM_HEADER_PREFIX_ROSETTE || key.to_s =~ CUSTOM_HEADER_PREFIX_BABELSTREET
64
92
  request[key] = custom_headers[key]
65
93
  else
66
94
  raise RosetteAPIError.new(
67
- 'invalidHeader',
68
- 'Custom header must begin with "X-RosetteAPI-"'
95
+ INVALID_HEADER_CODE,
96
+ INVALID_HEADER_MESSAGE
69
97
  )
70
98
  end
71
99
  end
72
100
  params.delete 'customHeaders'
73
101
  end
74
102
 
75
- request['X-RosetteAPI-Key'] = @user_key
76
- request['Content-Type'] = 'application/json'
77
- request['Accept'] = 'application/json'
78
- request['User-Agent'] = @user_agent
79
- request['X-RosetteAPI-Binding'] = 'ruby'
80
- request['X-RosetteAPI-Binding-Version'] = @binding_version
103
+ request[HEADER_API_KEY] = @user_key
104
+ request[HEADER_CONTENT_TYPE] = CONTENT_TYPE_JSON
105
+ request[HEADER_ACCEPT] = ACCEPT_JSON
106
+ request[HEADER_USER_AGENT] = @user_agent
107
+ request[HEADER_BINDING_LEGACY] = BINDING_NAME
108
+ request[HEADER_BINDING] = BINDING_NAME
109
+ request[HEADER_BINDING_VERSION_LEGACY] = @binding_version
110
+ request[HEADER_BINDING_VERSION] = @binding_version
81
111
  request.body = params.to_json
82
112
 
83
113
  [@http_client, request]
84
114
  end
85
115
 
86
- # Prepares a multipart/form-data POST request for Rosette API.
116
+ # Prepares a multipart/form-data POST request for Analytics API.
87
117
  #
88
118
  # ==== Attributes
89
119
  #
@@ -91,29 +121,25 @@ class RequestBuilder
91
121
  #
92
122
  # Returns a HTTP connection and the built POST request.
93
123
  def prepare_multipart_request(params)
94
- begin
95
- file = File.open params['filePath'], 'r'
96
- text = file.read
97
- rescue StandardError => e
98
- raise RosetteAPIError.new('readMultipartError', e)
99
- end
124
+ text = read_multipart_file params['filePath']
100
125
 
101
126
  boundary = SecureRandom.hex
102
127
  post_body = []
103
- params.delete 'filePath'
104
- request_file = params.to_json
105
128
 
106
129
  # Add the content data
107
130
  post_body << "--#{boundary}\r\n"
108
131
  post_body << 'Content-Disposition: form-data; name="content"; ' \
109
- "filename=\"#{File.basename(file)}\"\r\n"
110
- post_body << "Content-Type: text/plain\r\n\r\n"
132
+ "filename=\"#{File.basename(params['filePath'])}\"\r\n"
133
+ post_body << "#{HEADER_CONTENT_TYPE}: #{CONTENT_TYPE_TEXT_PLAIN}\r\n\r\n"
111
134
  post_body << text
112
135
 
113
136
  # Add the request data
137
+ params.delete 'filePath'
138
+ request_file = params.to_json
139
+
114
140
  post_body << "\r\n\r\n--#{boundary}\r\n"
115
141
  post_body << "Content-Disposition: form-data; name=\"request\"\r\n"
116
- post_body << "Content-Type: application/json\r\n\r\n"
142
+ post_body << "#{HEADER_CONTENT_TYPE}: #{CONTENT_TYPE_JSON}\r\n\r\n"
117
143
  post_body << request_file
118
144
  post_body << "\r\n\r\n--#{boundary}--\r\n"
119
145
 
@@ -125,8 +151,8 @@ class RequestBuilder
125
151
  # Not ideal. Consider switching to a different library.
126
152
  # https://stackoverflow.com/a/11802674
127
153
  raise RosetteAPIError.new(
128
- 'connectionError',
129
- 'Failed to establish connection with Rosette API server.'
154
+ CONNECTION_ERROR_CODE,
155
+ CONNECTION_ERROR_MESSAGE
130
156
  )
131
157
  end
132
158
 
@@ -134,30 +160,43 @@ class RequestBuilder
134
160
  unless params['customHeaders'].nil?
135
161
  keys_array = params['customHeaders'].keys
136
162
  keys_array.each do |k|
137
- if k.to_s =~ /^X-RosetteAPI-/
163
+ if k.to_s =~ CUSTOM_HEADER_PREFIX_ROSETTE || k.to_s =~ CUSTOM_HEADER_PREFIX_BABELSTREET
138
164
  request.add_field k, params['customHeaders'][k]
139
165
  else
140
166
  raise RosetteAPIError.new(
141
- 'invalidHeader',
142
- 'Custom header must begin with "X-RosetteAPI-"'
167
+ INVALID_HEADER_CODE,
168
+ INVALID_HEADER_MESSAGE
143
169
  )
144
170
  end
145
171
  end
146
172
  params.delete 'customHeaders'
147
173
  end
148
174
 
149
- request.add_field 'Content-Type',
150
- "multipart/form-data; boundary=#{boundary}"
151
- request.add_field 'User-Agent', @user_agent
152
- request.add_field 'X-RosetteAPI-Key', @user_key
153
- request.add_field 'X-RosetteAPI-Binding', 'ruby'
154
- request.add_field 'X-RosetteAPI-Binding-Version', @binding_version
175
+ request.add_field HEADER_CONTENT_TYPE,
176
+ "#{MULTIPART_FORM_DATA}; boundary=#{boundary}"
177
+ request.add_field HEADER_USER_AGENT, @user_agent
178
+ request.add_field HEADER_API_KEY, @user_key
179
+ request.add_field HEADER_BINDING_LEGACY, BINDING_NAME
180
+ request.add_field HEADER_BINDING, BINDING_NAME
181
+ request.add_field HEADER_BINDING_VERSION_LEGACY, @binding_version
182
+ request.add_field HEADER_BINDING_VERSION, @binding_version
155
183
  request.body = post_body.join
156
184
 
157
185
  [@http_client, request]
158
186
  end
159
187
 
160
- # Sends a GET request to Rosette API.
188
+ # Reads the content of a file given its path.
189
+ #
190
+ # Returns the content of the file or raises error if encountered.
191
+ def read_multipart_file(file_path)
192
+ File.open(file_path, 'r') do |f|
193
+ return f.read
194
+ end
195
+ rescue StandardError => e
196
+ raise RosetteAPIError.new(READ_MULTIPART_ERROR_CODE, e)
197
+ end
198
+
199
+ # Sends a GET request to Analytics API.
161
200
  #
162
201
  # Returns JSON response or raises RosetteAPIError if encountered.
163
202
  def send_get_request
@@ -168,17 +207,17 @@ class RequestBuilder
168
207
  # Not ideal. Consider switching to a different library.
169
208
  # https://stackoverflow.com/a/11802674
170
209
  raise RosetteAPIError.new(
171
- 'connectionError',
172
- 'Failed to establish connection with Rosette API server.'
210
+ CONNECTION_ERROR_CODE,
211
+ CONNECTION_ERROR_MESSAGE
173
212
  )
174
213
  end
175
- request['X-RosetteAPI-Key'] = @user_key
176
- request['User-Agent'] = @user_agent
214
+ request[HEADER_API_KEY] = @user_key
215
+ request[HEADER_USER_AGENT] = @user_agent
177
216
 
178
217
  get_response @http_client, request
179
218
  end
180
219
 
181
- # Sends a POST request to Rosette API.
220
+ # Sends a POST request to Analytics API.
182
221
  #
183
222
  # Returns JSON response or raises RosetteAPIError if encountered.
184
223
  def send_post_request
@@ -197,22 +236,23 @@ class RequestBuilder
197
236
  #
198
237
  # * +http+ - HTTP connection.
199
238
  #
200
- # * +request+ - Prepared Rosette API request.
239
+ # * +request+ - Prepared API request.
201
240
  #
202
241
  # Returns JSON response or raises RosetteAPIError if encountered.
203
242
  def get_response(http, request)
204
243
  response = http.request request
205
244
 
206
- if response.code != '200'
207
- message = JSON.parse(response.body)['message']
208
- code = JSON.parse(response.body)['code']
209
- raise RosetteAPIError.new code, message
210
- else
245
+ if response.code == '200'
211
246
  response_headers = {}
212
247
  response.header.each_header { |key, value| response_headers[key] = value }
213
248
  response_headers = { responseHeaders: response_headers }
214
249
 
215
250
  JSON.parse(response.body).merge(response_headers)
251
+ else
252
+ parsed_body = JSON.parse(response.body)
253
+ message = parsed_body['message']
254
+ code = parsed_body['code']
255
+ raise RosetteAPIError.new code, message
216
256
  end
217
257
  end
218
258
  end