big_shift 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8dc1bd209d69121511dbf0b3efffceb8c38c45e9
4
+ data.tar.gz: f05ef9279b88a0e8d630005a7ee541bd53e57d09
5
+ SHA512:
6
+ metadata.gz: b132ceb754777e66bd3a824a230014a3f0eae8047f506d73796549b904adb15f700ab474a2f181bc08cc436c9da2f8d67920c28a67576716d7b69014671f37df
7
+ data.tar.gz: 943089b7da61fd19178b5273e7fe71f73eccd6cef09301a880ad5a063a47b3ab890d5094c49af93455b6331ec7c4a9c8e80c7dc1366b3e73c70f8fb3888a8cf3
data/README.md ADDED
@@ -0,0 +1,127 @@
1
+ BigShift
2
+ ======
3
+
4
+ BigShift uploads your data to BigQuery.
5
+
6
+
7
+ Setup
8
+ -----
9
+
10
+ $ bundle install
11
+
12
+
13
+ Run Specs
14
+ ---------
15
+
16
+ $ bundle exec rake
17
+
18
+ ### Regenerating VCR Cassettes
19
+
20
+ #### BigQuery Workspace
21
+
22
+ A BigQuery dataset is necessary to regenerate cassettes.
23
+ The dataset may be named anything,
24
+ but a table named `vcr_insert_table` is required
25
+ and must have a field named `field` of type `string`.
26
+
27
+ If the cassettes have been regenerated against an existing dataset,
28
+ the table named `vcr_create_table` will need to be deleted
29
+ prior to generating vcr cassettes again.
30
+
31
+
32
+ #### Environment Variables
33
+
34
+ In order to regenerate vcr cassettes,
35
+ some envrionment variables are required
36
+ and should be added to a `.env` file in the root of the project:
37
+
38
+ ```
39
+ BIG_SHIFT_PROJECT_ID = [project-id]
40
+ BIG_SHIFT_DATASET_ID = [dataset-id]
41
+ BIG_SHIFT_REFRESH_TOKEN = [refresh-token]
42
+ BIG_SHIFT_GOOGLE_CLIENT_ID = [google-client-id]
43
+ BIG_SHIFT_GOOGLE_CLIENT_SECRET = [google-client-secret]
44
+ ```
45
+
46
+
47
+ #### Find AwesomenessTv Variables
48
+
49
+ ##### Project ID, Dataset ID
50
+
51
+ Look on the BigQuery dashboard or talk to a team member.
52
+
53
+
54
+ ##### Client ID and Client Secret
55
+
56
+ 1. Go to [the Google API Console][google-api-console].
57
+ 2. Log in as `awesomenesstv.dev@gmail.com` (see a team member for the password).
58
+ 3. Select the `Business Intelligence` project (if not already there).
59
+ 4. Click on `Credentials` on the left nav (under `APIs and auth`).
60
+ 5. Client ID and Client Secret are listed under `Client ID for web application`.
61
+
62
+
63
+ ##### Refresh Token (requires Client ID & Client Secret)
64
+
65
+ 1. Sign in to Google as `awesomenesstv.dev@gmail.com`.
66
+ 1. Go to [the OAuth playground][oauth-playground].
67
+ 2. Select the BigQuery APIs (`bigquery` and `bigquery.insertdata` scopes).
68
+ 3. Use the gear/options dropdown to set the Client ID and Client Secret.
69
+ 4. Click on `Authorize APIs`.
70
+ 5. Look for the `Refresh token` value that is generated.
71
+
72
+
73
+ Usage
74
+ -----
75
+
76
+ All environment variables listed in the section on regenerating vcr cassettes
77
+ must be set by any consumer of this gem.
78
+
79
+
80
+ Interface
81
+ ---------
82
+
83
+ All public endpoints are exposed in BigShift::Core.
84
+
85
+ Every response from the public API is wrapped in a `Response` object
86
+ that will always have the same interface regardless of request.
87
+ The `Response#data` attribute will be an object specific to the data requested.
88
+
89
+
90
+ ### create_table
91
+
92
+ This method requires only a schema to be specified:
93
+
94
+ ```
95
+ schema = BigShift::Schema.new('MyTable')
96
+ .add_field('field1', :string)
97
+ .add_field('field2', :integer)
98
+ .add_field('field3', :boolean)
99
+
100
+ BigShift.create_table schema
101
+ ```
102
+
103
+
104
+ ### insert_rows
105
+
106
+ This method requires a table name and an array of objects to insert.
107
+
108
+ All objects are expected to respond to `to_json`.
109
+
110
+ ```
111
+ rows = [{
112
+ :field1 => 'field1-value-1',
113
+ :field2 => 'field2-value-1',
114
+ }, {
115
+ :field1 => 'field1-value-2',
116
+ :field2 => 'field2-value-2',
117
+ }, {
118
+ :field1 => 'field1-value-3',
119
+ :field2 => 'field2-value-3',
120
+ }]
121
+
122
+ BigShift.insert_rows 'MyTable', rows
123
+ ```
124
+
125
+
126
+ [google-api-console]: https://code.google.com/apis/console
127
+ [oauth-playground]: https://developers.google.com/oauthplayground
@@ -0,0 +1,63 @@
1
+ module BigShift
2
+ class BaseCommand
3
+ class << self
4
+ private
5
+
6
+ def connection
7
+ Faraday.new(:url => base_url)
8
+ end
9
+
10
+ def post
11
+ connection.post url, request_body, headers
12
+ end
13
+
14
+ def headers
15
+ {
16
+ 'Authorization' => "Bearer #{access_token}",
17
+ 'Content-Type' => 'application/json',
18
+ }
19
+ end
20
+
21
+ def params
22
+ url_params.merge({
23
+ :key => access_token,
24
+ })
25
+ end
26
+
27
+ def request_body
28
+ body.to_json
29
+ end
30
+
31
+ def base_url
32
+ 'https://www.googleapis.com/bigquery/v2/projects/%s/datasets/%s' % [
33
+ project_id,
34
+ dataset_id,
35
+ ]
36
+ end
37
+
38
+ def url
39
+ connection.build_url endpoint, params
40
+ end
41
+
42
+ def url_params
43
+ {}
44
+ end
45
+
46
+ def body
47
+ {}
48
+ end
49
+
50
+ def project_id
51
+ ENV['BIG_SHIFT_PROJECT_ID']
52
+ end
53
+
54
+ def dataset_id
55
+ ENV['BIG_SHIFT_DATASET_ID']
56
+ end
57
+
58
+ def access_token
59
+ AccessTokenService.retrieve_token
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,13 @@
1
+ module BigShift
2
+ class BaseTableCommand < BaseCommand
3
+ class << self
4
+ attr_accessor :table_id
5
+
6
+ private
7
+
8
+ def base_url
9
+ "#{super}/tables/#{table_id}"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module BigShift
2
+ class CreateTableCommand < BaseCommand
3
+ class << self
4
+ def execute(schema)
5
+ @schema = schema
6
+ CreateTableResponse.new post
7
+ end
8
+
9
+ def endpoint
10
+ 'tables'
11
+ end
12
+
13
+ def body
14
+ {
15
+ 'tableReference' => {
16
+ 'projectId' => project_id,
17
+ 'datasetId' => dataset_id,
18
+ 'tableId' => @schema.table_name,
19
+ },
20
+
21
+ 'schema' => @schema,
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ module BigShift
2
+ class GetAccessTokenCommand < BaseCommand
3
+ class << self
4
+ def execute
5
+ GetAccessTokenResponse.new post
6
+ end
7
+
8
+ def headers
9
+ {
10
+ 'Content-Type' => 'application/json',
11
+ }
12
+ end
13
+
14
+ def params
15
+ {
16
+ :client_id => client_id,
17
+ :client_secret => client_secret,
18
+ :refresh_token => refresh_token,
19
+ :grant_type => 'refresh_token',
20
+ }
21
+ end
22
+
23
+ def endpoint
24
+ 'token'
25
+ end
26
+
27
+ private
28
+
29
+ def client_id
30
+ ENV['BIG_SHIFT_GOOGLE_CLIENT_ID']
31
+ end
32
+
33
+ def client_secret
34
+ ENV['BIG_SHIFT_GOOGLE_CLIENT_SECRET']
35
+ end
36
+
37
+ def refresh_token
38
+ ENV['BIG_SHIFT_REFRESH_TOKEN']
39
+ end
40
+
41
+ def base_url
42
+ 'https://www.googleapis.com/oauth2/v3'
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,27 @@
1
+ module BigShift
2
+ class InsertRowsCommand < BaseTableCommand
3
+ class << self
4
+ def execute(table_name, rows)
5
+ @rows = rows
6
+ self.table_id = table_name
7
+ InsertRowsResponse.new post
8
+ end
9
+
10
+ def endpoint
11
+ 'insertAll'
12
+ end
13
+
14
+ def body
15
+ { :rows => build_rows }
16
+ end
17
+
18
+ private
19
+
20
+ def build_rows
21
+ @rows.map do |row|
22
+ {:json => row}
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ module BigShift
2
+ module Core
3
+ extend self
4
+
5
+ def create_table(table_name)
6
+ CreateTableCommand.execute table_name
7
+ end
8
+
9
+ def insert_rows(table_name, rows)
10
+ InsertRowsCommand.execute table_name, rows
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module BigShift
2
+ class AccessToken
3
+ attr_accessor :access_token, :expires
4
+
5
+ def initialize(hash = {})
6
+ @access_token = hash['access_token']
7
+ @expires = hash['expires_in']
8
+ @created = Time.now
9
+ end
10
+
11
+ def expired?
12
+ Time.now - @created > (expires - 10)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module BigShift
2
+ class BaseModel
3
+ def to_json(json_state = nil)
4
+ as_json(json_state).to_json
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ module BigShift
2
+ class Schema < BaseModel
3
+ attr_reader :table_name
4
+
5
+ def initialize(table_name)
6
+ @table_name = table_name
7
+ @fields = []
8
+ end
9
+
10
+ def add_field(field_name, field_type)
11
+ @fields << TableField.new(field_name, field_type)
12
+ self
13
+ end
14
+
15
+ def as_json(json_state = nil)
16
+ {
17
+ 'fields' => @fields,
18
+ }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module BigShift
2
+ class TableField < BaseModel
3
+ def initialize(field_name, field_type)
4
+ @field_name = field_name
5
+ @field_type = field_type
6
+ end
7
+
8
+ def as_json(json_state = nil)
9
+ {
10
+ :name => @field_name,
11
+ :type => @field_type,
12
+ }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module BigShift
2
+ class CreateTableResponse < Reverb::Response
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module BigShift
2
+ class GetAccessTokenResponse < Reverb::Response
3
+ def on_success
4
+ self.data = AccessToken.new(body)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module BigShift
2
+ class InsertRowsResponse < Reverb::Response
3
+ def on_success
4
+ if body['insertErrors']
5
+ @success = false
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module BigShift
2
+ module AccessTokenService
3
+ extend self
4
+
5
+ def retrieve_token
6
+ if !defined?(@token) or @token.expired?
7
+ response = GetAccessTokenCommand.execute
8
+ @token = response.data
9
+ end
10
+
11
+ @token.access_token
12
+ end
13
+ end
14
+ end
data/lib/big_shift.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'json'
2
+
3
+ require 'faraday'
4
+ require 'reverb'
5
+
6
+ module BigShift
7
+ end
8
+
9
+ require_relative 'big_shift/models/base_model'
10
+ require_relative 'big_shift/models/access_token'
11
+ require_relative 'big_shift/models/table_field'
12
+ require_relative 'big_shift/models/schema'
13
+
14
+ require_relative 'big_shift/responses/get_access_token_response'
15
+ require_relative 'big_shift/responses/create_table_response'
16
+ require_relative 'big_shift/responses/insert_rows_response'
17
+
18
+ require_relative 'big_shift/commands/base_command'
19
+ require_relative 'big_shift/commands/base_table_command'
20
+ require_relative 'big_shift/commands/create_table_command'
21
+ require_relative 'big_shift/commands/get_access_token_command'
22
+ require_relative 'big_shift/commands/insert_rows_command'
23
+
24
+ require_relative 'big_shift/services/access_token_service'
25
+
26
+ require_relative 'big_shift/core'
27
+
28
+ module BigShift
29
+ extend Core
30
+ end