aylien_text_api 0.0.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.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +28 -0
  5. data/LICENSE +13 -0
  6. data/README.md +67 -0
  7. data/Rakefile +8 -0
  8. data/aylien_text_api.gemspec +24 -0
  9. data/config/app_config.yml.example +7 -0
  10. data/lib/aylien_text_api.rb +23 -0
  11. data/lib/aylien_text_api/client.rb +246 -0
  12. data/lib/aylien_text_api/configuration.rb +57 -0
  13. data/lib/aylien_text_api/connection.rb +71 -0
  14. data/lib/aylien_text_api/error.rb +110 -0
  15. data/lib/aylien_text_api/version.rb +17 -0
  16. data/spec/fixtures/aylien_text_api/client/classify_with_invalid_client.yml +36 -0
  17. data/spec/fixtures/aylien_text_api/client/classify_with_invalid_params.yml +40 -0
  18. data/spec/fixtures/aylien_text_api/client/classify_with_text.yml +48 -0
  19. data/spec/fixtures/aylien_text_api/client/classify_with_unauthenticated_client.yml +40 -0
  20. data/spec/fixtures/aylien_text_api/client/classify_with_valid_url.yml +98 -0
  21. data/spec/fixtures/aylien_text_api/client/classify_with_value_as_text.yml +48 -0
  22. data/spec/fixtures/aylien_text_api/client/classify_with_value_as_valid_url.yml +98 -0
  23. data/spec/fixtures/aylien_text_api/client/concepts_with_invalid_client.yml +36 -0
  24. data/spec/fixtures/aylien_text_api/client/concepts_with_invalid_params.yml +40 -0
  25. data/spec/fixtures/aylien_text_api/client/concepts_with_text.yml +44 -0
  26. data/spec/fixtures/aylien_text_api/client/concepts_with_unauthenticated_client.yml +40 -0
  27. data/spec/fixtures/aylien_text_api/client/concepts_with_valid_url.yml +63 -0
  28. data/spec/fixtures/aylien_text_api/client/concepts_with_value_as_text.yml +44 -0
  29. data/spec/fixtures/aylien_text_api/client/concepts_with_value_as_valid_url.yml +63 -0
  30. data/spec/fixtures/aylien_text_api/client/entities_with_invalid_client.yml +36 -0
  31. data/spec/fixtures/aylien_text_api/client/entities_with_invalid_params.yml +40 -0
  32. data/spec/fixtures/aylien_text_api/client/entities_with_text.yml +43 -0
  33. data/spec/fixtures/aylien_text_api/client/entities_with_unauthenticated_client.yml +40 -0
  34. data/spec/fixtures/aylien_text_api/client/entities_with_valid_url.yml +302 -0
  35. data/spec/fixtures/aylien_text_api/client/entities_with_value_as_text.yml +43 -0
  36. data/spec/fixtures/aylien_text_api/client/entities_with_value_as_valid_url.yml +302 -0
  37. data/spec/fixtures/aylien_text_api/client/extract_with_invalid_client.yml +36 -0
  38. data/spec/fixtures/aylien_text_api/client/extract_with_invalid_params.yml +40 -0
  39. data/spec/fixtures/aylien_text_api/client/extract_with_unauthenticated_client.yml +40 -0
  40. data/spec/fixtures/aylien_text_api/client/extract_with_valid_url.yml +185 -0
  41. data/spec/fixtures/aylien_text_api/client/extract_with_value_as_text.yml +40 -0
  42. data/spec/fixtures/aylien_text_api/client/extract_with_value_as_valid_url.yml +185 -0
  43. data/spec/fixtures/aylien_text_api/client/hashtags_with_invalid_client.yml +36 -0
  44. data/spec/fixtures/aylien_text_api/client/hashtags_with_invalid_params.yml +40 -0
  45. data/spec/fixtures/aylien_text_api/client/hashtags_with_text.yml +48 -0
  46. data/spec/fixtures/aylien_text_api/client/hashtags_with_unauthenticated_client.yml +40 -0
  47. data/spec/fixtures/aylien_text_api/client/hashtags_with_valid_url.yml +58 -0
  48. data/spec/fixtures/aylien_text_api/client/hashtags_with_value_as_text.yml +48 -0
  49. data/spec/fixtures/aylien_text_api/client/hashtags_with_value_as_valid_url.yml +58 -0
  50. data/spec/fixtures/aylien_text_api/client/language_with_invalid_client.yml +36 -0
  51. data/spec/fixtures/aylien_text_api/client/language_with_invalid_params.yml +40 -0
  52. data/spec/fixtures/aylien_text_api/client/language_with_unauthenticated_client.yml +40 -0
  53. data/spec/fixtures/aylien_text_api/client/language_with_valid_text.yml +41 -0
  54. data/spec/fixtures/aylien_text_api/client/language_with_valid_url.yml +57 -0
  55. data/spec/fixtures/aylien_text_api/client/language_with_value_as_text.yml +41 -0
  56. data/spec/fixtures/aylien_text_api/client/language_with_value_as_valid_url.yml +57 -0
  57. data/spec/fixtures/aylien_text_api/client/related_with_invalid_client.yml +36 -0
  58. data/spec/fixtures/aylien_text_api/client/related_with_invalid_params.yml +40 -0
  59. data/spec/fixtures/aylien_text_api/client/related_with_phrase.yml +60 -0
  60. data/spec/fixtures/aylien_text_api/client/related_with_unauthenticated_client.yml +40 -0
  61. data/spec/fixtures/aylien_text_api/client/related_with_value_as_phrase.yml +60 -0
  62. data/spec/fixtures/aylien_text_api/client/related_with_value_as_valid_url.yml +40 -0
  63. data/spec/fixtures/aylien_text_api/client/sentiment_with_invalid_client.yml +36 -0
  64. data/spec/fixtures/aylien_text_api/client/sentiment_with_invalid_params.yml +40 -0
  65. data/spec/fixtures/aylien_text_api/client/sentiment_with_text.yml +53 -0
  66. data/spec/fixtures/aylien_text_api/client/sentiment_with_unauthenticated_client.yml +40 -0
  67. data/spec/fixtures/aylien_text_api/client/sentiment_with_valid_url.yml +57 -0
  68. data/spec/fixtures/aylien_text_api/client/sentiment_with_value_as_text.yml +53 -0
  69. data/spec/fixtures/aylien_text_api/client/sentiment_with_value_as_valid_url.yml +57 -0
  70. data/spec/fixtures/aylien_text_api/client/summarize_with_invalid_client.yml +36 -0
  71. data/spec/fixtures/aylien_text_api/client/summarize_with_invalid_params.yml +41 -0
  72. data/spec/fixtures/aylien_text_api/client/summarize_with_title_and_text.yml +78 -0
  73. data/spec/fixtures/aylien_text_api/client/summarize_with_unauthenticated_client.yml +40 -0
  74. data/spec/fixtures/aylien_text_api/client/summarize_with_valid_url.yml +65 -0
  75. data/spec/fixtures/aylien_text_api/client/summarize_with_value_as_text_and_title.yml +78 -0
  76. data/spec/fixtures/aylien_text_api/client/summarize_with_value_as_text_and_without_title.yml +41 -0
  77. data/spec/fixtures/aylien_text_api/client/summarize_with_value_as_valid_url.yml +65 -0
  78. data/spec/lib/aylien_text_api/classify.rb +86 -0
  79. data/spec/lib/aylien_text_api/client_spec.rb +23 -0
  80. data/spec/lib/aylien_text_api/concepts.rb +81 -0
  81. data/spec/lib/aylien_text_api/entities.rb +81 -0
  82. data/spec/lib/aylien_text_api/extract.rb +81 -0
  83. data/spec/lib/aylien_text_api/hashtags.rb +87 -0
  84. data/spec/lib/aylien_text_api/language.rb +79 -0
  85. data/spec/lib/aylien_text_api/related.rb +80 -0
  86. data/spec/lib/aylien_text_api/sentiment.rb +91 -0
  87. data/spec/lib/aylien_text_api/summarize.rb +95 -0
  88. data/spec/spec_helper.rb +16 -0
  89. metadata +193 -0
@@ -0,0 +1,57 @@
1
+ # Copyright 2014 Aylien, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module AylienTextApi
16
+ module Configuration
17
+ VALID_CONNECTION_KEYS = [:base_uri, :user_agent, :method].freeze
18
+ VALID_OPTIONS_KEYS = [:app_id, :app_key].freeze
19
+ VALID_CONFIG_KEYS = VALID_CONNECTION_KEYS + VALID_OPTIONS_KEYS
20
+
21
+ DEFAULT_BASE_URI = 'https://api.aylien.com/api/v1/'.freeze
22
+ DEFAULT_METHOD = :post
23
+ DEFAULT_USER_AGENT = "Aylien Text API Ruby Gem #{AylienTextApi::VERSION}".freeze
24
+
25
+ DEFAULT_APP_ID = nil
26
+ DEFAULT_APP_KEY = nil
27
+
28
+ ENDPOINTS = [:extract, :classify, :concepts, :entities, :hashtags,
29
+ :language, :related, :sentiment, :summarize]
30
+
31
+ # Build accessor methods for every config options so we can do this, for example:
32
+ # AylienTextApi.method = :get
33
+ attr_accessor *VALID_CONFIG_KEYS
34
+
35
+ # Make sure we have the default values set when we get 'extended'
36
+ def self.extended(base)
37
+ base.reset
38
+ end
39
+
40
+ def reset
41
+ self.base_uri = DEFAULT_BASE_URI
42
+ self.method = DEFAULT_METHOD
43
+ self.user_agent = DEFAULT_USER_AGENT
44
+
45
+ self.app_id = DEFAULT_APP_ID
46
+ self.app_key = DEFAULT_APP_KEY
47
+ end
48
+
49
+ def configure
50
+ yield self
51
+ end
52
+
53
+ def options
54
+ Hash[ * VALID_CONFIG_KEYS.map { |key| [key, send(key)] }.flatten ]
55
+ end
56
+ end # Configuration
57
+ end
@@ -0,0 +1,71 @@
1
+ # Copyright 2014 Aylien, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'json'
16
+ require 'logger'
17
+ require 'uri'
18
+ require 'net/http'
19
+
20
+ module AylienTextApi
21
+ class Connection
22
+ def initialize(endpoint, params, config)
23
+ @config = config
24
+ @uri = URI.join(@config[:base_uri], endpoint.to_s)
25
+ @params = params
26
+ compile_request_params
27
+ end
28
+
29
+ def request
30
+ begin
31
+ request!
32
+ rescue => e
33
+ logger = Logger.new(STDOUT)
34
+ logger.level = Logger::ERROR
35
+ logger.info(e)
36
+ nil
37
+ end
38
+ end
39
+
40
+ def request!
41
+ Net::HTTP.start(@uri.host, @uri.port, use_ssl: (@uri.scheme == 'https')) do |http|
42
+ response = http.request(@request)
43
+ if response.kind_of?(Net::HTTPSuccess)
44
+ JSON.parse(response.body, :symbolize_names => true)
45
+ else
46
+ klass = AylienTextApi::Error::ERRORS[response.code.to_i]
47
+ error = klass.nil? ? AylienTextApi::Error.new(response.body) : klass.from_response(response)
48
+ raise error
49
+ end
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def compile_request_params
56
+ if @config[:method] == :post
57
+ request = Net::HTTP::Post.new(@uri.request_uri)
58
+ request.set_form_data(@params)
59
+ elsif @config[:method] == :get
60
+ @uri.query = URI.encode_www_form(@params)
61
+ request = Net::HTTP::Get.new(@uri.request_uri)
62
+ end
63
+
64
+ request['app_id'] = @config[:app_id]
65
+ request['app_key'] = @config[:app_key]
66
+ request['user-agent'] = @config[:user_agent]
67
+
68
+ @request = request
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,110 @@
1
+ # Copyright 2014 Aylien, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module AylienTextApi
16
+ class Error < StandardError
17
+ # Raised when Aylien Text API returns a 4xx HTTP status code
18
+ ClientError = Class.new(self)
19
+
20
+ # Raised when Aylien Text API returns the HTTP status code 400
21
+ BadRequest = Class.new(ClientError)
22
+
23
+ # Raised when Aylien Text API returns the HTTP status code 401
24
+ Unauthorized = Class.new(ClientError)
25
+
26
+ # Raised when Aylien Text API returns the HTTP status code 402
27
+ PaymentRequired = Class.new(ClientError)
28
+
29
+ # Raised when Aylien Text API returns the HTTP status code 403
30
+ Forbidden = Class.new(ClientError)
31
+
32
+ # Raised when Aylien Text API returns the HTTP status code 404
33
+ NotFound = Class.new(ClientError)
34
+
35
+ # Raised when Aylien Text API returns the HTTP status code 406
36
+ NotAcceptable = Class.new(ClientError)
37
+
38
+ # Raised when Aylien Text API returns the HTTP status code 422
39
+ UnprocessableEntity = Class.new(ClientError)
40
+
41
+ # Raised when Aylien Text API returns the HTTP status code 429
42
+ TooManyRequests = Class.new(ClientError)
43
+
44
+ # Raised when Aylien Text API returns a 5xx HTTP status code
45
+ ServerError = Class.new(self)
46
+
47
+ # Raised when Aylien Text API returns the HTTP status code 500
48
+ InternalServerError = Class.new(ServerError)
49
+
50
+ # Raised when Aylien Text API returns the HTTP status code 502
51
+ BadGateway = Class.new(ServerError)
52
+
53
+ # Raised when Aylien Text API returns the HTTP status code 503
54
+ ServiceUnavailable = Class.new(ServerError)
55
+
56
+ # Raised when Aylien Text API returns the HTTP status code 504
57
+ GatewayTimeout = Class.new(ServerError)
58
+
59
+ ERRORS = {
60
+ 400 => AylienTextApi::Error::BadRequest,
61
+ 401 => AylienTextApi::Error::Unauthorized,
62
+ 402 => AylienTextApi::Error::PaymentRequired,
63
+ 403 => AylienTextApi::Error::Forbidden,
64
+ 404 => AylienTextApi::Error::NotFound,
65
+ 406 => AylienTextApi::Error::NotAcceptable,
66
+ 422 => AylienTextApi::Error::UnprocessableEntity,
67
+ 429 => AylienTextApi::Error::TooManyRequests,
68
+ 500 => AylienTextApi::Error::InternalServerError,
69
+ 502 => AylienTextApi::Error::BadGateway,
70
+ 503 => AylienTextApi::Error::ServiceUnavailable,
71
+ 504 => AylienTextApi::Error::GatewayTimeout,
72
+ }
73
+
74
+ class << self
75
+ # Create a new error from an HTTP response
76
+ #
77
+ # @param response [HTTP::Response]
78
+ # @return [AylienTextApi::Error]
79
+ def from_response(response)
80
+ body = if response["Content-Type"].include?('json')
81
+ JSON.parse(response.body, :symbolize_names => true)
82
+ else
83
+ response.body
84
+ end
85
+ message = parse_error(body)
86
+ new(message)
87
+ end
88
+
89
+ private
90
+
91
+ def parse_error(body)
92
+ if body.nil? || body.empty?
93
+ ''
94
+ elsif body.is_a?(Hash) && body[:error]
95
+ body[:error]
96
+ else
97
+ body
98
+ end
99
+ end
100
+ end
101
+
102
+ # Initializes a new Error object
103
+ #
104
+ # @param message [Exception, String]
105
+ # @return [AylienTextApi::Error]
106
+ def initialize(message = '')
107
+ super(message)
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,17 @@
1
+ # Copyright 2014 Aylien, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module AylienTextApi
16
+ VERSION = "0.0.1" unless defined? AylienTextApi::VERSION
17
+ end
@@ -0,0 +1,36 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.aylien.com/api/v1/classify
6
+ body:
7
+ encoding: US-ASCII
8
+ string: text=CCTV+footage+shows+the+moment+a+suicide+car+bomber+detonates%0A++++++a+device+in+Beirut+on+Tuesday.+The+incident+took+place+in+an+area%0A++++++of+support+for+Hezbollah+and+left+four+people+dead+with+many+more+wounded.%0A++++++A+group+calling+itself+the+al-Nusra+Front+in+Lebanon+has+claimed%0A++++++responsibility+for+the+attack+saying+it+was+in+retaliation+for%0A++++++Hezbollah%27s+military+support+of+president+Bashar+al-Assad%27s+forces+in+Syria
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Aylien Text API Ruby Gem 0.0.1
14
+ Content-Type:
15
+ - application/x-www-form-urlencoded
16
+ response:
17
+ status:
18
+ code: 403
19
+ message: Forbidden
20
+ headers:
21
+ Server:
22
+ - openresty/1.5.12.1
23
+ Date:
24
+ - Tue, 02 Dec 2014 18:15:50 GMT
25
+ Content-Type:
26
+ - text/plain; charset=us-ascii
27
+ Transfer-Encoding:
28
+ - chunked
29
+ Connection:
30
+ - keep-alive
31
+ body:
32
+ encoding: US-ASCII
33
+ string: Authentication parameters missing
34
+ http_version:
35
+ recorded_at: Tue, 02 Dec 2014 18:14:48 GMT
36
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,40 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.aylien.com/api/v1/classify
6
+ body:
7
+ encoding: US-ASCII
8
+ string: wrong_param=CCTV+footage+shows+the+moment+a+suicide+car+bomber+detonates%0A++++++a+device+in+Beirut+on+Tuesday.+The+incident+took+place+in+an+area%0A++++++of+support+for+Hezbollah+and+left+four+people+dead+with+many+more+wounded.%0A++++++A+group+calling+itself+the+al-Nusra+Front+in+Lebanon+has+claimed%0A++++++responsibility+for+the+attack+saying+it+was+in+retaliation+for%0A++++++Hezbollah%27s+military+support+of+president+Bashar+al-Assad%27s+forces+in+Syria
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Aylien Text API Ruby Gem 0.0.1
14
+ Content-Type:
15
+ - application/x-www-form-urlencoded
16
+ App-Id:
17
+ - <PASSWORD>
18
+ App-Key:
19
+ - <PASSWORD>
20
+ response:
21
+ status:
22
+ code: 400
23
+ message: Bad Request
24
+ headers:
25
+ Server:
26
+ - openresty/1.5.12.1
27
+ Date:
28
+ - Tue, 02 Dec 2014 18:15:48 GMT
29
+ Content-Type:
30
+ - application/json;charset=UTF-8
31
+ Content-Length:
32
+ - '70'
33
+ Connection:
34
+ - keep-alive
35
+ body:
36
+ encoding: US-ASCII
37
+ string: ! '{"error" : "requirement failed: you must either provide url or text."}'
38
+ http_version:
39
+ recorded_at: Tue, 02 Dec 2014 18:14:45 GMT
40
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,48 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.aylien.com/api/v1/classify
6
+ body:
7
+ encoding: US-ASCII
8
+ string: text=CCTV+footage+shows+the+moment+a+suicide+car+bomber+detonates%0A++++++a+device+in+Beirut+on+Tuesday.+The+incident+took+place+in+an+area%0A++++++of+support+for+Hezbollah+and+left+four+people+dead+with+many+more+wounded.%0A++++++A+group+calling+itself+the+al-Nusra+Front+in+Lebanon+has+claimed%0A++++++responsibility+for+the+attack+saying+it+was+in+retaliation+for%0A++++++Hezbollah%27s+military+support+of+president+Bashar+al-Assad%27s+forces+in+Syria
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Aylien Text API Ruby Gem 0.0.1
14
+ Content-Type:
15
+ - application/x-www-form-urlencoded
16
+ App-Id:
17
+ - <PASSWORD>
18
+ App-Key:
19
+ - <PASSWORD>
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Server:
26
+ - openresty/1.5.12.1
27
+ Date:
28
+ - Tue, 02 Dec 2014 18:15:51 GMT
29
+ Content-Type:
30
+ - application/json;charset=UTF-8
31
+ Content-Length:
32
+ - '605'
33
+ Connection:
34
+ - keep-alive
35
+ body:
36
+ encoding: US-ASCII
37
+ string: ! "{\n \"text\": \"CCTV footage shows the moment a suicide car bomber
38
+ detonates\\n a device in Beirut on Tuesday. The incident took place in
39
+ an area\\n of support for Hezbollah and left four people dead with many
40
+ more wounded.\\n A group calling itself the al-Nusra Front in Lebanon
41
+ has claimed\\n responsibility for the attack saying it was in retaliation
42
+ for\\n Hezbollah's military support of president Bashar al-Assad's forces
43
+ in Syria\",\n \"language\": \"en\",\n \"categories\": [{\n \"label\":
44
+ \"defence - biological and chemical weapons\",\n \"code\": \"11001007\",\n
45
+ \ \"confidence\": 1.0\n }]\n}"
46
+ http_version:
47
+ recorded_at: Tue, 02 Dec 2014 18:14:48 GMT
48
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,40 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.aylien.com/api/v1/classify
6
+ body:
7
+ encoding: US-ASCII
8
+ string: text=CCTV+footage+shows+the+moment+a+suicide+car+bomber+detonates%0A++++++a+device+in+Beirut+on+Tuesday.+The+incident+took+place+in+an+area%0A++++++of+support+for+Hezbollah+and+left+four+people+dead+with+many+more+wounded.%0A++++++A+group+calling+itself+the+al-Nusra+Front+in+Lebanon+has+claimed%0A++++++responsibility+for+the+attack+saying+it+was+in+retaliation+for%0A++++++Hezbollah%27s+military+support+of+president+Bashar+al-Assad%27s+forces+in+Syria
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Aylien Text API Ruby Gem 0.0.1
14
+ Content-Type:
15
+ - application/x-www-form-urlencoded
16
+ App-Id:
17
+ - random_string
18
+ App-Key:
19
+ - random_string
20
+ response:
21
+ status:
22
+ code: 403
23
+ message: Forbidden
24
+ headers:
25
+ Server:
26
+ - openresty/1.5.12.1
27
+ Date:
28
+ - Tue, 02 Dec 2014 18:15:47 GMT
29
+ Content-Type:
30
+ - text/plain; charset=us-ascii
31
+ Transfer-Encoding:
32
+ - chunked
33
+ Connection:
34
+ - keep-alive
35
+ body:
36
+ encoding: US-ASCII
37
+ string: Authentication failed
38
+ http_version:
39
+ recorded_at: Tue, 02 Dec 2014 18:14:44 GMT
40
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,98 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.aylien.com/api/v1/classify
6
+ body:
7
+ encoding: US-ASCII
8
+ string: url=http%3A%2F%2Ftechcrunch.com%2F2014%2F10%2F20%2Fthe-super-slim-kindle-voyage-is-a-great-travel-companion%2F
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Aylien Text API Ruby Gem 0.0.1
14
+ Content-Type:
15
+ - application/x-www-form-urlencoded
16
+ App-Id:
17
+ - <PASSWORD>
18
+ App-Key:
19
+ - <PASSWORD>
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Server:
26
+ - openresty/1.5.12.1
27
+ Date:
28
+ - Tue, 02 Dec 2014 18:15:53 GMT
29
+ Content-Type:
30
+ - application/json;charset=UTF-8
31
+ Content-Length:
32
+ - '4482'
33
+ Connection:
34
+ - keep-alive
35
+ body:
36
+ encoding: US-ASCII
37
+ string: ! "{\n \"text\": \"The Super-Slim Kindle Voyage Is A Great Travel Companion\\nIn
38
+ 1935, Sir Allen Lane and V. K. Krishna Menon founded Penguin Books, a company
39
+ dedicated to producing high-quality, small-format paperback books for the
40
+ world market. These small, well-made little books introduced some amazing
41
+ fiction, philosophy, classical thought and spiritualism to a hungry audience,
42
+ and the low price made it easy to build a library of amazing titles that could
43
+ fit into a milk crate. Penguin, it can be argued, brought about an intellectual
44
+ sea change, bringing us both the post-war writers of note and, in another
45
+ direction, the Beats and the spiritual riot of the 1960s.\\n\\nWhy was Penguin
46
+ so popular? And why is the 6-inch Kindle Voyage its emotional successor? Both
47
+ revolutionized the physical notion of books.\\n\\nIn Penguin\\u2019s case,
48
+ the medium was truly the message, and\\u00a0the writing inside the small,
49
+ pocketable books allowed for portability and encouraged collection. In the
50
+ Kindle Voyage\\u2019s case, Amazon has created a delightful travel companion.\\n\\nFirst,
51
+ let\\u2019s address the size. The $199 Voyage ($219 without ads and with 3G)
52
+ is about as big as a Penguin paperback and just a bit bigger (and thicker)
53
+ than a standard passport. It\\u2019s 7.6 mm thick and removed from its case
54
+ it looks about as substantial as a thin stack of paper.\\n\\nThe Voyage is
55
+ the Kindle distilled. Almost all of the features are there \\u2013 touchscreen,
56
+ bright white e-ink display, and even a special haptic feedback system that
57
+ allows you to \\u201cclick\\u201d left and right side buttons to turn pages.
58
+ You can also swipe the page left and right to move to the next page and small
59
+ dedicated spots above the longer touch-sensitive pads that go back one page.\\n\\nAmazon
60
+ sells an $45 folding case for the Voyage that opens up like a Moleskine reporter\\u2019s
61
+ notebook. It activates the Kindle upon opening and turns it off when closed.
62
+ Hidden magnets then allow you to turn the cover into a little stand for hands-free
63
+ reading.\\n\\nSo how does it work? In short, I love e-ink devices, and the
64
+ Voyage is the best of them. Because it lasts for weeks \\u2013 I haven\\u2019t
65
+ charged it in a full week of use \\u2013 you can stick it in a bag or backpack
66
+ and expect it to be ready to read. The bright backlit screen casts a gentle
67
+ glow that is reactive to outside light and makes reading pleasant without
68
+ the glare of LCD. As a dedicated e-reader, it is nearly perfect, and I rarely
69
+ say anything in CE is perfect.\\n\\nWho is this for? It\\u2019s for readers.
70
+ The Voyage doesn\\u2019t do much except display books and allow you to buy
71
+ them. You can download thousands of titles and not run out of space and, thanks
72
+ to new organizational systems, you can place books into folders and control
73
+ their placement on the device. But, again, it\\u2019s for readers. Don\\u2019t
74
+ expect to read email, browse the web, or control your home security system
75
+ from this device. It\\u2019s the e-reader perfected, however, and that means
76
+ a lot.\\n\\nI don\\u2019t know how much longer the market for dedicated e-readers
77
+ will exist, but I certainly appreciate Amazon\\u2019s dedication to the cause.
78
+ E-ink devices are special because they\\u2019re amazingly readable and light
79
+ and have great battery life. All of these aspects work in concert to offer
80
+ a reading experience akin to thumbing through a Penguin Classic.\\n\\nAgain,
81
+ this isn\\u2019t for everyone. It\\u2019s great for travel \\u2013 I took
82
+ it with me to Disrupt in Europe and have read it on planes for the past few
83
+ days \\u2013 and it\\u2019s great for people who don\\u2019t want a distracting
84
+ reading experience. It\\u2019s a great gateway tablet, for example, for folks
85
+ who don\\u2019t want a complex experience and instead just want to read. It\\u2019s
86
+ also far more comfortable on the eyes for night reading in bed and the text
87
+ can be modified for any eyes.\\n\\nAmazon is aiming for readers. It knows
88
+ that people love Kindles because they are pure products for reading. And the
89
+ Voyage is Amazon\\u2019s latest attempt at perfecting the e-book. Not unlike
90
+ Penguin, Amazon looked at the market and made a bold move. It\\u2019s paid
91
+ off and the resulting products \\u2013 the Fire like and this new Kindle \\u2013
92
+ are nearly perfect media consumption devices by a company that knows how to
93
+ sell.\",\n \"language\": \"en\",\n \"categories\": [{\n \"label\": \"economy,
94
+ business and finance - computing and information technology\",\n \"code\":
95
+ \"04003000\",\n \"confidence\": 1.0\n }]\n}"
96
+ http_version:
97
+ recorded_at: Tue, 02 Dec 2014 18:14:50 GMT
98
+ recorded_with: VCR 2.9.3