Class: Embulk::Input::MixpanelApi::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/embulk/input/mixpanel_api/client.rb

Constant Summary collapse

TIMEOUT_SECONDS =
3600
PING_TIMEOUT_SECONDS =
3
PING_RETRY_LIMIT =
3
PING_RETRY_WAIT =
2
SMALL_NUM_OF_RECORDS =
10
DEFAULT_EXPORT_ENDPOINT =
"https://data.mixpanel.com/api/2.0/export/".freeze
DEFAULT_JQL_ENDPOINT =
"https://mixpanel.com/api/2.0/jql/".freeze
JQL_RATE_LIMIT =
60

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_secret, endpoint, retryer = nil) ⇒ Client

Returns a new instance of Client.



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/embulk/input/mixpanel_api/client.rb', line 45

def initialize(api_secret, endpoint, retryer = nil)
  @endpoint = endpoint
  @api_secret = api_secret
  @retryer = retryer || PerfectRetry.new do |config|
    # for test
    config.limit = 0
    config.dont_rescues = [RuntimeError]
    config.log_level = nil
    config.logger = Embulk.logger
    config.raise_original_error = true
  end
end

Instance Attribute Details

#retryerObject (readonly)

Returns the value of attribute retryer.



20
21
22
# File 'lib/embulk/input/mixpanel_api/client.rb', line 20

def retryer
  @retryer
end

Class Method Details

.mixpanel_available?(endpoint = nil) ⇒ Boolean

Returns:

  • (Boolean)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/embulk/input/mixpanel_api/client.rb', line 22

def self.mixpanel_available?(endpoint = nil)
  endpoint ||= DEFAULT_EXPORT_ENDPOINT
  retryer = PerfectRetry.new do |config|
    config.limit = PING_RETRY_LIMIT
    config.sleep = PING_RETRY_WAIT
    config.logger = Embulk.logger
    config.log_level = nil
  end

  begin
    retryer.with_retry do
      client = HTTPClient.new
      client.force_basic_auth = true
      client.connect_timeout = PING_TIMEOUT_SECONDS
      client.set_auth(nil, @api_secret, nil)
      client.get(URI.join(endpoint, '/'))
    end
    true
  rescue PerfectRetry::TooManyRetry
    false
  end
end

Instance Method Details

#export(params = {}, &block) ⇒ Object



58
59
60
61
62
# File 'lib/embulk/input/mixpanel_api/client.rb', line 58

def export(params = {}, &block)
  retryer.with_retry do
    request(params, &block)
  end
end

#export_for_small_dataset(params = {}) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/embulk/input/mixpanel_api/client.rb', line 64

def export_for_small_dataset(params = {})
  yesterday = Date.today - 1
  latest_tried_to_date = nil
  try_to_dates(params["from_date"]).each do |to_date|
    next if yesterday < to_date
    latest_tried_to_date = to_date
    params["to_date"] = to_date.strftime("%Y-%m-%d")
    records = retryer.with_retry do
      request_small_dataset(params, SMALL_NUM_OF_RECORDS)
    end
    next if records.first.nil?
    return records
  end

  raise ConfigError.new "#{params["from_date"]}..#{latest_tried_to_date} has no record."
end

#send_jql_script(params = {}) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/embulk/input/mixpanel_api/client.rb', line 81

def send_jql_script(params = {})
  retryer.with_retry do
    response = request_jql(params)
    handle_error(response, response.body)
    begin
      return JSON.parse(response.body)
      rescue =>e
      raise Embulk::DataError.new(e)
    end
  end
end

#send_jql_script_small_dataset(params = {}) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/embulk/input/mixpanel_api/client.rb', line 93

def send_jql_script_small_dataset(params = {})
  retryer.with_retry do
    response = request_jql(params)
    handle_error(response, response.body)
    begin
      return JSON.parse(response.body)[0..SMALL_NUM_OF_RECORDS - 1]
      rescue =>e
      raise Embulk::DataError.new(e.message)
    end
  end
end

#try_to_dates(from_date) ⇒ Object



105
106
107
108
109
110
111
112
113
114
# File 'lib/embulk/input/mixpanel_api/client.rb', line 105

def try_to_dates(from_date)
  try_to_dates = 5.times.map do |n|
    # from_date + 1, from_date + 10, from_date + 100, ... so on
    days = 1 * (10 ** n)
    Date.parse(from_date.to_s) + days
  end
  yesterday = Date.today - 1
  try_to_dates << yesterday
  try_to_dates.find_all {|date| date <= yesterday}.uniq
end