holistics 0.2.9 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b19979733fe3e8b7e3291a2d191b3fdd6f162274
4
- data.tar.gz: d3c4dfcfa4b1b65159c3ba307e50940cd2af5bb8
2
+ SHA256:
3
+ metadata.gz: 07bec8a025b674144e6fb6e35b9ef2c9a279e917e2187587d83a75e025f369c0
4
+ data.tar.gz: abe49de6255090ee1c96898df73eeb25ee3cc88dd36eef7233901c12dbc87980
5
5
  SHA512:
6
- metadata.gz: 855138b11b0725a28f254012e2c60c1765a87e4f41859f8aa6609a644d4dff6a7c7326c0a3c6e11414dfbc72302db5a4e964aca9a423f9471af41bb29e178ae2
7
- data.tar.gz: 1a5fe165c00d5bfb606d10e2e6dd9ca7b36ed565d2beb7dacbe68093c62df84aa8cbe0534776e691e4bdc11269ec3a6e9bc26a4a4f2db5f508ec1682d8e5ffd9
6
+ metadata.gz: d63c018afd38938a15be260b6ccdd63f3168d2ebba073789cba120cab1c52ea2fde9592061d580c1bfd5a166ca2662461bf16462d9b090b5fc1b951a86cec3ec
7
+ data.tar.gz: 6cef3b620618a6bbc562bc3ec6ed55197036ec18ebefe3ddc1c78e01492695dc17f58906df85b2054ed73f1b7e049832a302d4a64c54e84f30e98a50ba16d1fa
@@ -2,24 +2,39 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
- ## v0.0.11
6
- * Support invocation of transform from CLI: `holistics transform -j <id>`
5
+ ## v0.3.4
6
+ * Update retry mechanism for `fetch_job_details`
7
7
 
8
- ## v0.0.12
9
- * Support generation of transport config files from CLI: `holistics generate_configs -s <src_ds_id> -d <dest_ds_id> -t <tables> [-o <output>]`
8
+ ## v0.3.3
9
+ * Add "transform list" and "import list" commands
10
+ * Add "version" command
10
11
 
11
- ## v0.1.0
12
- * Modularized transport and data_sources commands. Rename existing transport command to transport_old.
12
+ ## v0.3.2
13
+ * Add 'colorize' to gemspec dependencies
13
14
 
14
- ## v0.2.0
15
- * Support command to import csv into table
15
+ ## v0.3.1
16
+ * Add option to split a custom range Data Import execution into smaller ones
16
17
 
17
- ## v0.2.1
18
- * Fix dependency error
18
+ ## v0.3.0
19
+ * Add option to execute Data Imports in custom range mode
20
+
21
+ ## v0.2.6
22
+ * Add error handling and retry mechanism for `fetch_job_details`
19
23
 
20
24
  ## v0.2.5
21
25
  * Support invoking email schedule with `holistics email_schedule trigger <id>`
22
26
 
23
- ## v0.2.6
24
- * Add error handling and retry mechanism for `fetch_job_details`
27
+ ## v0.2.1
28
+ * Fix dependency error
29
+
30
+ ## v0.2.0
31
+ * Support command to import csv into table
32
+
33
+ ## v0.1.0
34
+ * Modularized transport and data_sources commands. Rename existing transport command to transport_old.
25
35
 
36
+ ## v0.0.12
37
+ * Support generation of transport config files from CLI: `holistics generate_configs -s <src_ds_id> -d <dest_ds_id> -t <tables> [-o <output>]`
38
+
39
+ ## v0.0.11
40
+ * Support invocation of transform from CLI: `holistics transform -j <id>`
data/README.md CHANGED
@@ -8,6 +8,7 @@ Command-line interface to Holistics API
8
8
  First, open `version.rb` and increase the version number. Please also update the changelog too.
9
9
 
10
10
  Then run the following:
11
+ $ git tag -a v0.0.3 && git push --tags
11
12
 
12
13
  $ gem build holistics.gemspec
13
14
  WARNING: description and summary are identical
@@ -26,5 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'httparty', '~> 0.13'
27
27
  spec.add_dependency 'thor', '~> 0.19'
28
28
  spec.add_dependency 'multipart-post', '~> 2.0'
29
+ spec.add_dependency "colorize", "~> 0.8.1"
29
30
 
30
31
  end
@@ -1,12 +1,14 @@
1
1
  require 'thor'
2
2
  require 'vcr_helper'
3
3
 
4
+ require 'holistics/version'
4
5
  require 'holistics/api_client'
5
6
  require 'holistics/custom_logger'
6
7
  require 'holistics/auth_api_client'
7
8
 
8
9
  require 'import'
9
10
  require 'transport'
11
+ require 'transform'
10
12
  require 'data_sources'
11
13
  require 'email_schedule'
12
14
 
@@ -43,6 +45,7 @@ module Holistics
43
45
 
44
46
  register(Holistics::Import, 'import', 'import <command>', "Execute import commands")
45
47
  register(Holistics::Transport, 'transport', 'transport <command>', "Execute transport module's commands")
48
+ register(Holistics::Transform, 'transform', 'transform <command>', "Execute transform module's commands")
46
49
  register(Holistics::DataSources, 'data_sources', 'data_sources <command>', "Execute data_sources module's commands")
47
50
  register(Holistics::EmailSchedule, 'email_schedule', 'email_schedule <command>', "Execute email schedule's commands")
48
51
 
@@ -69,13 +72,6 @@ module Holistics
69
72
  api_client.ds_list
70
73
  end
71
74
 
72
- method_option :transform_id, aliases: '-j', type: :string, required: true, desc: 'ID of transform job to be executed'
73
- desc 'transform', 'Invoke a transform'
74
-
75
- def transform
76
- api_client.send_transform(options.dup)
77
- end
78
-
79
75
  method_option :job_id, aliases: '-j', type: :string, required: true, desc: 'Job ID'
80
76
  desc 'job_show', 'Show job log'
81
77
 
@@ -83,5 +79,9 @@ module Holistics
83
79
  api_client.job_show(options.dup)
84
80
  end
85
81
 
82
+ desc 'version', "Show current Holistics gem's version"
83
+ def version
84
+ puts Holistics::VERSION
85
+ end
86
86
  end
87
87
  end
@@ -7,6 +7,8 @@ require 'holistics/helpers/job_manager'
7
7
 
8
8
  module Holistics
9
9
  class ApiClient
10
+ class ImportError < StandardError
11
+ end
10
12
 
11
13
  def import_csv options
12
14
  local_filepath = options[:filepath]
@@ -47,6 +49,26 @@ module Holistics
47
49
  puts TabularFormatter.new(table).to_pretty_table
48
50
  end
49
51
 
52
+ def import_list
53
+ result = http_request.get 'data_imports.json', 'Error retrieving list of data imports'
54
+
55
+ table = [%w(ID Name)]
56
+ rows = result.map {|record| [record['id'], record['title']]}
57
+ table.concat(rows)
58
+
59
+ puts TabularFormatter.new(table).to_pretty_table
60
+ end
61
+
62
+ def transform_list
63
+ result = http_request.get 'data_transforms.json', 'Error retrieving list of data transports'
64
+
65
+ table = [%w(ID Name)]
66
+ rows = result.map {|record| [record['id'], record['title']]}
67
+ table.concat(rows)
68
+
69
+ puts TabularFormatter.new(table).to_pretty_table
70
+ end
71
+
50
72
  def send_transport(options)
51
73
  puts 'Submitting transport job ...'
52
74
 
@@ -89,6 +111,10 @@ module Holistics
89
111
 
90
112
  puts "Job submitted. Job ID: #{job_id}."
91
113
  job_manager.tail_logs job_id
114
+ res = job_manager.fetch_job_results job_id
115
+ unless res['status'] == 'success'
116
+ raise ImportError.new("Failed Import Job #{job_id}: #{res['error']}")
117
+ end
92
118
  end
93
119
 
94
120
  def job_show(options)
@@ -9,19 +9,24 @@ module Holistics
9
9
 
10
10
  def fetch_job_details(job_id, last_id = 0)
11
11
  tries ||= MAX_RETRIES
12
-
12
+
13
13
  url = auth_helper.api_url_for("jobs/#{job_id}/logs.json", last_id: last_id)
14
- response = HttpRequest.new.simple_get url
15
-
14
+ response = http_request.simple_get url
15
+
16
16
  JSON.parse(response.body)
17
- rescue JSON::ParserError => err
17
+ rescue StandardError => e
18
18
  sleep 2 ** (MAX_RETRIES - tries) unless Holistics.test?
19
19
  if (tries -= 1) >= 0
20
20
  puts 'Retrying...'
21
21
  retry
22
22
  end
23
23
  puts 'Retry exceeded... Raise error'
24
- raise
24
+ raise e
25
+ end
26
+
27
+ def fetch_job_results(job_id)
28
+ url = "jobs/#{job_id}/get_results.json"
29
+ http_request.get(url, "Cannot fetch info of job #{job_id}")
25
30
  end
26
31
 
27
32
  def job_show options
@@ -47,6 +52,12 @@ module Holistics
47
52
  ts = Time.parse(log['timestamp'])
48
53
  Holistics.logger.log(log['level'], log['message'], timestamp: ts)
49
54
  end
55
+
56
+ private
57
+
58
+ def http_request
59
+ @http_request ||= HttpRequest.new
60
+ end
50
61
  end
51
62
  end
52
63
  end
@@ -1,4 +1,4 @@
1
1
  module Holistics
2
- VERSION = '0.2.9'
3
- DATE = '2017-10-27'
2
+ VERSION = '0.3.4'
3
+ DATE = '2018-08-24'
4
4
  end
@@ -1,4 +1,5 @@
1
1
  require 'thor'
2
+ require 'colorize'
2
3
 
3
4
  module Holistics
4
5
  class Import < Thor
@@ -15,13 +16,14 @@ module Holistics
15
16
 
16
17
  # execute import job
17
18
  method_option :import_id, aliases: '-j', type: :string, required: true, desc: 'ID of import job to be executed'
18
- method_option :range, aliases: '--range', type: :boolean, required: false, desc: 'Execution type is custom_range. The range of left-closed right-opened range `[start, end)`.'
19
- method_option :range_start, aliases: '--start', type: :string, required: false, desc: 'start range'
20
- method_option :range_end, aliases: '--end', type: :string, required: false, desc: 'end range'
19
+ method_option :custom_range, aliases: '--custom-range', type: :boolean, lazy_default: true, required: false, desc: 'Execution type is custom_range. The range of left-closed right-opened range `[start, end)`.'
20
+ method_option :range_start, aliases: '--range-start', type: :string, required: false, desc: 'start range'
21
+ method_option :range_end, aliases: '--range-end', type: :string, required: false, desc: 'end range'
22
+ method_option :split_mode, aliases: '--split-mode', type: :string, required: false, desc: "Import splitting mode. Use 'daily' to split your custom range import to multiple executions, each covering one day of data."
21
23
  desc 'execute', 'Invoke an import job'
22
24
 
23
25
  def execute
24
- range_mode = options[:range]
26
+ range_mode = options[:custom_range]
25
27
  params = {
26
28
  import_id: options[:import_id]
27
29
  }
@@ -30,8 +32,19 @@ module Holistics
30
32
  params[:range_start] = options[:range_start]
31
33
  params[:range_end] = options[:range_end]
32
34
  params[:execution_mode] = 'custom_range'
35
+ if options[:split_mode] == 'daily'
36
+ return daily_splitted_import(params.dup)
37
+ end
33
38
  end
34
- api_client.send_import(params.dup)
39
+ send_import(params)
40
+ rescue => e
41
+ STDERR.puts e.message.red
42
+ exit 1
43
+ end
44
+
45
+ desc 'list', 'List all data imports'
46
+ def list
47
+ api_client.import_list
35
48
  end
36
49
 
37
50
  no_commands do
@@ -39,5 +52,36 @@ module Holistics
39
52
  @api_client ||= ApiClient.new
40
53
  end
41
54
  end
55
+
56
+ private
57
+
58
+ def daily_splitted_import(params)
59
+ start_date = Date.parse(params[:range_start]) rescue raise("Invalid range start")
60
+ if params[:range_end]
61
+ end_date = Date.parse(params[:range_end]) rescue raise("Invalid range end")
62
+ else
63
+ end_date = Date.today
64
+ end
65
+ while start_date + 1 < end_date
66
+ params[:range_start] = start_date.strftime('%Y-%m-%d')
67
+ params[:range_end] = (start_date + 1).strftime('%Y-%m-%d')
68
+ puts "Importing range '#{params[:range_start]}' - '#{params[:range_end]}'".green
69
+ send_import(params, tries: 2)
70
+ start_date = start_date + 1
71
+ end
72
+ end
73
+
74
+ def send_import(params, tries: 0)
75
+ total_trials ||= tries
76
+ api_client.send_import(params.dup)
77
+ rescue ApiClient::ImportError => e
78
+ sleep 2 ** (total_trials - tries) unless Holistics.test?
79
+ if (tries -= 1) >= 0
80
+ puts 'Retrying...'.orange
81
+ retry
82
+ end
83
+ puts "Exceeded retry count of #{total_trials}...".orange if total_trials > 0
84
+ raise
85
+ end
42
86
  end
43
- end
87
+ end
@@ -0,0 +1,29 @@
1
+ require 'thor'
2
+
3
+ module Holistics
4
+ class Transform < Thor
5
+
6
+ no_commands do
7
+ def api_client
8
+ @api_client ||= ApiClient.new
9
+ end
10
+ end
11
+
12
+ method_option :transform_id, aliases: '-j', type: :string, desc: 'ID of transform job to be executed'
13
+ desc 'transform', 'Invoke a transform'
14
+
15
+ def transform
16
+ unless options['transform_id']
17
+ puts "Please include a tranform job ID to execute. Usage: 'holistics transform --transform-id <id>'."
18
+ exit 1
19
+ end
20
+ api_client.send_transform(options.dup)
21
+ end
22
+ default_task :transform
23
+
24
+ desc 'list', 'List all data transforms'
25
+ def list
26
+ api_client.transform_list
27
+ end
28
+ end
29
+ end
@@ -30,4 +30,4 @@ module Holistics
30
30
  api_client.generate_configs(options.dup)
31
31
  end
32
32
  end
33
- end
33
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: holistics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thanh Dinh Khac
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-10-27 00:00:00.000000000 Z
12
+ date: 2018-08-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -81,6 +81,20 @@ dependencies:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
83
  version: '2.0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: colorize
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 0.8.1
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 0.8.1
84
98
  description: CLI interface for Holistics
85
99
  email: huy@holistics.io
86
100
  executables:
@@ -105,6 +119,7 @@ files:
105
119
  - lib/holistics/version.rb
106
120
  - lib/import.rb
107
121
  - lib/tabular_formatter.rb
122
+ - lib/transform.rb
108
123
  - lib/transport.rb
109
124
  - lib/vcr_helper.rb
110
125
  homepage: http://rubygems.org/gems/holistics-cli
@@ -128,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
143
  version: '0'
129
144
  requirements: []
130
145
  rubyforge_project:
131
- rubygems_version: 2.5.1
146
+ rubygems_version: 2.7.7
132
147
  signing_key:
133
148
  specification_version: 4
134
149
  summary: CLI interface for Holistics