opener-webservice 2.0.0 → 2.1.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.
@@ -1,418 +1,19 @@
1
- require "uuidtools"
2
- require "sinatra/base"
3
- require "json"
4
- require "opener/webservice/version"
5
- require "opener/webservice/opt_parser"
6
- require 'opener/callback_handler'
7
-
8
- module Opener
9
- class Webservice < Sinatra::Base
10
- configure do
11
- enable :logging
12
- if ARGV && pos = ARGV.index("--")
13
- ws_options = ARGV[pos..-1]
14
- else
15
- ws_options = []
16
- end
17
- options = OptParser.parse!(ws_options)
18
-
19
- options.each do |k,v|
20
- Sinatra::Application.set k.to_sym, v
21
- end
22
- end
23
-
24
- configure :development do
25
- set :raise_errors, true
26
- set :dump_errors, true
27
- end
28
-
29
- before %r{^((?!.css|.jpg|.png|.js|.ico).)+$} do
30
- extract_params
31
- authenticate! if Sinatra::Application.respond_to?(:authentication)
32
- end
33
-
34
- ##
35
- # Presents a simple form that can be used for getting the NER of a KAF
36
- # document.
37
- #
38
- get '/' do
39
- erb :index
40
- end
41
-
42
- ##
43
- # Puts the text through the primary processor. This route either accepts
44
- # regular POST fields or a JSON payload.
45
- #
46
- # @param [Hash] params The POST parameters.
47
- #
48
- # @option params [String] :input the input to send to the processor
49
- #
50
- # @option params [Array<String>] :callbacks A collection of callback URLs
51
- # that act as a chain. The results are posted to the first URL which is
52
- # then shifted of the list.
53
- #
54
- # @option params [String] :error_callback Callback URL to send errors to
55
- # when using the asynchronous setup.
56
- #
57
- post '/' do
58
- input_params = get_input_params
59
- input = get_input(input_params)
60
-
61
- if !input or input.strip.empty?
62
- logger.error('Failed to process the request: no input specified')
63
-
64
- halt(400, 'No input specified')
65
- end
66
-
67
- input_params[:input] = input
68
-
69
- callbacks = extract_callbacks(input_params[:callbacks])
70
- error_callback = input_params[:error_callback]
71
-
72
- if callbacks.empty?
73
- process_sync(input_params)
74
- else
75
- process_async(input_params, callbacks, error_callback)
76
- end
77
- end
78
-
79
- ##
80
- # @return [HTTPClient]
81
- #
82
- def self.http_client
83
- return @http_client || new_http_client
84
- end
85
-
86
- ##
87
- # @return [Opener::CallbackHandler]
88
- #
89
- def self.callback_handler
90
- return @callback_handler || new_callback_handler
91
- end
92
-
93
- ##
94
- # @return [HTTPClient]
95
- #
96
- def self.new_http_client
97
- client = HTTPClient.new
98
- client.connect_timeout = 120
99
-
100
- return client
101
- end
102
-
103
- ##
104
- # @return [Opener::CallbackHandler]
105
- #
106
- def self.new_callback_handler
107
- handler = Opener::CallbackHandler.new
108
-
109
- return handler
110
- end
111
-
112
- ##
113
- # Specifies the text processor to use or returns it if no parameter is
114
- # given.
115
- #
116
- # @param [Class] processor
117
- # @return [Class]
118
- #
119
- def self.text_processor(processor=nil)
120
- if processor.nil?
121
- return @processor
122
- else
123
- @processor = processor
124
- end
125
- end
126
-
127
- ##
128
- # Specifies what parameters are accepted.
129
- #
130
- # @param [Array] array The parameters to accept.
131
- #
132
- def self.accepted_params(*array)
133
- if array.empty?
134
- return @accepted_params
135
- else
136
- @accepted_params = array
137
- end
138
- @accepted_params.concat([secret_symbol, token_symbol]) if Sinatra::Application.respond_to?(:authentication)
139
- end
140
-
141
- ##
142
- # @return [Class]
143
- #
144
- def text_processor
145
- self.class.text_processor
146
- end
147
-
148
- ##
149
- # @return [Array]
150
- #
151
- def accepted_params
152
- self.class.accepted_params
153
- end
154
-
155
- ##
156
- # Processes the request synchronously.
157
- #
158
- # @param [Hash] input_params
159
- #
160
- def process_sync(input_params)
161
- output, type = analyze(filtered_params(input_params))
162
- content_type(type)
163
-
164
- body(output)
165
- end
166
-
167
- ##
168
- # Filter the params hash based on the accepted_params
169
- #
170
- # @param [Hash] input_params
171
- # @return [Hash]
172
- #
173
- def filtered_params(input_params)
174
- options = input_params.select{|k,v| accepted_params.include?(k.to_sym)}
175
- cleaned = {}
176
-
177
- options.each do |k, v|
178
- v = true if v == "true"
179
- v = false if v == "false"
180
-
181
- cleaned[k.to_sym] = v
182
- end
183
-
184
- return cleaned
185
- end
186
-
187
- ##
188
- # Processes the request asynchronously.
189
- #
190
- # @param [Hash] input_params
191
- # @param [Array] callbacks The callback URLs to use.
192
- # @param [String] error_callback
193
- #
194
- def process_async(input_params, callbacks, error_callback)
195
- request_id = get_request_id
196
- output_url = callbacks.last
197
-
198
- Thread.new do
199
- analyze_async(
200
- filtered_params(input_params),
201
- request_id,
202
- callbacks,
203
- error_callback
204
- )
205
- end
206
-
207
- content_type :json
208
-
209
- {
210
- :request_id => request_id.to_s,
211
- :output_url => [output_url, request_id].join("/")
212
- }.to_json
213
- end
214
-
215
- ##
216
- # Gets the Analyzed output of an input.
217
- #
218
- # @param [Hash] options The options for the text_processor
219
- # @return [String] output the output of the text_processor
220
- # @return [Symbol] type the output type ot the text_processor
221
- #
222
- # @raise RunetimeError Raised when the tagging process failed.
223
- #
224
- def analyze(options)
225
- processor = text_processor.new(options)
226
- output, error, status = processor.run(options[:input])
1
+ require 'securerandom'
2
+ require 'json'
227
3
 
228
- if processor.respond_to?(:output_type)
229
- type = processor.output_type
230
- else
231
- type = :xml
232
- end
233
-
234
- raise(error) if !status.nil? && !status.success?
235
-
236
- return output, type
237
- end
238
-
239
- ##
240
- # Gets the NER of a KAF document and submits it to a callback URL.
241
- #
242
- # @param [Hash] options
243
- # @param [String] request_id
244
- # @param [Array] callbacks
245
- # @param [String] error_callback
246
- #
247
- def analyze_async(options, request_id, callbacks, error_callback = nil)
248
- begin
249
- output, _ = analyze(options)
250
- rescue => error
251
- logger.error("Failed to process input: #{error.inspect}")
252
-
253
- submit_error(error_callback, error.message) if error_callback
254
- end
255
-
256
- url = callbacks.shift
257
-
258
- logger.info("Submitting results to #{url}")
259
-
260
- begin
261
- process_callback(options, url, output, request_id, callbacks, error_callback)
262
- rescue => error
263
- logger.error("Failed to submit the results: #{error.inspect}")
264
-
265
- submit_error(error_callback, error.message) if error_callback
266
- end
267
- end
268
-
269
- ##
270
- # @param [Hash] options
271
- # @param [String] url
272
- # @param [String] text
273
- # @param [String] request_id
274
- # @param [Array] callbacks
275
- #
276
- def process_callback(options, url, text, request_id, callbacks, error_callback)
277
- if request.content_type == 'application/json'
278
- headers = {'Content-Type' => 'application/json'}
279
- output = JSON.dump(
280
- filtered_params(options).merge(
281
- :input => text,
282
- :request_id => request_id,
283
- :callbacks => callbacks,
284
- :error_callback => error_callback
285
- )
286
- )
287
- else
288
- headers = {}
289
- output = filtered_params(options).merge(
290
- :input => text,
291
- :request_id => request_id,
292
- :'callbacks[]' => callbacks,
293
- :error_callback => error_callback
294
- )
295
- end
296
-
297
- extract_params
298
-
299
- callback_handler.post(url, :body => output, :header => headers)
300
- end
301
-
302
- ##
303
- # @param [String] url
304
- # @param [String] message
305
- #
306
- def submit_error(url, message)
307
- callback_handler.post(url, :body => {:error => message})
308
- end
309
-
310
- ##
311
- # Returns an Array containing the callback URLs, ignoring empty values.
312
- #
313
- # @param [Array|String] input
314
- # @return [Array]
315
- #
316
- def extract_callbacks(input)
317
- return [] if input.nil? || input.empty?
318
-
319
- callbacks = input.compact.reject(&:empty?)
320
-
321
- return callbacks
322
- end
323
-
324
- ##
325
- # @return [String]
326
- #
327
- def get_request_id
328
- return params[:request_id] || UUIDTools::UUID.random_create
329
- end
330
-
331
- ##
332
- # @see Opener::Webservice.http_client
333
- #
334
- def http_client
335
- return self.class.http_client
336
- end
337
-
338
- ##
339
- # @see Opener::Webservice.callback_handler
340
- #
341
- def callback_handler
342
- return self.class.callback_handler
343
- end
344
-
345
- def authenticate!
346
- credentials = {
347
- secret_symbol => params[secret_symbol.to_s],
348
- token_symbol => params[token_symbol.to_s]
349
- }
350
- response = http_client.get(Sinatra::Application.authentication, credentials)
351
- halt response.body unless response.ok?
352
- end
353
-
354
- ##
355
- # Returns a Hash containing the input parameters to use. If a JSON payload
356
- # is submitted the parameters will be based on the payload.
357
- #
358
- # @return [Hash]
359
- #
360
- def get_input_params
361
- input = {}
362
-
363
- if request.content_type == 'application/json'
364
- JSON.load(request.body).each do |key, value|
365
- input[key.to_sym] = value
366
- end
367
- else
368
- input = params
369
- end
370
-
371
- return input
372
- end
373
-
374
- def extract_params
375
- if request.referrer
376
- uri = URI.parse(request.referrer)
377
- extracted = Rack::Utils.parse_nested_query(uri.query)
378
- params.merge!(extracted)
379
- end
380
- end
381
-
382
- def self.secret_symbol
383
- Sinatra::Application.respond_to?(:secret)? Sinatra::Application.secret.to_sym : :secret
384
- end
385
-
386
- def self.token_symbol
387
- Sinatra::Application.respond_to?(:token)? Sinatra::Application.token.to_sym : :token
388
- end
389
-
390
- def secret_symbol
391
- return self.class.secret_symbol
392
- end
393
-
394
- def token_symbol
395
- return self.class.token_symbol
396
- end
397
-
398
- ##
399
- # Returns the KAF/text input as a String.
400
- #
401
- # @param [Hash] params
402
- # @return [String]
403
- #
404
- def get_input(params)
405
- input = nil
406
-
407
- if params[:input]
408
- input = params[:input]
409
-
410
- elsif params[:input_url]
411
- resp = HTTPClient.get(params[:input_url], :follow_redirect => true)
412
- input = resp.body if resp.ok?
413
- end
414
-
415
- return input
416
- end
417
- end
418
- end
4
+ require 'puma/cli'
5
+ require 'slop'
6
+ require 'sinatra/base'
7
+ require 'opener/core'
8
+ require 'opener/callback_handler'
9
+ require 'rollbar'
10
+ require 'new_relic/control'
11
+
12
+ require_relative 'webservice/version'
13
+ require_relative 'webservice/configuration'
14
+ require_relative 'webservice/server'
15
+ require_relative 'webservice/uploader'
16
+ require_relative 'webservice/error_handler'
17
+ require_relative 'webservice/input_extractor'
18
+ require_relative 'webservice/input_sanitizer'
19
+ require_relative 'webservice/option_parser'
@@ -1,10 +1,10 @@
1
1
  require File.expand_path('../lib/opener/webservice/version', __FILE__)
2
2
 
3
3
  Gem::Specification.new do |spec|
4
- spec.name = "opener-webservice"
4
+ spec.name = 'opener-webservice'
5
5
  spec.version = Opener::Webservice::VERSION
6
- spec.authors = ["development@olery.com"]
7
- spec.summary = %q{Basic webservice hooks for the opener toolchain}
6
+ spec.authors = ['development@olery.com']
7
+ spec.summary = 'Basic webservice hooks for the OpeNER toolchain'
8
8
  spec.description = spec.summary
9
9
 
10
10
  spec.license = 'Apache 2.0'
@@ -16,13 +16,21 @@ Gem::Specification.new do |spec|
16
16
  'LICENSE.txt'
17
17
  ]).select { |file| File.file?(file) }
18
18
 
19
- spec.add_dependency "sinatra", "~> 1.4.3"
20
- spec.add_dependency "uuidtools"
21
- spec.add_dependency "json"
22
- spec.add_dependency "opener-callback-handler", '~> 1.0'
19
+ spec.add_dependency 'sinatra', '~> 1.4.3'
20
+ spec.add_dependency 'uuidtools'
21
+ spec.add_dependency 'json'
22
+ spec.add_dependency 'opener-callback-handler', '~> 1.0'
23
23
  spec.add_dependency 'httpclient', ['~> 2.0', '>= 2.5.3.3']
24
+ spec.add_dependency 'opener-core', '~> 2.0'
25
+ spec.add_dependency 'puma'
26
+ spec.add_dependency 'slop', '~> 3.0'
24
27
 
25
- spec.add_development_dependency "bundler", "~> 1.3"
26
- spec.add_development_dependency "rake"
27
- spec.add_development_dependency "pry"
28
+ spec.add_dependency 'newrelic_rpm'
29
+ spec.add_dependency 'rollbar', '~> 1.0'
30
+
31
+ spec.add_development_dependency 'bundler', '~> 1.3'
32
+ spec.add_development_dependency 'rake'
33
+ spec.add_development_dependency 'pry'
34
+ spec.add_development_dependency 'rspec'
35
+ spec.add_development_dependency 'rack-test'
28
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opener-webservice
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - development@olery.com
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-17 00:00:00.000000000 Z
11
+ date: 2014-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -86,6 +86,76 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: 2.5.3.3
89
+ - !ruby/object:Gem::Dependency
90
+ name: opener-core
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.0'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: puma
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: slop
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '3.0'
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '3.0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: newrelic_rpm
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: rollbar
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '1.0'
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '1.0'
89
159
  - !ruby/object:Gem::Dependency
90
160
  name: bundler
91
161
  requirement: !ruby/object:Gem::Requirement
@@ -128,7 +198,35 @@ dependencies:
128
198
  - - ">="
129
199
  - !ruby/object:Gem::Version
130
200
  version: '0'
131
- description: Basic webservice hooks for the opener toolchain
201
+ - !ruby/object:Gem::Dependency
202
+ name: rspec
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ - !ruby/object:Gem::Dependency
216
+ name: rack-test
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ type: :development
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
229
+ description: Basic webservice hooks for the OpeNER toolchain
132
230
  email:
133
231
  executables: []
134
232
  extensions: []
@@ -137,7 +235,13 @@ files:
137
235
  - LICENSE.txt
138
236
  - README.md
139
237
  - lib/opener/webservice.rb
140
- - lib/opener/webservice/opt_parser.rb
238
+ - lib/opener/webservice/configuration.rb
239
+ - lib/opener/webservice/error_handler.rb
240
+ - lib/opener/webservice/input_extractor.rb
241
+ - lib/opener/webservice/input_sanitizer.rb
242
+ - lib/opener/webservice/option_parser.rb
243
+ - lib/opener/webservice/server.rb
244
+ - lib/opener/webservice/uploader.rb
141
245
  - lib/opener/webservice/version.rb
142
246
  - opener-webservice.gemspec
143
247
  homepage:
@@ -163,6 +267,6 @@ rubyforge_project:
163
267
  rubygems_version: 2.2.2
164
268
  signing_key:
165
269
  specification_version: 4
166
- summary: Basic webservice hooks for the opener toolchain
270
+ summary: Basic webservice hooks for the OpeNER toolchain
167
271
  test_files: []
168
272
  has_rdoc: