Skip to content

Commit

Permalink
Merge pull request #9 from bramski/master
Browse files Browse the repository at this point in the history
Add timeout capability.
  • Loading branch information
Gugic authored Oct 14, 2016
2 parents 56f2f6a + f3b3cb5 commit f3ece8d
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 8 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,20 @@ uer.delete('contacts') # will remove user entities for given session
#Error handling
**ApiAiRuby::Client** currently able to raise two kind of errors: **ApiAiRuby::ClientError** (due to configuration mismatch) and **ApiAiRuby::RequestError** in case of something goes wrong during request. For both kind of errors you can get **error.message** (as usual) and **ApiAiRuby::RequestError** can additionally give you code of server error (you can get it with **error.code**)

#Timeouts
**ApiAiRuby::Client** uses the [http gem](https://github.com/httprb/http) under the hood. You can use ```timeout_options``` on the client to set these.
```ruby
ApiAiRuby::Client.new(
client_access_token: 'YOUR_ACCESS_TOKEN',
api_lang: 'FR',
api_base_url: 'http://example.com/v1/',
api_version: 'YYYYMMDD',
api_session_id: 'some_uuid_or_whatever',
timeout_options: [:global, { write: 1, connect: 1, read: 1 }]
)
```

Please see the [httprb wiki on timeouts](https://github.com/httprb/http/wiki/Timeouts) for more information.

#Changelog

Expand Down
2 changes: 1 addition & 1 deletion lib/api-ai-ruby/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ApiAiRuby
class Client
attr_accessor :client_access_token, :subscription_key
attr_accessor :client_access_token, :subscription_key, :timeout_options
attr_writer :user_agent, :api_version, :api_lang, :api_base_url, :api_session_id

# Initializes a new Client object
Expand Down
9 changes: 5 additions & 4 deletions lib/api-ai-ruby/request/request_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module ApiAiRuby
class RequestQuery

attr_accessor :client, :headers, :options, :request_method, :uri
attr_accessor :client, :headers, :options, :request_method, :uri

# @param client [ApiAiRuby::Client]
# @param options [Hash]
Expand All @@ -18,20 +18,21 @@ def initialize(client, options = {})
@headers = {
Authorization: 'Bearer ' + client.client_access_token,
}
@timeout_options = client.timeout_options || options[:timeout_options]
end

# @return [Array, Hash]
def perform

if @options.has_key?(:voiceData)
options_key = :form
else
options_key = (@request_method === :get) ? :params : :json
end

response = HTTP.with(@headers).public_send(@request_method, @uri.to_s, options_key => @options)
request = HTTP.with(@headers)
request = request.timeout(*@timeout_options) if @timeout_options
response = request.public_send(@request_method, @uri.to_s, options_key => @options)
response_body = symbolize_keys!(response.parse)
response_headers = response.headers
fail_or_return_response_body(response.code, response_body)
end

Expand Down
4 changes: 3 additions & 1 deletion spec/api-ai-ruby/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@
api_lang: 'RU',
api_base_url: 'http://localhost',
api_version: '1234',
api_session_id: '555'
api_session_id: '555',
timeout_options: [:global, { write: 1, connect: 1, read: 1}]
)

expect(client.api_base_url).to eq 'http://localhost'
expect(client.api_version).to eq '1234'
expect(client.api_lang).to eq 'RU'
expect(client.api_session_id).to eq '555'
expect(client.timeout_options).to eq [:global, { write: 1, connect: 1, read: 1}]
end


Expand Down
59 changes: 59 additions & 0 deletions spec/api-ai-ruby/text_request_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require 'helper'

describe ApiAiRuby::TextRequest do
let(:client) do
ApiAiRuby::Client.new(
client_access_token: 'CS',
api_lang: 'EN',
api_session_id: '555',
timeout_options: [:global, { write: 1, connect: 1, read: 1 }]
)
end

subject(:text_request) { described_class.new(client, options) }
let(:options) { { query: "hello" } }

around do |test|
begin
WebMock.disable_net_connect!(allow: 'coveralls.io')
test.run
ensure
WebMock.allow_net_connect!
end
end

let(:response_headers) do
{ "Content-Type" => "application/json;charset=UTF-8", "Content-Length" => "437", "Connection" => "close", "Access-Control-Allow-Credentials" => "true", "Cache-Control" => "no-cache=\"set-cookie\"", "Date" => "Wed, 12 Oct 2016 20:07:54 GMT", "Server" => "nginx/1.9.7", "Set-Cookie" => "AWSELB=9D5B4D210CCFFAF1BE1E0CD7C7E6FCBD7B46140CAAF64A202A005B9079598B549F7A5EC269DD0FF88508DA57410EFC7882B7860453691E7ACC870186C9D1589D2A332B51EC;PATH=/", "X-Cache" => "Miss from cloudfront", "Via" => "1.1 978198446b6fdba8a499c04f84a3a7e6.cloudfront.net (CloudFront)", "X-Amz-Cf-Id" => "ilwhpG75Ea4iXumklw7484nYt2jbx-L6ZaeiO9naUOstx45ia_nuaQ==" }
end
let(:body) do
{ :id => "94613973-930f-4a53-9286-6e9efcbb5c57", :timestamp => "2016-10-12T20:07:54.876Z", :result => { :source => "domains", :resolvedQuery => "hello", :action => "smalltalk.greetings", :parameters => { :simplified => "hello" }, :metadata => {}, :fulfillment => { :speech => "Good day!" }, :score => 0.0 }, :status => { :code => 200, :errorType => "success" }, :sessionId => "555" }
end
let(:expected_headers) do
{ 'Authorization' => 'Bearer CS', 'Connection' => 'close', 'Content-Type' => 'application/json; charset=UTF-8', 'Host' => 'api.api.ai' }
end
let(:expected_url) { "https://api.api.ai/v1/query?v=20150910" }
let(:expected_body) { '{"query":"hello","lang":"EN","sessionId":"555"}' }

describe "#perform" do
it "performs a request" do
stub = stub_request(:post, expected_url).
with(:body => expected_body,
:headers => expected_headers).
to_return(:status => 200, :body => body.to_json, :headers => response_headers)
subject.perform
expect(stub).to have_been_requested
end

context "it times out" do
it "times out properly" do
stub = stub_request(:post, expected_url).
with(:body => expected_body,
:headers => expected_headers).to_timeout
expect {
subject.perform
}.to raise_error(Errno::ETIMEDOUT)
expect(stub).to have_been_requested
end
end
end
end
5 changes: 3 additions & 2 deletions spec/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@

require 'api-ai-ruby'
require 'rspec'
#require 'webmock/rspec'
require 'webmock'
require 'webmock/rspec'

#WebMock.disable_net_connect!(allow: 'coveralls.io')
WebMock.allow_net_connect!

RSpec.configure do |config|
config.expect_with :rspec do |c|
Expand Down

0 comments on commit f3ece8d

Please sign in to comment.