embulk-input-mixpanel 0.5.14 → 0.5.15
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.
- checksums.yaml +4 -4
- data/.travis.yml +6 -3
- data/CHANGELOG.md +5 -1
- data/README.md +0 -3
- data/embulk-input-mixpanel.gemspec +2 -2
- data/lib/embulk/input/mixpanel.rb +2 -7
- data/lib/embulk/input/mixpanel_api/client.rb +5 -23
- data/test/embulk/input/mixpanel_api/test_client.rb +27 -31
- data/test/embulk/input/test_mixpanel.rb +0 -15
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c2a00332d19da50d63a726cac679e745206ccab
|
4
|
+
data.tar.gz: f2810c25272ee6b001f206dd0ddd93895c247ab6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 062a5d9d8948ba9efe802b477756484f03add6ce542d9bdbf40ee3988c2c943f5f6445fc32b15d05dfd0b909761fbf4f47f530e0e2d1357b1a57ca0c20074c55
|
7
|
+
data.tar.gz: df58ccf3ab6acad568681d57c39e97258849dc6e3946f5367ccdf31d64265d8c6d6afbb724259b66d21003b670b1763b6e097a0e871ff9bdaeb9e396f5e1b0cc
|
data/.travis.yml
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
|
-
|
3
|
+
dist: trusty
|
4
|
+
|
5
|
+
jdk: openjdk8
|
6
|
+
|
4
7
|
sudo: false
|
5
8
|
|
6
9
|
addons:
|
@@ -15,9 +18,9 @@ before_install:
|
|
15
18
|
ruby -v
|
16
19
|
rvm get head
|
17
20
|
rvm use jruby-9.0.5.0 --install
|
18
|
-
gem install bundler
|
21
|
+
gem install bundler -v '< 2'
|
19
22
|
ruby -v
|
20
|
-
- gem
|
23
|
+
- gem install bundler -v '< 2'
|
21
24
|
|
22
25
|
rvm:
|
23
26
|
- jruby-9.0.5.0
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
## 0.5.15 - 2020-01-22
|
2
|
+
|
3
|
+
* [enhancement] Update the authentication method to latest [#63](https://github.com/treasure-data/embulk-input-mixpanel/pull/63)
|
4
|
+
|
1
5
|
## 0.5.14 - 2018-10-22
|
2
6
|
|
3
|
-
* [enhancement] Handle the wrong period during transition from standard to daylight saving time exception [#
|
7
|
+
* [enhancement] Handle the wrong period during transition from standard to daylight saving time exception [#62](https://github.com/treasure-data/embulk-input-mixpanel/pull/62)
|
4
8
|
|
5
9
|
## 0.5.13 - 2018-10-04
|
6
10
|
|
data/README.md
CHANGED
@@ -31,7 +31,6 @@ To get it, you should log in mixpanel website, and click gear icon at the lower
|
|
31
31
|
|
32
32
|
### Configuration
|
33
33
|
|
34
|
-
- **api_key**: project API Key (string, required)
|
35
34
|
- **api_secret**: project API Secret (string, required)
|
36
35
|
- **export_endpoint**: the Data Export API's endpoint (string, default to "http://data.mixpanel.com/api/2.0/export")
|
37
36
|
- **timezone**: project timezone(string, required)
|
@@ -69,7 +68,6 @@ If you have such data and set config.yml as below.
|
|
69
68
|
```yaml
|
70
69
|
in:
|
71
70
|
type: mixpanel
|
72
|
-
api_key: "API_KEY"
|
73
71
|
api_secret: "API_SECRET"
|
74
72
|
timezone: "US/Pacific"
|
75
73
|
from_date: "2015-07-19"
|
@@ -102,7 +100,6 @@ in:
|
|
102
100
|
```yaml
|
103
101
|
in:
|
104
102
|
type: mixpanel
|
105
|
-
api_key: "API_KEY"
|
106
103
|
api_secret: "API_SECRET"
|
107
104
|
timezone: "US/Pacific"
|
108
105
|
from_date: "2015-07-19"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "embulk-input-mixpanel"
|
3
|
-
spec.version = "0.5.
|
3
|
+
spec.version = "0.5.15"
|
4
4
|
spec.authors = ["yoshihara", "uu59"]
|
5
5
|
spec.summary = "Mixpanel input plugin for Embulk"
|
6
6
|
spec.description = "Loads records from Mixpanel."
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.require_paths = ["lib"]
|
14
14
|
|
15
15
|
spec.add_dependency 'httpclient', '>= 2.8.3' # To use tcp_keepalive
|
16
|
-
spec.add_dependency 'tzinfo'
|
16
|
+
spec.add_dependency 'tzinfo', '1.2.5' # to avoid failure in when upgrade to 1.2.6 https://github.com/tzinfo/tzinfo/issues/114
|
17
17
|
spec.add_dependency 'perfect_retry', ["~> 0.5"]
|
18
18
|
spec.add_dependency 'activesupport'
|
19
19
|
spec.add_development_dependency 'bundler', ['~> 1.0']
|
@@ -61,7 +61,6 @@ module Embulk
|
|
61
61
|
dates: range,
|
62
62
|
timezone: timezone,
|
63
63
|
export_endpoint: export_endpoint(config),
|
64
|
-
api_key: config.param(:api_key, :string),
|
65
64
|
api_secret: config.param(:api_secret, :string),
|
66
65
|
schema: config.param(:columns, :array),
|
67
66
|
fetch_unknown_columns: fetch_unknown_columns,
|
@@ -129,8 +128,7 @@ module Embulk
|
|
129
128
|
retry_initial_wait_sec: config.param(:retry_initial_wait_sec, :integer, default: 1),
|
130
129
|
retry_limit: config.param(:retry_limit, :integer, default: 5),
|
131
130
|
})
|
132
|
-
client = MixpanelApi::Client.new(config.param(:
|
133
|
-
config.param(:api_secret, :string),
|
131
|
+
client = MixpanelApi::Client.new(config.param(:api_secret, :string),
|
134
132
|
retryer,
|
135
133
|
export_endpoint(config))
|
136
134
|
|
@@ -162,7 +160,6 @@ module Embulk
|
|
162
160
|
|
163
161
|
def init
|
164
162
|
@export_endpoint = task[:export_endpoint]
|
165
|
-
@api_key = task[:api_key]
|
166
163
|
@api_secret = task[:api_secret]
|
167
164
|
@params = task[:params]
|
168
165
|
@timezone = task[:timezone]
|
@@ -310,7 +307,7 @@ module Embulk
|
|
310
307
|
)
|
311
308
|
end
|
312
309
|
Embulk.logger.info "Where params is #{params["where"]}"
|
313
|
-
client = MixpanelApi::Client.new(@
|
310
|
+
client = MixpanelApi::Client.new(@api_secret, self.class.perfect_retry(task), @export_endpoint)
|
314
311
|
|
315
312
|
if preview?
|
316
313
|
client.export_for_small_dataset(params)
|
@@ -342,9 +339,7 @@ module Embulk
|
|
342
339
|
def self.export_params(config)
|
343
340
|
event = config.param(:event, :array, default: nil)
|
344
341
|
event = event.nil? ? nil : event.to_json
|
345
|
-
|
346
342
|
{
|
347
|
-
api_key: config.param(:api_key, :string),
|
348
343
|
event: event,
|
349
344
|
where: config.param(:where, :string, default: nil),
|
350
345
|
bucket: config.param(:bucket, :string, default: nil),
|
@@ -29,7 +29,9 @@ module Embulk
|
|
29
29
|
begin
|
30
30
|
retryer.with_retry do
|
31
31
|
client = HTTPClient.new
|
32
|
+
client.force_basic_auth = true
|
32
33
|
client.connect_timeout = PING_TIMEOUT_SECONDS
|
34
|
+
client.set_auth(nil, @api_secret, nil)
|
33
35
|
client.get(URI.join(endpoint, '/'))
|
34
36
|
end
|
35
37
|
true
|
@@ -38,9 +40,8 @@ module Embulk
|
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
|
-
def initialize(
|
43
|
+
def initialize(api_secret, retryer = nil, endpoint = DEFAULT_EXPORT_ENDPOINT)
|
42
44
|
@endpoint = endpoint
|
43
|
-
@api_key = api_key
|
44
45
|
@api_secret = api_secret
|
45
46
|
@retryer = retryer || PerfectRetry.new do |config|
|
46
47
|
# for test
|
@@ -100,7 +101,6 @@ module Embulk
|
|
100
101
|
def request(params, &block)
|
101
102
|
# https://mixpanel.com/docs/api-documentation/exporting-raw-data-you-inserted-into-mixpanel
|
102
103
|
Embulk.logger.debug "Export param: #{params.to_s}"
|
103
|
-
set_signatures(params)
|
104
104
|
|
105
105
|
buf = ""
|
106
106
|
error_response = ''
|
@@ -133,7 +133,6 @@ module Embulk
|
|
133
133
|
# guess/preview
|
134
134
|
# Try to fetch first number of records
|
135
135
|
params["limit"] = num_of_records
|
136
|
-
set_signatures(params)
|
137
136
|
Embulk.logger.info "Sending request to #{@endpoint}"
|
138
137
|
res = httpclient.get(@endpoint, params)
|
139
138
|
handle_error(res,res.body)
|
@@ -154,25 +153,6 @@ module Embulk
|
|
154
153
|
end
|
155
154
|
end
|
156
155
|
|
157
|
-
def set_signatures(params)
|
158
|
-
params[:expire] ||= Time.now.to_i + TIMEOUT_SECONDS
|
159
|
-
params[:sig] = signature(params)
|
160
|
-
params
|
161
|
-
end
|
162
|
-
|
163
|
-
def signature(params)
|
164
|
-
# https://mixpanel.com/docs/api-documentation/data-export-api#auth-implementation
|
165
|
-
params.delete(:sig)
|
166
|
-
sorted_keys = params.keys.map(&:to_s).sort
|
167
|
-
signature = sorted_keys.inject("") do |sig, key|
|
168
|
-
value = params[key] || params[key.to_sym]
|
169
|
-
next sig unless value
|
170
|
-
sig << "#{key}=#{value}"
|
171
|
-
end
|
172
|
-
|
173
|
-
Digest::MD5.hexdigest(signature + @api_secret)
|
174
|
-
end
|
175
|
-
|
176
156
|
def httpclient
|
177
157
|
@client ||=
|
178
158
|
begin
|
@@ -181,6 +161,8 @@ module Embulk
|
|
181
161
|
client.tcp_keepalive = true
|
182
162
|
client.default_header = {Accept: "application/json; charset=UTF-8"}
|
183
163
|
# client.debug_dev = STDERR
|
164
|
+
client.force_basic_auth = true
|
165
|
+
client.set_auth(nil, @api_secret, nil);
|
184
166
|
client
|
185
167
|
end
|
186
168
|
end
|
@@ -8,49 +8,28 @@ module Embulk
|
|
8
8
|
class ClientTest < Test::Unit::TestCase
|
9
9
|
include OverrideAssertRaise
|
10
10
|
|
11
|
-
API_KEY = "api_key".freeze
|
12
11
|
API_SECRET = "api_secret".freeze
|
13
12
|
|
14
13
|
def setup
|
15
|
-
@client = Client.new(
|
14
|
+
@client = Client.new(API_SECRET)
|
16
15
|
stub(Embulk).logger { ::Logger.new(IO::NULL) }
|
17
16
|
end
|
18
17
|
|
19
|
-
# NOTE: Client#signature is private method but this value
|
20
|
-
# can't be checked via other methods.
|
21
|
-
def test_signature
|
22
|
-
now = Time.parse("2015-07-22 00:00:00")
|
23
|
-
stub(Time).now { now }
|
24
|
-
|
25
|
-
params = {
|
26
|
-
string: "string",
|
27
|
-
array: ["elem1", "elem2"],
|
28
|
-
}
|
29
|
-
expected = "4be4a4f92f57e12b543a2a5f2f5897b6"
|
30
|
-
|
31
|
-
assert_equal(expected, @client.__send__(:signature, params))
|
32
|
-
end
|
33
|
-
|
34
18
|
class TestKeepAlive < self
|
35
19
|
def test_tcp_keepalive_enabled
|
36
|
-
client = Client.new(
|
20
|
+
client = Client.new(API_SECRET)
|
37
21
|
assert client.send(:httpclient).tcp_keepalive
|
38
22
|
end
|
39
23
|
end
|
40
24
|
|
41
25
|
class TryToDatesTest < self
|
42
26
|
def setup
|
43
|
-
@client = Client.new(
|
27
|
+
@client = Client.new(API_SECRET)
|
44
28
|
end
|
45
29
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
["2010-01-01", "2010-01-01"],
|
50
|
-
["3 days ago", (Date.today - 3).to_s],
|
51
|
-
]
|
52
|
-
end
|
53
|
-
def test_candidates(from_str)
|
30
|
+
|
31
|
+
def test_candidates_case1
|
32
|
+
from_str = "2000-01-01"
|
54
33
|
from = Date.parse(from_str)
|
55
34
|
yesterday = Date.today - 1
|
56
35
|
dates = @client.try_to_dates(from.to_s)
|
@@ -66,6 +45,24 @@ module Embulk
|
|
66
45
|
assert_equal expect, dates
|
67
46
|
assert dates.all?{|d| d <= yesterday}
|
68
47
|
end
|
48
|
+
|
49
|
+
def test_candidates_case2
|
50
|
+
from_str = (Date.today - 3).to_s
|
51
|
+
from = Date.parse(from_str)
|
52
|
+
yesterday = Date.today - 1
|
53
|
+
dates = @client.try_to_dates(from.to_s)
|
54
|
+
expect = [
|
55
|
+
from + 1,
|
56
|
+
from + 10,
|
57
|
+
from + 100,
|
58
|
+
from + 1000,
|
59
|
+
from + 10000,
|
60
|
+
yesterday,
|
61
|
+
].find_all{|d| d <= yesterday}
|
62
|
+
|
63
|
+
assert_equal expect, dates
|
64
|
+
assert dates.all?{|d| d <= yesterday}
|
65
|
+
end
|
69
66
|
end
|
70
67
|
|
71
68
|
class ExportTest < self
|
@@ -77,7 +74,7 @@ module Embulk
|
|
77
74
|
|
78
75
|
def test_success
|
79
76
|
stub_client
|
80
|
-
stub(@client).set_signatures(anything) {}
|
77
|
+
# stub(@client).set_signatures(anything) {}
|
81
78
|
stub_response(success_response)
|
82
79
|
|
83
80
|
records = []
|
@@ -90,7 +87,7 @@ module Embulk
|
|
90
87
|
|
91
88
|
def test_export_partial_with_export_terminated_early
|
92
89
|
stub_client
|
93
|
-
stub(@client).set_signatures(anything) {}
|
90
|
+
# stub(@client).set_signatures(anything) {}
|
94
91
|
stub_response(Struct.new(:code, :body).new(200, jsonl_dummy_responses+"\nexport terminated early"))
|
95
92
|
|
96
93
|
records = []
|
@@ -104,7 +101,7 @@ module Embulk
|
|
104
101
|
|
105
102
|
def test_export_partial_with_error_json
|
106
103
|
stub_client
|
107
|
-
stub(@client).set_signatures(anything) {}
|
104
|
+
# stub(@client).set_signatures(anything) {}
|
108
105
|
stub_response(Struct.new(:code, :body).new(200, jsonl_dummy_responses+"\n{\"error\":"))
|
109
106
|
records = []
|
110
107
|
assert_raise MixpanelApi::IncompleteExportResponseError do
|
@@ -203,7 +200,6 @@ module Embulk
|
|
203
200
|
|
204
201
|
def params
|
205
202
|
{
|
206
|
-
"api_key" => API_KEY,
|
207
203
|
"api_secret" => API_SECRET,
|
208
204
|
"from_date" => "2015-01-01",
|
209
205
|
"to_date" => "2015-03-02",
|
@@ -9,7 +9,6 @@ module Embulk
|
|
9
9
|
class MixpanelTest < Test::Unit::TestCase
|
10
10
|
include OverrideAssertRaise
|
11
11
|
|
12
|
-
API_KEY = "api_key".freeze
|
13
12
|
API_SECRET = "api_secret".freeze
|
14
13
|
FROM_DATE = "2015-02-22".freeze
|
15
14
|
TO_DATE = "2015-03-02".freeze
|
@@ -31,7 +30,6 @@ module Embulk
|
|
31
30
|
|
32
31
|
def setup_client
|
33
32
|
params = {
|
34
|
-
api_key: API_KEY,
|
35
33
|
event: nil,
|
36
34
|
where: nil,
|
37
35
|
bucket: nil,
|
@@ -72,7 +70,6 @@ module Embulk
|
|
72
70
|
def test_from_date_old_date
|
73
71
|
config = {
|
74
72
|
type: "mixpanel",
|
75
|
-
api_key: API_KEY,
|
76
73
|
api_secret: API_SECRET,
|
77
74
|
from_date: FROM_DATE,
|
78
75
|
}
|
@@ -87,7 +84,6 @@ module Embulk
|
|
87
84
|
def test_from_date_future
|
88
85
|
config = {
|
89
86
|
type: "mixpanel",
|
90
|
-
api_key: API_KEY,
|
91
87
|
api_secret: API_SECRET,
|
92
88
|
timezone: TIMEZONE,
|
93
89
|
from_date: (today + 1).to_s
|
@@ -103,7 +99,6 @@ module Embulk
|
|
103
99
|
from_date = (today - 1).to_s
|
104
100
|
config = {
|
105
101
|
type: "mixpanel",
|
106
|
-
api_key: API_KEY,
|
107
102
|
api_secret: API_SECRET,
|
108
103
|
from_date: from_date,
|
109
104
|
}
|
@@ -117,7 +112,6 @@ module Embulk
|
|
117
112
|
def test_no_from_date
|
118
113
|
config = {
|
119
114
|
type: "mixpanel",
|
120
|
-
api_key: API_KEY,
|
121
115
|
api_secret: API_SECRET,
|
122
116
|
timezone: TIMEZONE
|
123
117
|
}
|
@@ -141,7 +135,6 @@ module Embulk
|
|
141
135
|
stub(Embulk::Input::MixpanelApi::Client).mixpanel_available? { false }
|
142
136
|
config = {
|
143
137
|
type: "mixpanel",
|
144
|
-
api_key: API_KEY,
|
145
138
|
api_secret: API_SECRET,
|
146
139
|
}
|
147
140
|
|
@@ -300,7 +293,6 @@ module Embulk
|
|
300
293
|
def transaction_task(timezone)
|
301
294
|
task.merge(
|
302
295
|
dates: DATES.map {|date| date.to_s},
|
303
|
-
api_key: API_KEY,
|
304
296
|
api_secret: API_SECRET,
|
305
297
|
incremental: true,
|
306
298
|
incremental_column: nil,
|
@@ -366,7 +358,6 @@ module Embulk
|
|
366
358
|
from_date = Date.parse(FROM_DATE)
|
367
359
|
task.merge(
|
368
360
|
dates: (from_date..(from_date + days - 1)).map {|date| date.to_s},
|
369
|
-
api_key: API_KEY,
|
370
361
|
api_secret: API_SECRET,
|
371
362
|
timezone: TIMEZONE,
|
372
363
|
schema: schema
|
@@ -434,7 +425,6 @@ module Embulk
|
|
434
425
|
def transaction_task
|
435
426
|
task.merge(
|
436
427
|
dates: DATES.map {|date| date.to_s},
|
437
|
-
api_key: API_KEY,
|
438
428
|
api_secret: API_SECRET,
|
439
429
|
timezone: TIMEZONE,
|
440
430
|
schema: schema
|
@@ -451,7 +441,6 @@ module Embulk
|
|
451
441
|
def test_export_params
|
452
442
|
config_params = [
|
453
443
|
:type, "mixpanel",
|
454
|
-
:api_key, API_KEY,
|
455
444
|
:api_secret, API_SECRET,
|
456
445
|
:from_date, FROM_DATE,
|
457
446
|
:to_date, TO_DATE,
|
@@ -463,7 +452,6 @@ module Embulk
|
|
463
452
|
config = DataSource[*config_params]
|
464
453
|
|
465
454
|
expected = {
|
466
|
-
api_key: API_KEY,
|
467
455
|
event: "[\"ViewHoge\",\"ViewFuga\"]",
|
468
456
|
where: 'properties["$os"] == "Windows"',
|
469
457
|
bucket: "987",
|
@@ -541,7 +529,6 @@ module Embulk
|
|
541
529
|
|
542
530
|
def task
|
543
531
|
{
|
544
|
-
api_key: API_KEY,
|
545
532
|
api_secret: API_SECRET,
|
546
533
|
export_endpoint: "https://data.mixpanel.com/api/2.0/export/",
|
547
534
|
timezone: TIMEZONE,
|
@@ -846,7 +833,6 @@ module Embulk
|
|
846
833
|
|
847
834
|
def task
|
848
835
|
{
|
849
|
-
api_key: API_KEY,
|
850
836
|
api_secret: API_SECRET,
|
851
837
|
export_endpoint: "https://data.mixpanel.com/api/2.0/export/",
|
852
838
|
timezone: TIMEZONE,
|
@@ -891,7 +877,6 @@ module Embulk
|
|
891
877
|
def config
|
892
878
|
{
|
893
879
|
type: "mixpanel",
|
894
|
-
api_key: API_KEY,
|
895
880
|
api_secret: API_SECRET,
|
896
881
|
from_date: FROM_DATE,
|
897
882
|
fetch_days: DAYS,
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-input-mixpanel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yoshihara
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -28,17 +28,17 @@ dependencies:
|
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.2.5
|
34
34
|
name: tzinfo
|
35
35
|
prerelease: false
|
36
36
|
type: :runtime
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - '='
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: 1.2.5
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|