keen 0.8.7 → 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Build Status](https://secure.travis-ci.org/keenlabs/keen-gem.png?branch=master)](http://travis-ci.org/keenlabs/keen-gem) [![Code Climate](https://codeclimate.com/github/keenlabs/keen-gem.png)](https://codeclimate.com/github/keenlabs/keen-gem)
4
4
  [![Gem Version](https://badge.fury.io/rb/keen.svg)](http://badge.fury.io/rb/keen)
5
5
 
6
- keen-gem is the official Ruby Client for the [Keen IO](https://keen.io/) API. The
6
+ keen-gem is the official Ruby Client for the [Keen IO](https://keen.io/?s=gh-gem) API. The
7
7
  Keen IO API lets developers build analytics features directly into their apps.
8
8
 
9
9
  ### Installation
@@ -25,14 +25,14 @@ keen is tested with Ruby 1.8 and 1.9 on:
25
25
  ### Usage
26
26
 
27
27
  Before making any API calls, you must supply keen-gem with a Project ID and one or more authentication keys.
28
- (If you need a Keen IO account, [sign up here](https://keen.io/signup) - it's free.)
28
+ (If you need a Keen IO account, [sign up here](https://keen.io/signup?s=gh-gem) - it's free.)
29
29
 
30
30
  Setting a write key is required for publishing events. Setting a read key is required for running queries.
31
31
  Setting a master key is required for performing deletes. You can find keys for all of your projects
32
- on [keen.io](https://keen.io).
32
+ on [keen.io](https://keen.io?s=gh-gem).
33
33
 
34
34
  The recommended way to set keys is via the environment. The keys you can set are
35
- `KEEN_PROJECT_ID`, `KEEN_WRITE_KEY`, `KEEN_READ_KEY`, and `KEEN_MASTER_KEY`.
35
+ `KEEN_PROJECT_ID`, `KEEN_WRITE_KEY`, `KEEN_READ_KEY` and `KEEN_MASTER_KEY`.
36
36
  You only need to specify the keys that correspond to the API calls you'll be performing.
37
37
  If you're using [foreman](http://ddollar.github.com/foreman/), add this to your `.env` file:
38
38
 
@@ -58,7 +58,7 @@ Keen.publish(:sign_ups, { :username => "lloyd", :referred_by => "harry" })
58
58
  ```
59
59
 
60
60
  This will publish an event to the `sign_ups` collection with the `username` and `referred_by` properties set.
61
- The event properties can be any valid Ruby hash. Nested properties are allowed. Lists of objects are also allowed, but not recommended because they can be difficult to query over. See alternatives to lists of objects [here](http://stackoverflow.com/questions/24620330/nested-json-objects-in-keen-io). You can learn more about data modeling with Keen IO with the [Data Modeling Guide](https://keen.io/docs/event-data-modeling/event-data-intro/).
61
+ The event properties can be any valid Ruby hash. Nested properties are allowed. Lists of objects are also allowed, but not recommended because they can be difficult to query over. See alternatives to lists of objects [here](http://stackoverflow.com/questions/24620330/nested-json-objects-in-keen-io). You can learn more about data modeling with Keen IO with the [Data Modeling Guide](https://keen.io/docs/event-data-modeling/event-data-intro/?s=gh-gem).
62
62
 
63
63
  Protip: Marshalling gems like [Blockhead](https://github.com/vinniefranco/blockhead) make converting structs or objects to hashes easier.
64
64
 
@@ -106,7 +106,7 @@ to resume processing immediately.
106
106
 
107
107
  ### Running queries
108
108
 
109
- The Keen IO API provides rich querying capabilities against your event data set. For more information, see the [Data Analysis API Guide](https://keen.io/docs/data-analysis/).
109
+ The Keen IO API provides rich querying capabilities against your event data set. For more information, see the [Data Analysis API Guide](https://keen.io/docs/data-analysis/?s=gh-gem).
110
110
 
111
111
  Running queries requires that `KEEN_READ_KEY` is set.
112
112
 
@@ -121,27 +121,31 @@ Keen.average("purchases", :target_property => "price") # => 60
121
121
  Keen.median("purchases", :target_property => "price") # => 60
122
122
  Keen.percentile("purchases", :target_property => "price", :percentile => 90) # => 100
123
123
 
124
- Keen.sum("purchases", :target_property => "price", :group_by => "item.id") # => [{ "item.id": 123, "result": 240 }, { ... }]
124
+ Keen.sum("purchases", :target_property => "price", :group_by => "item.id") # => [{ "item.id": 123, "result": 240 }]
125
+ Keen.count("purchases", :timeframe => "today", :filters => [{
126
+ "property_name" => "referred_by",
127
+ "operator" => "eq",
128
+ "property_value" => "harry"
129
+ }]) # => 2
125
130
 
126
131
  Keen.count_unique("purchases", :target_property => "username") # => 3
127
132
  Keen.select_unique("purchases", :target_property => "username") # => ["Bob", "Linda", "Travis"]
128
133
 
129
- Keen.extraction("purchases") # => [{ "price" => 20, ... }, { ... }]
134
+ Keen.extraction("purchases") # => [{ "keen" => { "timestamp" => "2014-01-01T00:00:00Z" }, "price" => 20 }]
130
135
 
131
- Keen.funnel(:steps => [
132
- { :actor_property => "username", :event_collection => "purchases" },
133
- { :actor_property => "username", :event_collection => "referrals" },
134
- { ... }]) # => [20, 15 ...]
136
+ Keen.funnel(:steps => [{
137
+ :actor_property => "username", :event_collection => "purchases" }, {
138
+ :actor_property => "username", :event_collection => "referrals" }]) # => [20, 15]
135
139
 
136
140
  Keen.multi_analysis("purchases", analyses: {
137
141
  :gross => { :analysis_type => "sum", :target_property => "price" },
138
142
  :customers => { :analysis_type => "count_unique", :target_property => "username" } },
139
- :timeframe => 'today', :group_by => "item.id") # => [{"item.id"=>2, "gross"=>314.49, "customers"=> 8}, { ... }]
143
+ :timeframe => 'today', :group_by => "item.id") # => [{ "item.id" => 2, "gross" => 314.49, "customers" => 8 } }]
140
144
  ```
141
145
 
142
146
  Many of these queries can be performed with group by, filters, series and intervals. The response is returned as a Ruby Hash or Array.
143
147
 
144
- Detailed information on available parameters for each API resource can be found on the [API Technical Reference](https://keen.io/docs/api/reference/).
148
+ Detailed information on available parameters for each API resource can be found on the [API Technical Reference](https://keen.io/docs/api/reference/?s=gh-gem).
145
149
 
146
150
  ##### The Query Method
147
151
 
@@ -187,7 +191,7 @@ Getting the list of event collections requires that the `KEEN_MASTER_KEY` is set
187
191
 
188
192
  ### Deleting events
189
193
 
190
- The Keen IO API allows you to [delete events](https://keen.io/docs/maintenance/#deleting-event-collections)
194
+ The Keen IO API allows you to [delete events](https://keen.io/docs/maintenance/#deleting-event-collections?s=gh-gem)
191
195
  from event collections, optionally supplying a filter to narrow the scope of what you would like to delete.
192
196
 
193
197
  Deleting events requires that the `KEEN_MASTER_KEY` is set.
@@ -208,7 +212,7 @@ Keen.delete(:signups, filters: [{
208
212
 
209
213
  #### Overwriting event timestamps
210
214
 
211
- Two time-related properties are included in your event automatically. The properties “keen.timestamp” and “keen.created_at” are set at the time your event is recorded. You have the ability to overwrite the keen.timestamp property. This could be useful, for example, if you are backfilling historical data. Be sure to use [ISO-8601 Format](https://keen.io/docs/event-data-modeling/event-data-intro/#iso-8601-format).
215
+ Two time-related properties are included in your event automatically. The properties “keen.timestamp” and “keen.created_at” are set at the time your event is recorded. You have the ability to overwrite the keen.timestamp property. This could be useful, for example, if you are backfilling historical data. Be sure to use [ISO-8601 Format](https://keen.io/docs/event-data-modeling/event-data-intro/#iso-8601-format?s=gh-gem).
212
216
 
213
217
  Keen stores all date and time information in UTC!
214
218
 
@@ -266,6 +270,7 @@ Keen.project_id = 'xxxxxxxxxxxxxxx'
266
270
  Keen.write_key = 'yyyyyyyyyyyyyyy'
267
271
  Keen.read_key = 'zzzzzzzzzzzzzzz'
268
272
  Keen.master_key = 'aaaaaaaaaaaaaaa'
273
+ Keen.read_timeoout = 60
269
274
  ```
270
275
 
271
276
  You can also configure unique client instances as follows:
@@ -274,7 +279,8 @@ You can also configure unique client instances as follows:
274
279
  keen = Keen::Client.new(:project_id => 'xxxxxxxxxxxxxxx',
275
280
  :write_key => 'yyyyyyyyyyyyyyy',
276
281
  :read_key => 'zzzzzzzzzzzzzzz',
277
- :master_key => 'aaaaaaaaaaaaaaa')
282
+ :master_key => 'aaaaaaaaaaaaaaa',
283
+ :read_timeout => 60)
278
284
  ```
279
285
 
280
286
  #### em-synchrony
@@ -299,22 +305,22 @@ Keen.beacon_url("sign_ups", :recipient => "foo@foo.com")
299
305
  # => "https://api.keen.io/3.0/projects/xxxxxx/events/email_opens?api_key=yyyyyy&data=eyJyZWNpcGllbnQiOiJmb29AZm9vLmNvbSJ9"
300
306
  ```
301
307
 
302
- To track email opens, simply add an image to your email template that points to this URL. For further information on how to do this, see the [image beacon documentation](https://keen.io/docs/data-collection/image-beacon/).
308
+ To track email opens, simply add an image to your email template that points to this URL. For further information on how to do this, see the [image beacon documentation](https://keen.io/docs/data-collection/image-beacon/?s=gh-gem).
303
309
 
304
310
  #### Redirect URLs
305
311
  Redirect URLs are just like image beacon URLs with the addition of a `redirect` query parameter. This parameter is used
306
312
  to issue a redirect to a certain URL after an event is recorded.
307
313
 
308
- ```
314
+ ``` ruby
309
315
  Keen.redirect_url("sign_ups", { :recipient => "foo@foo.com" }, "http://foo.com")
310
316
  # => "https://api.keen.io/3.0/projects/xxxxxx/events/email_opens?api_key=yyyyyy&data=eyJyZWNpcGllbnQiOiJmb29AZm9vLmNvbSJ9&redirect=http://foo.com"
311
317
  ```
312
318
 
313
- This is helpful for tracking email clickthroughs. See the [redirect documentation](https://keen.io/docs/data-collection/redirect/) for further information.
319
+ This is helpful for tracking email clickthroughs. See the [redirect documentation](https://keen.io/docs/data-collection/redirect/?s=gh-gem) for further information.
314
320
 
315
321
  #### Generating scoped keys
316
322
 
317
- A [scoped key](https://keen.io/docs/security/#scoped-key) is a string, generated with your API Key, that represents some encrypted authentication and query options.
323
+ A [scoped key](https://keen.io/docs/security/#scoped-key?s=gh-gem) is a string, generated with your API Key, that represents some encrypted authentication and query options.
318
324
  Use them to control what data queries have access to.
319
325
 
320
326
  ``` ruby
@@ -328,6 +334,21 @@ scoped_key = Keen::ScopedKey.new("my-api-key", { "filters" => [{
328
334
 
329
335
  You can use the scoped key created in Ruby for API requests from any client. Scoped keys are commonly used in JavaScript, where credentials are visible and need to be protected.
330
336
 
337
+ ### Additional options
338
+
339
+ ##### HTTP Read Timeout
340
+
341
+ The default `Net:HTTP` timeout is 60 seconds. That's usually enough, but if you're querying over a large collection you may need to increase it. The timeout on the API side is 300 seconds, so that's as far as you'd want to go. You can configure a read timeout (in seconds) by setting a `KEEN_READ_TIMEOUT` environment variable, or by passing in a `read_timeout` option to the client constructor as follows:
342
+
343
+ ```
344
+ keen = Keen::Client.new(:read_timeout => 300)
345
+ ```
346
+
347
+ ##### HTTP Proxy
348
+
349
+ You can set the `KEEN_PROXY_TYPE` and `KEEN_PROXY_URL` environment variables to enable HTTP proxying. `KEEN_PROXY_TYPE` should most likely be set to `socks5`. You can also configure this on client instances by passing in `proxy_type` and `proxy_url` keys.
350
+
351
+
331
352
  ### Troubleshooting
332
353
 
333
354
  ##### EventMachine
@@ -343,6 +364,9 @@ EventMachine itself won't do this because it runs in a different thread. Here's
343
364
 
344
365
  ### Changelog
345
366
 
367
+ ##### 0.8.8
368
+ + Add support for a configurable read timeout
369
+
346
370
  ##### 0.8.7
347
371
  + Add support for returning all keys back from query API responses
348
372
 
@@ -351,10 +375,10 @@ EventMachine itself won't do this because it runs in a different thread. Here's
351
375
  + Make the `query` method public so code supporting dynamic analysis types is easier to write
352
376
 
353
377
  ##### 0.8.4
354
- + Add support for getting [project details](https://keen.io/docs/api/reference/#project-row-resource)
378
+ + Add support for getting [project details](https://keen.io/docs/api/reference/#project-row-resource?s=gh-gem)
355
379
 
356
380
  ##### 0.8.3
357
- + Add support for getting a list of a [project's collections](https://keen.io/docs/api/reference/#event-resource)
381
+ + Add support for getting a list of a [project's collections](https://keen.io/docs/api/reference/#event-resource?s=gh-gem)
358
382
 
359
383
  ##### 0.8.2
360
384
  + Add support for `median` and `percentile` analysis
@@ -365,9 +389,9 @@ EventMachine itself won't do this because it runs in a different thread. Here's
365
389
 
366
390
  ##### 0.8.0
367
391
  + **UPGRADE WARNING** Do you use spaces in collection names? Or other special characters? Read [this post](https://groups.google.com/forum/?fromgroups#!topic/keen-io-devs/VtCgPuNKrgY) from the mailing list to make sure your collection names don't change.
368
- + Add support for generating [scoped keys](https://keen.io/docs/security/#scoped-key).
392
+ + Add support for generating [scoped keys](https://keen.io/docs/security/#scoped-key?s=gh-gem).
369
393
  + Make collection name encoding more robust. Make sure collection names are encoded identically for publishing events, running queries, and performing deletes.
370
- + Add support for [grouping by multiple properties](https://keen.io/docs/data-analysis/group-by/#grouping-by-multiple-properties).
394
+ + Add support for [grouping by multiple properties](https://keen.io/docs/data-analysis/group-by/#grouping-by-multiple-properties?s=gh-gem).
371
395
 
372
396
  ##### 0.7.8
373
397
  + Add support for redirect URL creation.
@@ -426,9 +450,14 @@ server-side querying processes require a Read key that should not be made public
426
450
 
427
451
  ### Questions & Support
428
452
 
429
- If you have any questions, bugs, or suggestions, please
430
- report them via Github Issues. Or, come chat with us anytime
431
- at [users.keen.io](http://users.keen.io). We'd love to hear your feedback and ideas!
453
+ For questions, bugs, or suggestions about this gem:
454
+ [File a Github Issue](https://github.com/keenlabs/keen-gem/issues).
455
+
456
+ For other Keen-IO related technical questions:
457
+ ['keen-io' on Stack Overflow](http://stackoverflow.com/questions/tagged/keen-io)
458
+
459
+ For general Keen IO discussion & feedback:
460
+ ['keen-io-devs' Google Group](https://groups.google.com/forum/#!forum/keen-io-devs)
432
461
 
433
462
  ### Contributing
434
463
  keen-gem is an open source project and we welcome your contributions.
@@ -73,7 +73,8 @@ module Keen
73
73
  :master_key => ENV['KEEN_MASTER_KEY'],
74
74
  :api_url => ENV['KEEN_API_URL'],
75
75
  :proxy_url => ENV['KEEN_PROXY_URL'],
76
- :proxy_type => ENV['KEEN_PROXY_TYPE']
76
+ :proxy_type => ENV['KEEN_PROXY_TYPE'],
77
+ :read_timeout => ENV['KEEN_READ_TIMEOUT']
77
78
  )
78
79
  end
79
80
  end
@@ -15,7 +15,7 @@ module Keen
15
15
  include Keen::Client::QueryingMethods
16
16
  include Keen::Client::MaintenanceMethods
17
17
 
18
- attr_accessor :project_id, :write_key, :read_key, :master_key, :api_url, :proxy_url, :proxy_type
18
+ attr_accessor :project_id, :write_key, :read_key, :master_key, :api_url, :proxy_url, :proxy_type, :read_timeout
19
19
 
20
20
  CONFIG = {
21
21
  :api_url => "https://api.keen.io",
@@ -49,6 +49,8 @@ module Keen
49
49
  self.api_url = options[:api_url] || CONFIG[:api_url]
50
50
 
51
51
  self.proxy_url, self.proxy_type = options.values_at(:proxy_url, :proxy_type)
52
+
53
+ self.read_timeout = options[:read_timeout].to_f unless options[:read_timeout].nil?
52
54
  end
53
55
 
54
56
  private
@@ -16,7 +16,7 @@ module Keen
16
16
  query_params = preprocess_params(params) if params != {}
17
17
 
18
18
  begin
19
- response = Keen::HTTP::Sync.new(self.api_url, self.proxy_url).delete(
19
+ response = http_sync.delete(
20
20
  :path => [api_event_collection_resource_path(event_collection), query_params].compact.join('?'),
21
21
  :headers => api_headers(self.master_key, "sync"))
22
22
  rescue Exception => http_error
@@ -35,7 +35,7 @@ module Keen
35
35
  ensure_master_key!
36
36
 
37
37
  begin
38
- response = Keen::HTTP::Sync.new(self.api_url, self.proxy_url).get(
38
+ response = http_sync.get(
39
39
  :path => "/#{api_version}/projects/#{project_id}/events",
40
40
  :headers => api_headers(self.master_key, "sync"))
41
41
  rescue Exception => http_error
@@ -54,7 +54,7 @@ module Keen
54
54
  ensure_master_key!
55
55
 
56
56
  begin
57
- response = Keen::HTTP::Sync.new(self.api_url, self.proxy_url).get(
57
+ response = http_sync.get(
58
58
  :path => "/#{api_version}/projects/#{project_id}",
59
59
  :headers => api_headers(self.master_key, "sync"))
60
60
  rescue Exception => http_error
@@ -65,6 +65,12 @@ module Keen
65
65
  process_response(response.code, response_body)
66
66
  end
67
67
 
68
+ private
69
+
70
+ def http_sync
71
+ @http_sync ||= Keen::HTTP::Sync.new(self.api_url, self.proxy_url, self.read_timeout)
72
+ end
73
+
68
74
  end
69
75
  end
70
76
  end
@@ -161,7 +161,7 @@ module Keen
161
161
  def publish_body(path, body, error_method)
162
162
  begin
163
163
  response = Keen::HTTP::Sync.new(
164
- self.api_url, self.proxy_url).post(
164
+ self.api_url, self.proxy_url, self.read_timeout).post(
165
165
  :path => path,
166
166
  :headers => api_headers(self.write_key, "sync"),
167
167
  :body => body)
@@ -241,7 +241,7 @@ module Keen
241
241
 
242
242
  def get_response(url)
243
243
  uri = URI.parse(url)
244
- Keen::HTTP::Sync.new(self.api_url, self.proxy_url).get(
244
+ Keen::HTTP::Sync.new(self.api_url, self.proxy_url, self.read_timeout).get(
245
245
  :path => "#{uri.path}?#{uri.query}",
246
246
  :headers => api_headers(self.read_key, "sync")
247
247
  )
@@ -1,21 +1,16 @@
1
1
  module Keen
2
2
  module HTTP
3
3
  class Sync
4
- def initialize(base_url, proxy_url=nil)
4
+ def initialize(base_url, proxy_url=nil, read_timeout=nil)
5
5
  require 'uri'
6
6
  require 'net/http'
7
7
 
8
8
  uri = URI.parse(base_url)
9
- if proxy_url
10
- proxy_uri = URI.parse(proxy_url)
11
- @http = Net::HTTP::Proxy(
12
- proxy_uri.host,
13
- proxy_uri.port,
14
- proxy_uri.user,
15
- proxy_uri.password).new(uri.host, uri.port)
16
- else
17
- @http = Net::HTTP.new(uri.host, uri.port)
18
- end
9
+ arguments = [uri.host, uri.port]
10
+ arguments+= proxy_arguments_for(proxy_url) if proxy_url
11
+
12
+ @http = Net::HTTP.new(*arguments)
13
+ @http.read_timeout = read_timeout if read_timeout
19
14
 
20
15
  if uri.scheme == "https"
21
16
  require 'net/https'
@@ -26,6 +21,11 @@ module Keen
26
21
  end
27
22
  end
28
23
 
24
+ def proxy_arguments_for(uri)
25
+ proxy_uri = URI.parse(proxy_url)
26
+ [proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password]
27
+ end
28
+
29
29
  def post(options)
30
30
  path, headers, body = options.values_at(
31
31
  :path, :headers, :body)
@@ -1,3 +1,3 @@
1
1
  module Keen
2
- VERSION = "0.8.7"
2
+ VERSION = "0.8.8"
3
3
  end
@@ -6,12 +6,14 @@ describe Keen::Client do
6
6
  let(:read_key) { "abcderead" }
7
7
  let(:api_url) { "http://fake.keen.io:fakeport" }
8
8
  let(:client) { Keen::Client.new(:project_id => project_id) }
9
+ let(:read_timeout) { 40 }
9
10
 
10
11
  before do
11
12
  ENV["KEEN_PROJECT_ID"] = nil
12
13
  ENV["KEEN_WRITE_KEY"] = nil
13
14
  ENV["KEEN_READ_KEY"] = nil
14
15
  ENV["KEEN_API_URL"] = nil
16
+ ENV["KEEN_READ_TIMEOUT"] = nil
15
17
  end
16
18
 
17
19
  describe "#initialize" do
@@ -29,11 +31,13 @@ describe Keen::Client do
29
31
  :project_id => project_id,
30
32
  :write_key => write_key,
31
33
  :read_key => read_key,
32
- :api_url => api_url)
34
+ :api_url => api_url,
35
+ :read_timeout => read_timeout)
33
36
  client.write_key.should == write_key
34
37
  client.read_key.should == read_key
35
38
  client.project_id.should == project_id
36
39
  client.api_url.should == api_url
40
+ client.read_timeout.should == read_timeout
37
41
  end
38
42
 
39
43
  it "should set a default api_url" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.8.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-09-18 00:00:00.000000000 Z
14
+ date: 2014-12-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: multi_json