grepdata_client 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +132 -47
- data/lib/grepdata_client.rb +48 -41
- data/lib/grepdata_client/query.rb +1 -1
- data/lib/grepdata_client/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -1,36 +1,75 @@
|
|
1
|
-
|
1
|
+
GrepdataClient
|
2
2
|
|
3
|
-
Official Ruby client for Grepdata API
|
3
|
+
Official Ruby client for Grepdata API. More info on GrepData APIs can be found
|
4
|
+
in the [GrepData docs](www.grepdata.com/docs).
|
4
5
|
|
5
6
|
## Installation
|
6
7
|
|
7
8
|
gem install grepdata_client
|
9
|
+
gem install typhoeus
|
8
10
|
|
9
11
|
or if you use a Gemfile:
|
10
12
|
|
11
13
|
gem 'grepdata_client'
|
12
|
-
|
14
|
+
gem 'typhoeus'
|
15
|
+
|
13
16
|
## Publishing Events
|
14
17
|
|
18
|
+
The track call allows you to send data into the system, usually from client devices.
|
19
|
+
Setup the client with your public token (token) and the endpoint (default_endpoint),
|
20
|
+
generally either 'prod' or 'qa', to send data. These can be found in
|
21
|
+
[settings](www.grepdata.com/#/settings/account) and
|
22
|
+
[endpoints](www.grepdata.com/#/settings/endpoints) respectively. Each track call
|
23
|
+
requires a first parameter of event name and a second JSON object with any related
|
24
|
+
dimensions you would like to track along with this event. For more info see
|
25
|
+
[docs for sending data](www.grepdata.com/docs#sending).
|
26
|
+
|
27
|
+
###Example
|
28
|
+
|
15
29
|
require 'rubygems'
|
16
30
|
require 'grepdata_client'
|
17
31
|
|
18
|
-
client = GrepdataClient::Client.new(token
|
19
|
-
client.track 'play', data: { age
|
32
|
+
client = GrepdataClient::Client.new(:token => "abcdefghijklmnopqrstuvwxyz123456", :default_endpoint => 'prod')
|
33
|
+
client.track 'play', data: { :age => 18 }
|
20
34
|
|
21
35
|
## Querying Data
|
22
36
|
|
37
|
+
Querying data using the GrepData API is almost as simple as sending it. This time
|
38
|
+
the client is configured using the private key (api_key) for your account which can
|
39
|
+
be found in [settings](www.grepdata.com/#/settings/account).
|
40
|
+
|
41
|
+
|
42
|
+
### Data Query
|
43
|
+
|
44
|
+
Each data request requires a params object including the following fields:
|
45
|
+
+ **datamart** (string): the name of the datamart to query (endpoint name for timeseries data)
|
46
|
+
+ **dimensions** (array): all dimensions to query, be sure to include any dimensions being filtered
|
47
|
+
+ **filters** (JSON): an object containing any filters to apply to the selected dimensions, key is dimension name, value is array of valid options
|
48
|
+
+ **metrics** (array): all metrics columns you want aggregated and returned
|
49
|
+
+ **time_interval** (string): the time granularity to breakout, options are h => hour, d => day, m => month
|
50
|
+
+ **start_date** (string): the inclusive start of the query in format yyyymmddhh00
|
51
|
+
+ **end_date** (string): the inclusive end of the query in format yyyymmddhh00
|
52
|
+
|
53
|
+
The `client.query` call will return a query object which can be executed with the method `get_result` or printed as
|
54
|
+
a the complete API url that will be executed with `get_url`.
|
55
|
+
|
56
|
+
###Example
|
57
|
+
From the user_info datamart
|
58
|
+
Select the hour, country and the total count of events
|
59
|
+
Where the country is either US, UK or CA and the event was between 2013/06/11 08:00 and 2013/06/11 09:00
|
60
|
+
Grouped by hour and country
|
61
|
+
|
23
62
|
require 'rubygems'
|
24
63
|
require 'grepdata_client'
|
25
|
-
|
26
|
-
client = GrepdataClient::Client.new(:api_key => "
|
64
|
+
|
65
|
+
client = GrepdataClient::Client.new(:api_key => "abcdefghijklmnopqrstuvwxyz123456")
|
27
66
|
|
28
67
|
#Query
|
29
68
|
params = {
|
30
69
|
:datamart => "user_info",
|
31
70
|
:dimensions => %w(country),
|
32
71
|
:metrics => %w(Count),
|
33
|
-
:filters => { :country => %w(US) },
|
72
|
+
:filters => { :country => %w(US UK CA) },
|
34
73
|
:time_interval => "h",
|
35
74
|
:start_date => "201306110800",
|
36
75
|
:end_date => "201306110900"
|
@@ -38,6 +77,30 @@ or if you use a Gemfile:
|
|
38
77
|
req = client.query params
|
39
78
|
puts req.get_result
|
40
79
|
|
80
|
+
Funneling queries can also be issued from this client. Similar to querying above, the
|
81
|
+
client is configured with the api_key and fired with a set of query parameters:
|
82
|
+
+ **datamart** (string): the name of the datamart to query (endpoint name for timeseries data)
|
83
|
+
+ **funnel_dimension** (string): the dimension used to identify individual steps in this funnel, usually 'event'
|
84
|
+
+ **dimensions** (array): all dimensions included in the query, be sure to include any dimensions being filtered and funnel_dimension
|
85
|
+
+ **filters** (JSON): an object containing any filters to apply to the selected dimensions, key is dimension name, value is array of valid options
|
86
|
+
+ **metrics** (array): all metrics columns you want aggregated and returned
|
87
|
+
+ **time_interval** (string): the time granularity upon which to query, should align with start and end date boundaries, options are h => hour, d => day, m => month
|
88
|
+
+ **start_date** (string): the inclusive start of the query in format yyyymmddhh00
|
89
|
+
+ **end_date** (string): the inclusive end of the query in format yyyymmddhh00
|
90
|
+
+ **steps** (array of JSON): an ordered array containing JSON objects for each step with a friendly display name (name) and the actual dimension value in the data (value)
|
91
|
+
+ **only_totals** (boolean): a flag to indicate whether to collapse all data from the given timerange into a single total (true) or leave it broken out by time_interval (false)
|
92
|
+
|
93
|
+
###Example
|
94
|
+
From the demonstration datamart
|
95
|
+
Select the daily counts of play, pause, seek and stop events
|
96
|
+
Where the country is US and the events occurred between 2013/06/12 and 2013/06/19
|
97
|
+
Broken out by day and country
|
98
|
+
|
99
|
+
require 'rubygems'
|
100
|
+
require 'grepdata_client'
|
101
|
+
|
102
|
+
client = GrepdataClient::Client.new(:api_key => "abcdefghijklmnopqrstuvwxyz123456")
|
103
|
+
|
41
104
|
#Funneling
|
42
105
|
params = {
|
43
106
|
:datamart => 'demonstration',
|
@@ -51,67 +114,89 @@ or if you use a Gemfile:
|
|
51
114
|
{ :name => "step1: play", :value => "play" },
|
52
115
|
{ :name => "step2: pause", :value => "pause" },
|
53
116
|
{ :name => "step3: seek", :value => "seek" },
|
54
|
-
{ :name => "
|
117
|
+
{ :name => "step4: stop", :value => "stop" }
|
55
118
|
],
|
56
119
|
:filters => { :country => %w(US) },
|
57
120
|
:only_totals => false
|
58
121
|
}
|
59
122
|
req = client.funneling params
|
60
123
|
puts req.get_result
|
124
|
+
|
125
|
+
## Dimensions Query
|
126
|
+
|
127
|
+
Before querying for data, it may be useful to retreive a list of all available dimensions sent to a
|
128
|
+
given endpoint. This can be acheived with the dimensions query, simply by supplying the api_key
|
129
|
+
and the datamart name.
|
61
130
|
|
62
|
-
|
131
|
+
###Example
|
132
|
+
Show all dimensions that have been included with events sent to the demonstration endpoint
|
63
133
|
|
64
134
|
require 'rubygems'
|
65
135
|
require 'grepdata_client'
|
66
|
-
|
67
|
-
client = GrepdataClient::Client.new(:api_key => "0ac15f3688987af763c67412066e3378")
|
68
136
|
|
69
|
-
|
70
|
-
:datamart => "user_info",
|
71
|
-
:dimensions => %w(country),
|
72
|
-
:metrics => %w(Count),
|
73
|
-
:filters => { :country => %w(US) },
|
74
|
-
:time_interval => "h",
|
75
|
-
:start_date => "201306110800",
|
76
|
-
:end_date => "201306110900"
|
77
|
-
}
|
137
|
+
client = GrepdataClient::Client.new(:api_key => "abcdefghijklmnopqrstuvwxyz123456")
|
78
138
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
139
|
+
params = { :endpoint => 'demonstration' }
|
140
|
+
req = client.dimensions params
|
141
|
+
|
142
|
+
puts req.get_result
|
143
|
+
|
144
|
+
|
145
|
+
##Restricted Queries
|
146
|
+
While the above method for querying is relatively straight forward, it requires the use of your
|
147
|
+
secret api_key, a method which is only suitable for internal or server-side calls since anyone
|
148
|
+
with this key can access all your account's data. However, it is possible to safely expose a
|
149
|
+
controlled subset of the data externally without exposing your secret key.
|
150
|
+
|
151
|
+
We previously discussed the `client.query` call that generates a normal query, but there is also
|
152
|
+
a second method `client.get_safe_url` which will return a simple url using your public token
|
153
|
+
and a special 'signature' access token in place of the api_key. This url will not have your api_key
|
154
|
+
included and so it can safely be passed to a client and called from the client side.
|
85
155
|
|
86
|
-
|
156
|
+
The generated signature acts like a checksum, restricting the resulting query to execute only with
|
157
|
+
the restricted parameters you specify when calling `client.get_safe_url` on the server side. By
|
158
|
+
default, with no options set, the generated url will be signed such that no modifications are
|
159
|
+
possible. However, looser restrictions can be applied by passing a `restricted` array to the method.
|
160
|
+
This array of strings should contain all fields which the client should _not_ be allowed to change.
|
161
|
+
All other fields will be modifiable by the client (with the exception of datamart, which can never
|
162
|
+
be changed).
|
163
|
+
|
164
|
+
An optional `expiration` time is also available when generating the safe url generation to restrict
|
165
|
+
for how long the url will remain valid.
|
166
|
+
|
167
|
+
###Example
|
168
|
+
Generate a url that cannot be modified and a few which can be partially modified
|
87
169
|
|
88
170
|
require 'rubygems'
|
89
171
|
require 'grepdata_client'
|
90
|
-
|
91
|
-
client = GrepdataClient::Client.new(:token => "054a9c9ade7dcf325a3aab542ebd73b5")
|
92
172
|
|
93
|
-
#
|
94
|
-
|
95
|
-
:signature=>"0xBBKoaUe6RZSLM//6yqzbYelmI=",
|
96
|
-
:restricted=>"dimensions,filters.country",
|
97
|
-
:expiration=>"201306220100",
|
98
|
-
}
|
173
|
+
#note that we need to include both the token and api_key. The token can either be in this client initialization or in the params
|
174
|
+
client = GrepdataClient::Client.new(:api_key => "abcdefghijklmnopqrstuvwxyz123456", :token => "abcdefghijklmnopqrstuvwxyz123456")
|
99
175
|
|
100
176
|
params = {
|
101
177
|
:datamart => "user_info",
|
102
|
-
:dimensions => %w(country),
|
178
|
+
:dimensions => %w(country gender),
|
103
179
|
:metrics => %w(Count),
|
104
|
-
:filters => { :country => %w(US) },
|
180
|
+
:filters => { :country => %w(US UK), :gender => %w(M) },
|
105
181
|
:time_interval => "h",
|
106
182
|
:start_date => "201306110800",
|
107
183
|
:end_date => "201306110900"
|
108
184
|
}
|
109
|
-
|
110
|
-
req = client.query_with_token params, access_key
|
111
|
-
puts req.get_result
|
112
185
|
|
113
|
-
#
|
114
|
-
|
186
|
+
#generate a fully restricted, immutable request that expires at 201312312300
|
187
|
+
fully_safe_url = client.get_safe_url(params, expiration:"201312312300")
|
188
|
+
puts fully_safe_url
|
189
|
+
|
190
|
+
#generate a loosely restricted url that allows the client to modify only the dates and interval
|
191
|
+
restricted = %w(datamart dimensions metrics filters)
|
192
|
+
time_free_safe_url = client.get_safe_url(params, expiration:"201312312300", restricted:restricted)
|
193
|
+
puts time_free_safe_url
|
194
|
+
|
195
|
+
#individual filters may be locked with dot notation without other filters being locked as well
|
196
|
+
#this will generate a query which allows the gender filters to be changed but not the country
|
197
|
+
restricted = %w(datamart dimensions metrics filters.country)
|
198
|
+
time_and_gender_free_safe_url = client.get_safe_url(params, expiration:"201312312300", restricted:restricted)
|
199
|
+
puts time_and_gender_free_safe_url
|
115
200
|
|
116
201
|
## Running Request in Parallel
|
117
202
|
|
@@ -121,8 +206,8 @@ or if you use a Gemfile:
|
|
121
206
|
#set parallel to true
|
122
207
|
client = GrepdataClient::Client.new(
|
123
208
|
:default_endpoint => 'demonstration',
|
124
|
-
:token => "
|
125
|
-
:api_key => "
|
209
|
+
:token => "abcdefghijklmnopqrstuvwxyz123456",
|
210
|
+
:api_key => "abcdefghijklmnopqrstuvwxyz123456",
|
126
211
|
:parallel => true)
|
127
212
|
|
128
213
|
# query or publish data. Requests will be queued up
|
@@ -140,8 +225,8 @@ We use Typhoeus to handle parallel requests. You can also pass in your own hydr
|
|
140
225
|
hydra = ::Typhoeus::Hydra.new
|
141
226
|
client = GrepdataClient::Client.new(
|
142
227
|
:default_endpoint => 'demonstration',
|
143
|
-
:token => "
|
144
|
-
:api_key => "
|
228
|
+
:token => "abcdefghijklmnopqrstuvwxyz123456",
|
229
|
+
:api_key => "abcdefghijklmnopqrstuvwxyz123456",
|
145
230
|
:parallel => true,
|
146
231
|
:parallel_manager => hydra)
|
147
232
|
|
data/lib/grepdata_client.rb
CHANGED
@@ -2,7 +2,7 @@ require "typhoeus"
|
|
2
2
|
require 'base64'
|
3
3
|
require 'openssl'
|
4
4
|
require 'json'
|
5
|
-
require '
|
5
|
+
require 'date'
|
6
6
|
|
7
7
|
require "grepdata_client/version"
|
8
8
|
require "grepdata_client/query"
|
@@ -102,6 +102,52 @@ module GrepdataClient
|
|
102
102
|
request(__method__, params: params)
|
103
103
|
end
|
104
104
|
|
105
|
+
def get_safe_url(params, options={})
|
106
|
+
params[:token] = params[:token] || @token
|
107
|
+
api_key = params[:api_key] || @api_key
|
108
|
+
params.delete(:api_key)
|
109
|
+
params[:filters] = params[:filters] || {}
|
110
|
+
expiration = options[:expiration] || Utils.default_expiration
|
111
|
+
|
112
|
+
restricted = options[:restricted] || ["datamart", "dimensions", "metrics", "filters", "time_interval", "start_date", "end_date"]
|
113
|
+
|
114
|
+
access_key = generate_access_key(api_key, params:params, restricted:restricted, expiration:expiration)
|
115
|
+
|
116
|
+
Utils.preprocess_dates params, [:start_date, :end_date]
|
117
|
+
Utils.preprocess_dates access_key, [:expiration]
|
118
|
+
|
119
|
+
Utils.check_attributes "Request",
|
120
|
+
params: params,
|
121
|
+
required: {
|
122
|
+
token: String,
|
123
|
+
datamart: String,
|
124
|
+
dimensions: Array,
|
125
|
+
metrics: Array,
|
126
|
+
filters: Hash,
|
127
|
+
time_interval: String,
|
128
|
+
start_date: String,
|
129
|
+
end_date: String
|
130
|
+
}
|
131
|
+
|
132
|
+
Utils.check_attributes "access_key",
|
133
|
+
params: access_key,
|
134
|
+
required: {
|
135
|
+
signature: String,
|
136
|
+
restricted: String,
|
137
|
+
expiration: String
|
138
|
+
}
|
139
|
+
|
140
|
+
params[:signature] = access_key[:signature]
|
141
|
+
params[:restricted] = access_key[:restricted]
|
142
|
+
params[:expiration] = access_key[:expiration]
|
143
|
+
|
144
|
+
query = GrepdataClient::DataRequest.new "fetch",
|
145
|
+
url: @api_url,
|
146
|
+
params: params
|
147
|
+
|
148
|
+
query.get_url
|
149
|
+
end
|
150
|
+
|
105
151
|
def funneling(params)
|
106
152
|
params[:api_key] = params[:api_key] || @api_key
|
107
153
|
params[:filters] = params[:filters] || {}
|
@@ -140,46 +186,6 @@ module GrepdataClient
|
|
140
186
|
request(__method__, params: params)
|
141
187
|
end
|
142
188
|
|
143
|
-
def query_with_token(params, access_key)
|
144
|
-
params[:token] = params[:token] || @token
|
145
|
-
params[:filters] = params[:filters] || {}
|
146
|
-
|
147
|
-
Utils.preprocess_dates params, [:start_date, :end_date]
|
148
|
-
Utils.preprocess_dates access_key, [:expiration]
|
149
|
-
|
150
|
-
Utils.check_attributes "Request",
|
151
|
-
params: params,
|
152
|
-
required: {
|
153
|
-
token: String,
|
154
|
-
datamart: String,
|
155
|
-
dimensions: Array,
|
156
|
-
metrics: Array,
|
157
|
-
filters: Hash,
|
158
|
-
time_interval: String,
|
159
|
-
start_date: String,
|
160
|
-
end_date: String
|
161
|
-
}
|
162
|
-
|
163
|
-
Utils.check_attributes "access_key",
|
164
|
-
params: access_key,
|
165
|
-
required: {
|
166
|
-
signature: String,
|
167
|
-
restricted: String,
|
168
|
-
expiration: String
|
169
|
-
}
|
170
|
-
|
171
|
-
headers = {}
|
172
|
-
if @send_with_headers
|
173
|
-
headers = access_key
|
174
|
-
else
|
175
|
-
params[:signature] = access_key[:signature]
|
176
|
-
params[:restricted] = access_key[:restricted]
|
177
|
-
params[:expiration] = access_key[:expiration]
|
178
|
-
end
|
179
|
-
|
180
|
-
request('fetch', params: params, headers: headers)
|
181
|
-
end
|
182
|
-
|
183
189
|
def run_requests
|
184
190
|
@parallel_manager.run if @parallel_manager
|
185
191
|
end
|
@@ -240,3 +246,4 @@ module GrepdataClient
|
|
240
246
|
end
|
241
247
|
end
|
242
248
|
end
|
249
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grepdata_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: typhoeus
|