databricks 1.0.0 → 2.0.0

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
  SHA256:
3
- metadata.gz: c27151990dcc087e396f387f45f6909f54bb6eb8529b8835706ce84d3ac399ab
4
- data.tar.gz: 0ddfaf4cd06981894bddc1ff2ede2bf2372aa6d08521699458502cdf4b83f308
3
+ metadata.gz: 06a826e00c327ae1b293c0da9f57632ec9103e128f253fcf2f8ce1229a64074c
4
+ data.tar.gz: 6830f2c2fc4fe380b92856f28d827e8573ccfbb78f86280d1d11269ccf602fbb
5
5
  SHA512:
6
- metadata.gz: 747bf19db30cc24740b101aaacd14d22eeb7051995b7d1707917835a34fb90bc096304d2e11c18ea4c04c28049e5ead90961f1fcdb319642bbd54409feb580cf
7
- data.tar.gz: dae0b046280172f770df37ce37440d0311f5e65896fe35209e3d0e900c4961d1a8396d195b570dac122c23b373aeb0be364f9c94178d54da888fab20dd81a819
6
+ metadata.gz: 601a0e36f9fb7bc79c9d4f42ecf9f3ff32eb1a531ce9d706f38b6731e3ef373da32b7cd2c404414e4747f1d2ec2b9833e0aa913ac8e1dac84f7e72fb8113d151
7
+ data.tar.gz: 7ef05a8b17ff9167e346cd129fbda117fd75289e9ac77d1b0679340b56bddcfec17d66c437a8c2fc95fa8278ee653a439936b408d1b7dacfde41aa69c85f8a36
data/lib/databricks.rb CHANGED
@@ -1,5 +1,6 @@
1
- require 'databricks/domains/root'
1
+ require 'databricks/connector'
2
2
  require 'databricks/resource'
3
+ require 'databricks/resources/root'
3
4
 
4
5
  module Databricks
5
6
 
@@ -9,9 +10,9 @@ module Databricks
9
10
  # * *host* (String): Host to connect to
10
11
  # * *token* (String): Token to be used in th API
11
12
  # Result::
12
- # * Domains::Root: The root domain of the API
13
+ # * Resources::Root: The root resource of the API
13
14
  def self.api(host, token)
14
- Domains::Root.new(Resource.new(host, token))
15
+ Resources::Root.new(Connector.new(host, token))
15
16
  end
16
17
 
17
18
  end
@@ -0,0 +1,79 @@
1
+ require 'json'
2
+ require 'rest-client'
3
+
4
+ module Databricks
5
+
6
+ # Underlying connector making API calls
7
+ class Connector
8
+
9
+ # Constructor
10
+ #
11
+ # Parameters::
12
+ # * *host* (String): Host to connect to
13
+ # * *token* (String): Token to be used in th API
14
+ def initialize(host, token)
15
+ @host = host
16
+ @token = token
17
+ end
18
+
19
+ # Issue a GET request to the API with JSON payload
20
+ #
21
+ # Parameters::
22
+ # * *api_path* (String): API path to query
23
+ # * *json_payload* (Object): JSON payload to include in the query [default = {}]
24
+ # Result::
25
+ # * Object: JSON result
26
+ def get_json(api_path, json_payload = {})
27
+ JSON.parse(
28
+ RestClient::Request.execute(
29
+ method: :get,
30
+ url: "#{@host}/api/2.0/#{api_path}",
31
+ payload: json_payload.to_json,
32
+ headers: {
33
+ Authorization: "Bearer #{@token}",
34
+ 'Content-Type': 'application/json'
35
+ }
36
+ ).body
37
+ )
38
+ end
39
+
40
+ # Issue a POST request to the API with JSON payload
41
+ #
42
+ # Parameters::
43
+ # * *api_path* (String): API path to query
44
+ # * *json_payload* (Object): JSON payload to include in the query [default = {}]
45
+ # Result::
46
+ # * Object: JSON result
47
+ def post_json(api_path, json_payload = {})
48
+ JSON.parse(
49
+ RestClient::Request.execute(
50
+ method: :post,
51
+ url: "#{@host}/api/2.0/#{api_path}",
52
+ payload: json_payload.to_json,
53
+ headers: {
54
+ Authorization: "Bearer #{@token}",
55
+ 'Content-Type': 'application/json'
56
+ }
57
+ ).body
58
+ )
59
+ end
60
+
61
+ # Issue a POST request to the API with multipart form data payload
62
+ #
63
+ # Parameters::
64
+ # * *api_path* (String): API path to query
65
+ # * *form_payload* (Hash): Form payload to include in the query [default = {}]
66
+ def post(api_path, form_payload = {})
67
+ RestClient::Request.execute(
68
+ method: :post,
69
+ url: "#{@host}/api/2.0/#{api_path}",
70
+ payload: form_payload.merge(multipart: true),
71
+ headers: {
72
+ Authorization: "Bearer #{@token}"
73
+ }
74
+ )
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -1,77 +1,95 @@
1
- require 'json'
2
- require 'rest-client'
1
+ require 'forwardable'
3
2
 
4
3
  module Databricks
5
4
 
6
- # Underlying resource making API calls
5
+ # Encapsulate a resource identified in the API.
6
+ # A resource can have some properties, directly accessible, and also gives access to eventual sub-resources to get a hierarchical organization of the API.
7
7
  class Resource
8
8
 
9
+ extend Forwardable
10
+
11
+ # Delegate the API low-level methods to the @connector object
12
+ def_delegators :@connector, *%i[
13
+ get_json
14
+ post
15
+ post_json
16
+ ]
17
+
18
+ # Declare sub-resources accessors.
19
+ # This will make sure this resource has methods named after the sub-resources identifiers.
20
+ #
21
+ # Parameters::
22
+ # * *resource_names* (Array<Symbol>): Resource names to instantiate
23
+ def self.sub_resources(*resource_names)
24
+ resource_names.flatten.each do |resource_name|
25
+ self.define_method(resource_name) do
26
+ sub_resource(resource_name)
27
+ end
28
+ end
29
+ end
30
+
9
31
  # Constructor
10
32
  #
11
33
  # Parameters::
12
- # * *host* (String): Host to connect to
13
- # * *token* (String): Token to be used in th API
14
- def initialize(host, token)
15
- @host = host
16
- @token = token
34
+ # * *connector* (Connector): Connector handling API calls
35
+ def initialize(connector)
36
+ @connector = connector
37
+ # Keep a map of sub-resources instantiated, per resource name.
38
+ # Hash< Symbol, Resource >
39
+ @sub_resources = {}
40
+ # Properties linked to this resource
41
+ # Hash< Symbol, Object >
42
+ @properties = {}
17
43
  end
18
44
 
19
- # Issue a GET request to the API with JSON payload
45
+ # Add/replace properties for this resource
20
46
  #
21
47
  # Parameters::
22
- # * *api_path* (String): API path to query
23
- # * *json_payload* (Object): JSON payload to include in the query [default = {}]
48
+ # * *properties* (Hash<Symbol,Object>): Properties for this resource
49
+ def add_properties(properties)
50
+ # Define getters for properties
51
+ (properties.keys - @properties.keys).each do |property_name|
52
+ if self.respond_to?(property_name)
53
+ raise "Can't define a property named #{property_name} - It's already used."
54
+ else
55
+ define_singleton_method(property_name) { @properties[property_name] }
56
+ end
57
+ end
58
+ @properties.merge!(properties)
59
+ end
60
+
61
+ # Return a simple string representation of this resource
62
+ #
24
63
  # Result::
25
- # * Object: JSON result
26
- def get_json(api_path, json_payload = {})
27
- JSON.parse(
28
- RestClient::Request.execute(
29
- method: :get,
30
- url: "#{@host}/api/2.0/#{api_path}",
31
- payload: json_payload.to_json,
32
- headers: {
33
- Authorization: "Bearer #{@token}",
34
- 'Content-Type': 'application/json'
35
- }
36
- ).body
37
- )
64
+ # * String: Default representation
65
+ def inspect
66
+ "#<#{self.class.name.split('::').last} - #{@properties}>"
38
67
  end
39
68
 
40
- # Issue a POST request to the API with JSON payload
69
+ # Instantiate a sub-resource.
70
+ # Keep a cache of it.
41
71
  #
42
72
  # Parameters::
43
- # * *api_path* (String): API path to query
44
- # * *json_payload* (Object): JSON payload to include in the query [default = {}]
73
+ # * *resource_name* (Symbol): Resource name.
45
74
  # Result::
46
- # * Object: JSON result
47
- def post_json(api_path, json_payload = {})
48
- JSON.parse(
49
- RestClient::Request.execute(
50
- method: :post,
51
- url: "#{@host}/api/2.0/#{api_path}",
52
- payload: json_payload.to_json,
53
- headers: {
54
- Authorization: "Bearer #{@token}",
55
- 'Content-Type': 'application/json'
56
- }
57
- ).body
58
- )
75
+ # * Resource: Corresponding sub-resource
76
+ def sub_resource(resource_name)
77
+ @sub_resources[resource_name] = new_resource(resource_name) unless @sub_resources.key?(resource_name)
78
+ @sub_resources[resource_name]
59
79
  end
60
80
 
61
- # Issue a POST request to the API with multipart form data payload
81
+ # Instantiate a new resource, with optional properties
62
82
  #
63
83
  # Parameters::
64
- # * *api_path* (String): API path to query
65
- # * *form_payload* (Hash): Form payload to include in the query [default = {}]
66
- def post(api_path, form_payload = {})
67
- RestClient::Request.execute(
68
- method: :post,
69
- url: "#{@host}/api/2.0/#{api_path}",
70
- payload: form_payload.merge(multipart: true),
71
- headers: {
72
- Authorization: "Bearer #{@token}"
73
- }
74
- )
84
+ # * *resource_name* (Symbol): The resource's name.
85
+ # * *properties* (Hash<Symbol or String,Object>): This resource's initial properties [default = {}]
86
+ # Result::
87
+ # * Resource: The corresponding resource
88
+ def new_resource(resource_name, properties = {})
89
+ require "#{__dir__}/resources/#{resource_name}.rb"
90
+ resource = Resources.const_get(resource_name.to_s.split('_').collect(&:capitalize).join.to_sym).new(@connector)
91
+ resource.add_properties(properties.transform_keys(&:to_sym))
92
+ resource
75
93
  end
76
94
 
77
95
  end
@@ -0,0 +1,27 @@
1
+ module Databricks
2
+
3
+ module Resources
4
+
5
+ class Cluster < Resource
6
+
7
+ # Edit properties of this cluster.
8
+ #
9
+ # Parameters::
10
+ # * *properties* (Hash<Symbol,Object>): Properties of this cluster
11
+ def edit(**properties)
12
+ # Make sure we don't change its ID
13
+ properties[:cluster_id] = cluster_id
14
+ post_json('clusters/edit', properties)
15
+ add_properties(properties)
16
+ end
17
+
18
+ # Delete a cluster
19
+ def delete
20
+ post_json('clusters/delete', { cluster_id: cluster_id })
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,39 @@
1
+ module Databricks
2
+
3
+ module Resources
4
+
5
+ # Provide the Clusters API
6
+ # cf. https://docs.databricks.com/dev-tools/api/latest/clusters.html
7
+ class Clusters < Resource
8
+
9
+ # List clusters
10
+ #
11
+ # Result::
12
+ # * Array<Hash>: List of clusters information
13
+ def list
14
+ (get_json('clusters/list')['clusters'] || []).map { |properties| new_resource(:cluster, properties) }
15
+ end
16
+
17
+ # Get a cluster based on its cluster_id
18
+ #
19
+ # Result::
20
+ # * Cluster: The cluster
21
+ def get(cluster_id)
22
+ new_resource(:cluster, get_json('clusters/get', { cluster_id: cluster_id }))
23
+ end
24
+
25
+ # Create a new cluster.
26
+ #
27
+ # Parameters::
28
+ # * *properties* (Hash<Symbol,Object>): Properties to create the cluster
29
+ def create(**properties)
30
+ cluster = new_resource(:cluster, post_json('clusters/create', properties))
31
+ cluster.add_properties(properties)
32
+ cluster
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -1,12 +1,10 @@
1
- require 'databricks/domain'
2
-
3
1
  module Databricks
4
2
 
5
- module Domains
3
+ module Resources
6
4
 
7
5
  # Provide the DBFS API
8
6
  # cf. https://docs.databricks.com/dev-tools/api/latest/dbfs.html
9
- class Dbfs < Domain
7
+ class Dbfs < Resource
10
8
 
11
9
  # List a path
12
10
  #
@@ -15,12 +13,7 @@ module Databricks
15
13
  # Result::
16
14
  # * Array<String>: List of DBFS paths
17
15
  def list(path)
18
- @resource.get_json(
19
- 'dbfs/list',
20
- {
21
- path: path
22
- }
23
- )['files'].map { |file_info| file_info['path'] }
16
+ (get_json('dbfs/list', { path: path })['files'] || []).map { |properties| new_resource(:file, properties) }
24
17
  end
25
18
 
26
19
  # Put a new file
@@ -29,16 +22,31 @@ module Databricks
29
22
  # * *path* (String): Path to the file to create
30
23
  # * *local_file* (String): Path to the local file to put
31
24
  def put(path, local_file)
32
- @resource.post(
25
+ post(
33
26
  'dbfs/put',
34
27
  {
35
28
  path: path,
36
- contents: File.new(local_file, 'rb'),
29
+ contents: ::File.new(local_file, 'rb'),
37
30
  overwrite: true
38
31
  }
39
32
  )
40
33
  end
41
34
 
35
+ # Delete a path
36
+ #
37
+ # Parameters::
38
+ # * *path* (String): Path to delete
39
+ # * *recursive* (Boolean): Do we delete recursively? [default: false]
40
+ def delete(path, recursive: false)
41
+ post_json(
42
+ 'dbfs/delete',
43
+ {
44
+ path: path,
45
+ recursive: recursive
46
+ }
47
+ )
48
+ end
49
+
42
50
  end
43
51
 
44
52
  end
@@ -0,0 +1,11 @@
1
+ module Databricks
2
+
3
+ module Resources
4
+
5
+ class File < Resource
6
+
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ module Databricks
2
+
3
+ module Resources
4
+
5
+ class Job < Resource
6
+
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,31 @@
1
+ module Databricks
2
+
3
+ module Resources
4
+
5
+ # Provide the Jobs API
6
+ # cf. https://docs.databricks.com/dev-tools/api/latest/jobs.html
7
+ class Jobs < Resource
8
+
9
+ # List jobs
10
+ #
11
+ # Result::
12
+ # * Array<Hash>: List of jobs information
13
+ def list
14
+ (get_json('jobs/list')['jobs'] || []).map { |properties| new_resource(:job, properties) }
15
+ end
16
+
17
+ # Create a new job.
18
+ #
19
+ # Parameters::
20
+ # * *properties* (Hash<Symbol,Object>): Properties to create the job
21
+ def create(**properties)
22
+ job = new_resource(:job, post_json('jobs/create', properties))
23
+ job.add_properties(properties)
24
+ job
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -1,14 +1,15 @@
1
- require 'databricks/domain'
1
+ require 'databricks/resource'
2
2
 
3
3
  module Databricks
4
4
 
5
- module Domains
5
+ module Resources
6
6
 
7
7
  # API entry point
8
8
  # cf. https://docs.databricks.com/dev-tools/api/latest/index.html
9
- class Root < Domain
9
+ class Root < Resource
10
10
 
11
- sub_domains %i[
11
+ sub_resources %i[
12
+ clusters
12
13
  dbfs
13
14
  jobs
14
15
  ]
@@ -1,5 +1,5 @@
1
1
  module Databricks
2
2
 
3
- VERSION = '1.0.0'
3
+ VERSION = '2.0.0'
4
4
 
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: databricks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-20 00:00:00.000000000 Z
11
+ date: 2021-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -74,11 +74,15 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - lib/databricks.rb
77
- - lib/databricks/domain.rb
78
- - lib/databricks/domains/dbfs.rb
79
- - lib/databricks/domains/jobs.rb
80
- - lib/databricks/domains/root.rb
77
+ - lib/databricks/connector.rb
81
78
  - lib/databricks/resource.rb
79
+ - lib/databricks/resources/cluster.rb
80
+ - lib/databricks/resources/clusters.rb
81
+ - lib/databricks/resources/dbfs.rb
82
+ - lib/databricks/resources/file.rb
83
+ - lib/databricks/resources/job.rb
84
+ - lib/databricks/resources/jobs.rb
85
+ - lib/databricks/resources/root.rb
82
86
  - lib/databricks/version.rb
83
87
  homepage: https://github.com/Muriel-Salvan/databricks
84
88
  licenses:
@@ -1,47 +0,0 @@
1
- module Databricks
2
-
3
- # Encapsulate a part of the API for better organization
4
- class Domain
5
-
6
- # Declare sub-domain accessors in the current domain.
7
- # This will make sure the current domain has methods named after the sub-domain identifiers that will instantiate the corresponding domains at will.
8
- #
9
- # Parameters::
10
- # * *domains* (Array<Symbol>): Domains to instantiate
11
- def self.sub_domains(*domains)
12
- domains.flatten.each do |domain|
13
- self.define_method(domain) do
14
- sub_domain(domain)
15
- end
16
- end
17
- end
18
-
19
- # Instantiate a sub-domain.
20
- # Keep a cache of it.
21
- #
22
- # Parameters::
23
- # * *domain* (Symbol): Sub-domain identifier.
24
- # Result::
25
- # * Domain: Corresponding sub-domain
26
- def sub_domain(domain)
27
- unless @sub_domains.key?(domain)
28
- require "#{__dir__}/domains/#{domain}.rb"
29
- @sub_domains[domain] = Domains.const_get(domain.to_s.split('_').collect(&:capitalize).join.to_sym).new(@resource)
30
- end
31
- @sub_domains[domain]
32
- end
33
-
34
- # Constructor
35
- #
36
- # Parameters::
37
- # * *resource* (Resource): Resource handling API calls
38
- def initialize(resource)
39
- @resource = resource
40
- # Keep a map of sub-domains instantiated, per domain identifier.
41
- # Hash< Symbol, Domain >
42
- @sub_domains = {}
43
- end
44
-
45
- end
46
-
47
- end
@@ -1,31 +0,0 @@
1
- require 'databricks/domain'
2
-
3
- module Databricks
4
-
5
- module Domains
6
-
7
- # Provide the Jobs API
8
- # cf. https://docs.databricks.com/dev-tools/api/latest/jobs.html
9
- class Jobs < Domain
10
-
11
- # List a path
12
- #
13
- # Result::
14
- # * Array<Hash>: List of jobs information
15
- def list
16
- @resource.get_json('jobs/list')['jobs']
17
- end
18
-
19
- # Create a new job
20
- #
21
- # Parameters::
22
- # * *settings* (Hash<Symbol,Object>): Settings to create the job
23
- def create(**settings)
24
- @resource.post_json('jobs/create', settings)
25
- end
26
-
27
- end
28
-
29
- end
30
-
31
- end