mixpanel_client 2.2.3 → 3.0.0
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 +22 -18
- data/lib/mixpanel/client.rb +22 -55
- data/lib/mixpanel/version.rb +1 -1
- data/mixpanel_client.gemspec +1 -1
- data/spec/mixpanel_client/events_externalspec.rb +44 -53
- data/spec/mixpanel_client/mixpanel_client_spec.rb +10 -71
- data/spec/mixpanel_client/properties_externalspec.rb +11 -14
- metadata +9 -12
data/README.md
CHANGED
@@ -17,27 +17,27 @@ or if you use a Gemfile
|
|
17
17
|
require 'rubygems'
|
18
18
|
require 'mixpanel_client'
|
19
19
|
|
20
|
-
config = {
|
20
|
+
config = {api_key: 'changeme', api_secret: 'changeme'}
|
21
21
|
client = Mixpanel::Client.new(config)
|
22
22
|
|
23
|
-
data = client.request
|
23
|
+
data = client.request('events/properties', {
|
24
24
|
# Available options
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
25
|
+
event: '["test-event"]',
|
26
|
+
name: 'hello',
|
27
|
+
values: '["uno", "dos"]',
|
28
|
+
timezone: '-8',
|
29
|
+
type: 'general',
|
30
|
+
unit: 'hour',
|
31
|
+
interval: 24,
|
32
|
+
limit: 5,
|
33
|
+
bucket: 'contents',
|
34
|
+
from_date: '2011-08-11',
|
35
|
+
to_date: '2011-08-12',
|
36
|
+
on: 'properties["product_id"]',
|
37
|
+
where: '1 in properties["product_id"]',
|
38
|
+
buckets: '5',
|
39
|
+
# etc.
|
40
|
+
})
|
41
41
|
|
42
42
|
puts data.inspect
|
43
43
|
|
@@ -74,6 +74,10 @@ Create tag v2.0.2 and build and push mixpanel_client-2.0.2.gem to Rubygems
|
|
74
74
|
|
75
75
|
## Changelog
|
76
76
|
|
77
|
+
### v.3.0.0
|
78
|
+
* NOTE: This version breaks backwards compatibility.
|
79
|
+
* Use a regular ruby hash instead of metaprogramming for mixpanel options.
|
80
|
+
|
77
81
|
### v.2.2.3
|
78
82
|
* Added some more options.
|
79
83
|
|
data/lib/mixpanel/client.rb
CHANGED
@@ -15,20 +15,6 @@ module Mixpanel
|
|
15
15
|
attr_reader :uri
|
16
16
|
attr_accessor :api_key, :api_secret
|
17
17
|
|
18
|
-
# Available options for a Mixpanel API request
|
19
|
-
OPTIONS = [:resource, :event, :events, :funnel_id, :name, :type, :unit, :interval, :length, :limit,
|
20
|
-
:format, :bucket, :values, :from_date, :to_date, :on, :where, :buckets, :timezone,
|
21
|
-
:retention_type, :interval_count, :born_event, :born_where]
|
22
|
-
|
23
|
-
# Dynamically define accessor methods for each option
|
24
|
-
OPTIONS.each do |option|
|
25
|
-
class_eval "
|
26
|
-
def #{option}(arg=nil)
|
27
|
-
arg ? @#{option} = arg : @#{option}
|
28
|
-
end
|
29
|
-
"
|
30
|
-
end
|
31
|
-
|
32
18
|
# Configure the client
|
33
19
|
#
|
34
20
|
# @example
|
@@ -37,31 +23,30 @@ module Mixpanel
|
|
37
23
|
#
|
38
24
|
# @param [Hash] config consisting of an 'api_key' and an 'api_secret'
|
39
25
|
def initialize(config)
|
40
|
-
@api_key = config[
|
41
|
-
@api_secret = config[
|
26
|
+
@api_key = config[:api_key]
|
27
|
+
@api_secret = config[:api_secret]
|
42
28
|
end
|
43
29
|
|
44
30
|
# Return mixpanel data as a JSON object or CSV string
|
45
31
|
#
|
46
32
|
# @example
|
47
|
-
# data = client.request
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
# end
|
33
|
+
# data = client.request('events/properties', {
|
34
|
+
# event: '["test-event"]',
|
35
|
+
# name: 'hello',
|
36
|
+
# values: '["uno", "dos"]',
|
37
|
+
# type: 'general',
|
38
|
+
# unit: 'hour',
|
39
|
+
# interval: 24,
|
40
|
+
# limit: 5,
|
41
|
+
# bucket: 'contents'
|
42
|
+
# })
|
58
43
|
#
|
59
|
-
# @
|
60
|
-
# @
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
@uri = URI.mixpanel(resource,
|
44
|
+
# @resource [String] mixpanel api resource endpoint
|
45
|
+
# @options [Hash] options variables used to make a specific request for mixpanel data
|
46
|
+
# @return [JSON, String] mixpanel response as a JSON object or CSV string
|
47
|
+
def request(resource, options)
|
48
|
+
@format = options[:format] || :json
|
49
|
+
@uri = URI.mixpanel(resource, normalize_options(options))
|
65
50
|
response = URI.get(@uri)
|
66
51
|
response = %Q|[#{response.split("\n").join(',')}]| if resource == 'export'
|
67
52
|
Utils.to_hash(response, @format)
|
@@ -69,33 +54,15 @@ module Mixpanel
|
|
69
54
|
|
70
55
|
private
|
71
56
|
|
72
|
-
# Reset options so we can reuse the Mixpanel::Client object without the options persisting
|
73
|
-
# between requests
|
74
|
-
def reset_options
|
75
|
-
(OPTIONS - [:resource]).each do |option|
|
76
|
-
eval "remove_instance_variable(:@#{option}) if defined?(@#{option})"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Return a hash of options for a given request
|
81
|
-
#
|
82
|
-
# @return [Hash] collection of options passed in from the request method
|
83
|
-
def params
|
84
|
-
OPTIONS.inject({}) do |params, param|
|
85
|
-
option = send(param)
|
86
|
-
params.merge!(param => option) if param != :resource && !option.nil?
|
87
|
-
params
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
57
|
# Return a hash of options along with defaults and a generated signature
|
92
58
|
#
|
93
59
|
# @return [Hash] collection of options including defaults and generated signature
|
94
|
-
def
|
95
|
-
|
60
|
+
def normalize_options(options)
|
61
|
+
options.merge!(
|
62
|
+
:format => @format,
|
96
63
|
:api_key => @api_key,
|
97
64
|
:expire => Time.now.to_i + 600 # Grant this request 10 minutes
|
98
|
-
).merge!(:sig => Utils.generate_signature(
|
65
|
+
).merge!(:sig => Utils.generate_signature(options, @api_secret))
|
99
66
|
end
|
100
67
|
|
101
68
|
def self.base_uri_for_resource(resource)
|
data/lib/mixpanel/version.rb
CHANGED
data/mixpanel_client.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ['lib']
|
21
21
|
|
22
22
|
s.add_runtime_dependency('json', '~> 1.6') if RUBY_VERSION < '1.9'
|
23
|
-
s.add_development_dependency('bundler', '>=1.
|
23
|
+
s.add_development_dependency('bundler', '>=1.2')
|
24
24
|
s.add_development_dependency('rake', '>=0.9.2.2')
|
25
25
|
s.add_development_dependency('rdoc', '>=3.11')
|
26
26
|
s.add_development_dependency('rspec', '>=2.5.0')
|
@@ -12,90 +12,81 @@ describe 'External calls to mixpanel' do
|
|
12
12
|
context 'when requesting events' do
|
13
13
|
it 'should raise an error for bad requests' do
|
14
14
|
data = lambda {
|
15
|
-
@client.request
|
16
|
-
resource 'events'
|
17
|
-
end
|
15
|
+
@client.request('events', {})
|
18
16
|
}
|
19
17
|
data.should raise_error(Mixpanel::HTTPError)
|
20
18
|
end
|
21
19
|
|
22
20
|
it 'should return events' do
|
23
|
-
data = @client.request
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
21
|
+
data = @client.request('events', {
|
22
|
+
:event => '["test-event"]',
|
23
|
+
:type => 'general',
|
24
|
+
:unit => 'hour',
|
25
|
+
:interval => 24
|
26
|
+
})
|
30
27
|
data.should_not be_a Exception
|
31
28
|
end
|
32
29
|
|
33
30
|
it 'should return events in csv format' do
|
34
|
-
data = @client.request
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
31
|
+
data = @client.request('events', {
|
32
|
+
:event => '["test-event"]',
|
33
|
+
:type => 'general',
|
34
|
+
:unit => 'hour',
|
35
|
+
:interval => 24,
|
36
|
+
:format => 'csv'
|
37
|
+
})
|
42
38
|
data.should_not be_a Exception
|
43
39
|
end
|
44
40
|
|
45
41
|
it 'should return events with optional bucket' do
|
46
|
-
data = @client.request
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
42
|
+
data = @client.request('events', {
|
43
|
+
:event => '["test-event"]',
|
44
|
+
:type => 'general',
|
45
|
+
:unit => 'hour',
|
46
|
+
:interval => 24,
|
47
|
+
:bucket => 'test'
|
48
|
+
})
|
54
49
|
data.should_not be_a Exception
|
55
50
|
end
|
56
51
|
|
57
52
|
it 'should return top events' do
|
58
|
-
data = @client.request
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
53
|
+
data = @client.request('events/top', {
|
54
|
+
:type => 'general',
|
55
|
+
:limit => 10
|
56
|
+
})
|
63
57
|
data.should_not be_a Exception
|
64
58
|
end
|
65
59
|
|
66
60
|
it 'should return names' do
|
67
|
-
data = @client.request
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
61
|
+
data = @client.request('events/names', {
|
62
|
+
:type => 'general',
|
63
|
+
:unit => 'hour',
|
64
|
+
:interval => 24,
|
65
|
+
:limit => 10
|
66
|
+
})
|
74
67
|
data.should_not be_a Exception
|
75
68
|
end
|
76
69
|
|
77
70
|
it 'should return retention' do
|
78
71
|
pending 'Retention now has its own endpoint.'
|
79
|
-
data = @client.request
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
72
|
+
data = @client.request('events/retention', {
|
73
|
+
:event => '["test-event"]',
|
74
|
+
:type => 'general',
|
75
|
+
:unit => 'hour',
|
76
|
+
:interval => 24
|
77
|
+
})
|
86
78
|
data.should_not be_a Exception
|
87
79
|
end
|
88
80
|
|
89
81
|
it 'should return retention in csv format' do
|
90
82
|
pending 'Retention now has its own endpoint.'
|
91
|
-
data = @client.request
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
83
|
+
data = @client.request('events/retention', {
|
84
|
+
:event => '["test-event"]',
|
85
|
+
:type => 'general',
|
86
|
+
:unit => 'hour',
|
87
|
+
:interval => 24,
|
88
|
+
:format => 'csv'
|
89
|
+
})
|
99
90
|
data.should_not be_a Exception
|
100
91
|
end
|
101
92
|
end
|
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe Mixpanel::Client do
|
4
4
|
before :all do
|
5
|
-
@client = Mixpanel::Client.new(
|
5
|
+
@client = Mixpanel::Client.new(:api_key => 'test_key', :api_secret => 'test_secret')
|
6
6
|
@uri = Regexp.escape(Mixpanel::Client::BASE_URI)
|
7
7
|
end
|
8
8
|
|
@@ -32,12 +32,11 @@ describe Mixpanel::Client do
|
|
32
32
|
stub_request(:get, /^#{@uri}.*/).to_return(:body => '{"legend_size": 0, "data": {"series": [], "values": {}}}')
|
33
33
|
|
34
34
|
# No endpoint
|
35
|
-
data = @client.request
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
35
|
+
data = @client.request('events', {
|
36
|
+
:event => '["test-event"]',
|
37
|
+
:unit => 'hour',
|
38
|
+
:interval => 24
|
39
|
+
})
|
41
40
|
data.should == {"data"=>{"series"=>[], "values"=>{}}, "legend_size"=>0}
|
42
41
|
end
|
43
42
|
|
@@ -46,25 +45,11 @@ describe Mixpanel::Client do
|
|
46
45
|
stub_request(:get, /^#{@uri}.*/).to_return(:body => '{"events": [], "type": "general"}')
|
47
46
|
|
48
47
|
# With endpoint
|
49
|
-
data = @client.request
|
50
|
-
|
51
|
-
|
52
|
-
end
|
48
|
+
data = @client.request('events/top', {
|
49
|
+
:type => 'general'
|
50
|
+
})
|
53
51
|
data.should == {"events"=>[], "type"=>"general"}
|
54
52
|
end
|
55
|
-
|
56
|
-
it 'should create getter methods for given options' do
|
57
|
-
@client.resource.should == 'events/top'
|
58
|
-
@client.type.should == 'general'
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should create setter methods for given options' do
|
62
|
-
@client.resource 'hi'
|
63
|
-
@client.resource.should == 'hi'
|
64
|
-
|
65
|
-
@client.type 'ok'
|
66
|
-
@client.type.should == 'ok'
|
67
|
-
end
|
68
53
|
end
|
69
54
|
|
70
55
|
describe '#hash_args' do
|
@@ -77,53 +62,7 @@ describe Mixpanel::Client do
|
|
77
62
|
|
78
63
|
describe '#to_hash' do
|
79
64
|
it 'should return a ruby hash given json as a string' do
|
80
|
-
Mixpanel::Client::Utils.to_hash('{"a" : "ey", "b" : "bee"}',
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
context 'when resetting options for each request' do
|
85
|
-
it 'should reset options before each request' do
|
86
|
-
# Stub Mixpanel request
|
87
|
-
stub_request(:get, /^#{@uri}.*/).to_return(:body => '{"events": [], "type": "general"}')
|
88
|
-
|
89
|
-
@client.request do
|
90
|
-
# This is not a real request. It just lists all possible options.
|
91
|
-
resource 'events'
|
92
|
-
event '["test-event"]'
|
93
|
-
funnel_id 'down-the-rabbit-hole'
|
94
|
-
name 'ricky-bobby'
|
95
|
-
type 'A'
|
96
|
-
unit 'hour'
|
97
|
-
interval 24
|
98
|
-
length 1
|
99
|
-
limit 5
|
100
|
-
format 'csv'
|
101
|
-
bucket 'list'
|
102
|
-
values '["tiger", "blood"]'
|
103
|
-
timezone '-8'
|
104
|
-
from_date '2011-08-11'
|
105
|
-
to_date '2011-08-12'
|
106
|
-
on 'properties["product_id"]'
|
107
|
-
where '1 in properties["product_id"]'
|
108
|
-
buckets '5'
|
109
|
-
events [{"event" => "page:view"}, {"event" => "button:click"}].to_json
|
110
|
-
retention_type 'abc'
|
111
|
-
born_event 'test-event'
|
112
|
-
born_where '1 in properties["product_id"]'
|
113
|
-
interval_count 'def'
|
114
|
-
end
|
115
|
-
|
116
|
-
Mixpanel::Client::OPTIONS.each do |option|
|
117
|
-
@client.send(option).should_not be_nil, "#{option} option was nil"
|
118
|
-
end
|
119
|
-
|
120
|
-
@client.request do
|
121
|
-
resource 'events/properties/top'
|
122
|
-
end
|
123
|
-
|
124
|
-
(Mixpanel::Client::OPTIONS - [:resource]).each do |option|
|
125
|
-
@client.send(option).should be_nil
|
126
|
-
end
|
65
|
+
Mixpanel::Client::Utils.to_hash('{"a" : "ey", "b" : "bee"}', :json).should == {'a' => 'ey', 'b' => 'bee'}
|
127
66
|
end
|
128
67
|
end
|
129
68
|
end
|
@@ -12,25 +12,22 @@ describe 'External calls to mixpanel' do
|
|
12
12
|
context 'when requesting event properties' do
|
13
13
|
it 'should raise an error for bad requests' do
|
14
14
|
data = lambda {
|
15
|
-
@client.request
|
16
|
-
resource 'properties'
|
17
|
-
end
|
15
|
+
@client.request('properties', {})
|
18
16
|
}
|
19
17
|
data.should raise_error(Mixpanel::HTTPError)
|
20
18
|
end
|
21
19
|
|
22
20
|
it 'should return events' do
|
23
|
-
data = @client.request
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
21
|
+
data = @client.request('events/properties', {
|
22
|
+
:event => '["test-event"]',
|
23
|
+
:name => 'hello',
|
24
|
+
:values => '["uno", "dos"]',
|
25
|
+
:type => 'general',
|
26
|
+
:unit => 'hour',
|
27
|
+
:interval => 24,
|
28
|
+
:limit => 5,
|
29
|
+
:bucket => 'kicked'
|
30
|
+
})
|
34
31
|
data.should_not be_a Exception
|
35
32
|
end
|
36
33
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixpanel_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
-
- 2
|
8
|
-
- 2
|
9
7
|
- 3
|
10
|
-
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 3.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Keolo Keagy
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-09-
|
19
|
-
default_executable:
|
18
|
+
date: 2012-09-22 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: json
|
@@ -41,12 +40,11 @@ dependencies:
|
|
41
40
|
requirements:
|
42
41
|
- - ">="
|
43
42
|
- !ruby/object:Gem::Version
|
44
|
-
hash:
|
43
|
+
hash: 11
|
45
44
|
segments:
|
46
45
|
- 1
|
47
|
-
-
|
48
|
-
|
49
|
-
version: 1.0.21
|
46
|
+
- 2
|
47
|
+
version: "1.2"
|
50
48
|
type: :development
|
51
49
|
version_requirements: *id002
|
52
50
|
- !ruby/object:Gem::Dependency
|
@@ -144,7 +142,6 @@ files:
|
|
144
142
|
- spec/mixpanel_client/properties_externalspec.rb
|
145
143
|
- spec/mixpanel_client/uri_spec.rb
|
146
144
|
- spec/spec_helper.rb
|
147
|
-
has_rdoc: true
|
148
145
|
homepage: http://github.com/keolo/mixpanel_client
|
149
146
|
licenses: []
|
150
147
|
|
@@ -174,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
171
|
requirements: []
|
175
172
|
|
176
173
|
rubyforge_project: mixpanel_client
|
177
|
-
rubygems_version: 1.
|
174
|
+
rubygems_version: 1.8.15
|
178
175
|
signing_key:
|
179
176
|
specification_version: 3
|
180
177
|
summary: Ruby Mixpanel API Client Library
|