holistics 0.3.0 → 0.3.5

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
2
  SHA1:
3
- metadata.gz: 971907f72fa1cd5696fcb351d9c3ef571a40990e
4
- data.tar.gz: 865601ab1b96aba716d23ddec7eb3a13db454100
3
+ metadata.gz: cab913239d13210e0e3c091b01bc3f9b61cdc78d
4
+ data.tar.gz: 53b64ba89eb7ffb7134b7b80c15948d291b75efe
5
5
  SHA512:
6
- metadata.gz: 47788d94da15628c6100e653c4bb371c07e245fe0733dfbc039a101ff6a8f806123e98a76c188e49d31c3f1b6a2cb8414a3a17a2a77bf8ef51c50395ca651d02
7
- data.tar.gz: e9db1824bdd8a394de9cad3e2d592bb4f03891d40539b860d7a8eccd3b54f94fa1bd11db834378a781e80f639bf9ed9ed39350ce074b210af4b539d23312b4fa
6
+ metadata.gz: 89b361bb3763a3c89c59ffe4845d5f3b1625da74292fd6e19164dfb19ee1814566e9c8f246f7d7a753fb56a4e926c7894738099006dad0063f2c4dc1e1753925
7
+ data.tar.gz: f115d45d5baa6972a7d30d2b9610032aa39b924d1cf97c1ff98101cfc20e9ca8e6b640b5830245c77f39b1a2915e3c424ebdc40d3959eb7d68d90b8646eefa1c
data/CHANGELOG.md CHANGED
@@ -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
data/holistics.gemspec CHANGED
@@ -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
data/lib/holistics.rb CHANGED
@@ -1,12 +1,15 @@
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'
10
+ require 'import_chunking'
9
11
  require 'transport'
12
+ require 'transform'
10
13
  require 'data_sources'
11
14
  require 'email_schedule'
12
15
 
@@ -42,7 +45,9 @@ module Holistics
42
45
  end
43
46
 
44
47
  register(Holistics::Import, 'import', 'import <command>', "Execute import commands")
48
+ register(Holistics::ImportChunking, 'import_chunking', 'import_chunking <command>', "Generate import chunks for date range imports")
45
49
  register(Holistics::Transport, 'transport', 'transport <command>', "Execute transport module's commands")
50
+ register(Holistics::Transform, 'transform', 'transform <command>', "Execute transform module's commands")
46
51
  register(Holistics::DataSources, 'data_sources', 'data_sources <command>', "Execute data_sources module's commands")
47
52
  register(Holistics::EmailSchedule, 'email_schedule', 'email_schedule <command>', "Execute email schedule's commands")
48
53
 
@@ -69,13 +74,6 @@ module Holistics
69
74
  api_client.ds_list
70
75
  end
71
76
 
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
77
  method_option :job_id, aliases: '-j', type: :string, required: true, desc: 'Job ID'
80
78
  desc 'job_show', 'Show job log'
81
79
 
@@ -83,5 +81,9 @@ module Holistics
83
81
  api_client.job_show(options.dup)
84
82
  end
85
83
 
84
+ desc 'version', "Show current Holistics gem's version"
85
+ def version
86
+ puts Holistics::VERSION
87
+ end
86
88
  end
87
89
  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.3.0'
3
- DATE = '2017-10-27'
2
+ VERSION = '0.3.5'
3
+ DATE = '2021-04-19'
4
4
  end
data/lib/import.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'thor'
2
+ require 'colorize'
2
3
 
3
4
  module Holistics
4
5
  class Import < Thor
@@ -18,6 +19,7 @@ module Holistics
18
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)`.'
19
20
  method_option :range_start, aliases: '--range-start', type: :string, required: false, desc: 'start range'
20
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
@@ -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,52 @@
1
+ require 'thor'
2
+ require 'colorize'
3
+ require 'time'
4
+
5
+ module Holistics
6
+ class ImportChunking < Thor
7
+
8
+
9
+ # Example
10
+ # holistics import_chunking execute -j 29283 --range-start 2020-8-01T00:00:00Z --range-end 2021-9-01T00:00:00Z --chunk-days 10
11
+
12
+
13
+ method_option :import_id, aliases: '-j', type: :string, required: true, desc: 'ID of import job to be executed'
14
+ method_option :range_start, aliases: '--range-start', type: :string, required: true, desc: 'start range'
15
+ method_option :range_end, aliases: '--range-end', type: :string, required: true, desc: 'end range'
16
+ method_option :chunk_days, aliases: '--chunk-days', type: :numeric, required: true, desc: 'The range in days of each import'
17
+
18
+ desc 'execute', 'Generate import chunks for a date range'
19
+ def execute
20
+ one_day = 86_400
21
+ chunk_duration = one_day * options[:chunk_days]
22
+
23
+ date_start = Time.parse(options[:range_start])
24
+ date_end = Time.parse(options[:range_end])
25
+
26
+ generated_result = []
27
+
28
+ current_time = date_start
29
+
30
+ while current_time < date_end
31
+ chunk_start = current_time
32
+ chunk_end = current_time + chunk_duration
33
+
34
+ generated_result << gen_command(options[:import_id],
35
+ chunk_start,
36
+ chunk_end < date_end ? chunk_end : date_end)
37
+
38
+ current_time += chunk_duration
39
+ end
40
+
41
+ puts generated_result.join(" && \\ \n")
42
+ end
43
+
44
+ private
45
+
46
+ def gen_command(id, range_start, range_end)
47
+ start_str = range_start.utc.iso8601
48
+ end_str = range_end.utc.iso8601
49
+ "holistics import execute -j #{id} --custom-range --range-start #{start_str} --range-end #{end_str}"
50
+ end
51
+ end
52
+ end
data/lib/transform.rb ADDED
@@ -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
data/lib/transport.rb CHANGED
@@ -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,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: holistics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thanh Dinh Khac
8
8
  - Huy Nguyen
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-10-27 00:00:00.000000000 Z
12
+ date: 2021-04-19 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:
@@ -104,14 +118,16 @@ files:
104
118
  - lib/holistics/helpers/job_manager.rb
105
119
  - lib/holistics/version.rb
106
120
  - lib/import.rb
121
+ - lib/import_chunking.rb
107
122
  - lib/tabular_formatter.rb
123
+ - lib/transform.rb
108
124
  - lib/transport.rb
109
125
  - lib/vcr_helper.rb
110
126
  homepage: http://rubygems.org/gems/holistics-cli
111
127
  licenses:
112
128
  - GPL
113
129
  metadata: {}
114
- post_install_message:
130
+ post_install_message:
115
131
  rdoc_options: []
116
132
  require_paths:
117
133
  - lib
@@ -127,9 +143,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
143
  - !ruby/object:Gem::Version
128
144
  version: '0'
129
145
  requirements: []
130
- rubyforge_project:
146
+ rubyforge_project:
131
147
  rubygems_version: 2.5.1
132
- signing_key:
148
+ signing_key:
133
149
  specification_version: 4
134
150
  summary: CLI interface for Holistics
135
151
  test_files: []