databricks 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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