grepdata_client 0.0.2 → 0.0.3
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.
- 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
|