globus_client 0.15.0 → 0.17.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: e189003b0a3f0592abd4fb7fabb006a3367f3cd330d83d7e46da2c2993bbbc21
4
- data.tar.gz: 36c6ff9a70ddcfea7be6e1ca044b110adb536aa911adbb1626f5086737342d88
3
+ metadata.gz: e08e97fbfd4a9b84d55f71a12289777a097f650de25717e9823e6bc8654d2237
4
+ data.tar.gz: ca58e7a6b52206fa2bef9a57f65fb3481ceac9036d07ff3779f9a23e7fbd4b7a
5
5
  SHA512:
6
- metadata.gz: 02cd08266cd52d2a3dd86ded97c8ce0085832fb446223375ab69164ed087187611e184e7cb4555208a0fb30b477e6c8b0e212041073cce2a3c328ddf6412e0c3
7
- data.tar.gz: 1d54da5c74f41e1a98ecdf0296ee948e14a9e569ed1f58a20f52c96347b1b215a4121050cef2e9c7f3d25d525a5b061e9cfe79cc8517efb1ff896cb517226962
6
+ metadata.gz: fe82ef0a3bf4bf62ba8ea77d5d504915be2ccb860c28afdd7b2fcfab7231df1df205390d712b7ac83ff21346bd6a28c29c00672fa0bc80105a2a57c82e0bb697
7
+ data.tar.gz: d26b68220d051ab56d04ed21459a29c64b62fe24aa8012760ae80e0e02d8afd28de764248a7ad69e49292683262ecdc6ce268dbd9244e6bd2b48ab5628a6ed90
data/.rubocop.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
- require:
3
+ plugins:
4
4
  - rubocop-performance
5
5
  - rubocop-rspec
6
6
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- globus_client (0.15.0)
4
+ globus_client (0.17.0)
5
5
  activesupport (>= 4.2)
6
6
  faraday
7
7
  faraday-retry
@@ -10,7 +10,7 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (8.0.1)
13
+ activesupport (8.0.2)
14
14
  base64
15
15
  benchmark (>= 0.3)
16
16
  bigdecimal
@@ -25,76 +25,82 @@ GEM
25
25
  uri (>= 0.13.1)
26
26
  addressable (2.8.7)
27
27
  public_suffix (>= 2.0.2, < 7.0)
28
- ast (2.4.2)
29
- base64 (0.2.0)
30
- benchmark (0.4.0)
31
- bigdecimal (3.1.9)
32
- byebug (11.1.3)
28
+ ast (2.4.3)
29
+ base64 (0.3.0)
30
+ benchmark (0.4.1)
31
+ bigdecimal (3.2.1)
32
+ byebug (12.0.0)
33
33
  concurrent-ruby (1.3.5)
34
- connection_pool (2.5.0)
34
+ connection_pool (2.5.3)
35
35
  crack (1.0.0)
36
36
  bigdecimal
37
37
  rexml
38
- diff-lcs (1.5.1)
38
+ diff-lcs (1.6.2)
39
39
  docile (1.4.1)
40
- drb (2.2.1)
41
- faraday (2.12.2)
40
+ drb (2.2.3)
41
+ faraday (2.13.1)
42
42
  faraday-net_http (>= 2.0, < 3.5)
43
43
  json
44
44
  logger
45
45
  faraday-net_http (3.4.0)
46
46
  net-http (>= 0.5.0)
47
- faraday-retry (2.2.1)
47
+ faraday-retry (2.3.1)
48
48
  faraday (~> 2.0)
49
- hashdiff (1.1.2)
49
+ hashdiff (1.2.0)
50
50
  i18n (1.14.7)
51
51
  concurrent-ruby (~> 1.0)
52
- json (2.9.1)
53
- language_server-protocol (3.17.0.4)
54
- logger (1.6.6)
55
- minitest (5.25.4)
52
+ json (2.12.2)
53
+ language_server-protocol (3.17.0.5)
54
+ lint_roller (1.1.0)
55
+ logger (1.7.0)
56
+ minitest (5.25.5)
56
57
  net-http (0.6.0)
57
58
  uri
58
- parallel (1.26.3)
59
- parser (3.3.7.1)
59
+ parallel (1.27.0)
60
+ parser (3.3.8.0)
60
61
  ast (~> 2.4.1)
61
62
  racc
62
- public_suffix (6.0.1)
63
+ prism (1.4.0)
64
+ public_suffix (6.0.2)
63
65
  racc (1.8.1)
64
66
  rainbow (3.1.1)
65
- rake (13.2.1)
67
+ rake (13.3.0)
66
68
  regexp_parser (2.10.0)
67
- rexml (3.4.0)
68
- rspec (3.13.0)
69
+ rexml (3.4.1)
70
+ rspec (3.13.1)
69
71
  rspec-core (~> 3.13.0)
70
72
  rspec-expectations (~> 3.13.0)
71
73
  rspec-mocks (~> 3.13.0)
72
- rspec-core (3.13.3)
74
+ rspec-core (3.13.4)
73
75
  rspec-support (~> 3.13.0)
74
- rspec-expectations (3.13.3)
76
+ rspec-expectations (3.13.5)
75
77
  diff-lcs (>= 1.2.0, < 2.0)
76
78
  rspec-support (~> 3.13.0)
77
- rspec-mocks (3.13.2)
79
+ rspec-mocks (3.13.5)
78
80
  diff-lcs (>= 1.2.0, < 2.0)
79
81
  rspec-support (~> 3.13.0)
80
- rspec-support (3.13.2)
81
- rubocop (1.71.2)
82
+ rspec-support (3.13.4)
83
+ rubocop (1.75.8)
82
84
  json (~> 2.3)
83
- language_server-protocol (>= 3.17.0)
85
+ language_server-protocol (~> 3.17.0.2)
86
+ lint_roller (~> 1.1.0)
84
87
  parallel (~> 1.10)
85
88
  parser (>= 3.3.0.2)
86
89
  rainbow (>= 2.2.2, < 4.0)
87
90
  regexp_parser (>= 2.9.3, < 3.0)
88
- rubocop-ast (>= 1.38.0, < 2.0)
91
+ rubocop-ast (>= 1.44.0, < 2.0)
89
92
  ruby-progressbar (~> 1.7)
90
93
  unicode-display_width (>= 2.4.0, < 4.0)
91
- rubocop-ast (1.38.0)
92
- parser (>= 3.3.1.0)
93
- rubocop-performance (1.23.1)
94
- rubocop (>= 1.48.1, < 2.0)
95
- rubocop-ast (>= 1.31.1, < 2.0)
96
- rubocop-rspec (3.4.0)
97
- rubocop (~> 1.61)
94
+ rubocop-ast (1.44.1)
95
+ parser (>= 3.3.7.2)
96
+ prism (~> 1.4)
97
+ rubocop-performance (1.25.0)
98
+ lint_roller (~> 1.1)
99
+ rubocop (>= 1.75.0, < 2.0)
100
+ rubocop-ast (>= 1.38.0, < 2.0)
101
+ rubocop-rspec (3.6.0)
102
+ lint_roller (~> 1.1)
103
+ rubocop (~> 1.72, >= 1.72.1)
98
104
  ruby-progressbar (1.13.0)
99
105
  securerandom (0.4.1)
100
106
  simplecov (0.22.0)
@@ -108,14 +114,15 @@ GEM
108
114
  unicode-display_width (3.1.4)
109
115
  unicode-emoji (~> 4.0, >= 4.0.4)
110
116
  unicode-emoji (4.0.4)
111
- uri (1.0.2)
112
- webmock (3.25.0)
117
+ uri (1.0.3)
118
+ webmock (3.25.1)
113
119
  addressable (>= 2.8.0)
114
120
  crack (>= 0.3.2)
115
121
  hashdiff (>= 0.4.0, < 2.0.0)
116
- zeitwerk (2.7.1)
122
+ zeitwerk (2.7.3)
117
123
 
118
124
  PLATFORMS
125
+ arm64-darwin-23
119
126
  x86_64-darwin-19
120
127
  x86_64-darwin-20
121
128
  x86_64-darwin-21
@@ -133,4 +140,4 @@ DEPENDENCIES
133
140
  webmock
134
141
 
135
142
  BUNDLED WITH
136
- 2.4.13
143
+ 2.6.9
@@ -53,7 +53,7 @@ class GlobusClient
53
53
 
54
54
  # Delete the access rule https://docs.globus.org/api/transfer/acl/#delete_access_rule
55
55
  def delete_access_rule
56
- raise(StandardError, "Access rule not found for #{path}") unless access_rule_id
56
+ raise GlobusClient::AccessRuleNotFound, "Access rule not found for #{path}" unless access_rule_id
57
57
 
58
58
  GlobusClient.instance.delete(
59
59
  base_url: GlobusClient.config.transfer_url,
@@ -61,6 +61,28 @@ class GlobusClient
61
61
  )
62
62
  end
63
63
 
64
+ # Renames a directory https://docs.globus.org/api/transfer/file_operations/#rename
65
+ def rename(new_path:)
66
+ GlobusClient.instance.post(
67
+ base_url: GlobusClient.config.transfer_url,
68
+ path: "#{transfer_path}/rename",
69
+ body: { DATA_TYPE: 'rename', old_path: path, new_path: }
70
+ )
71
+ end
72
+
73
+ # @returns true if the file / directory exists at the path
74
+ # See https://docs.globus.org/api/transfer/file_operations/#stat
75
+ def exists?
76
+ GlobusClient.instance.get(
77
+ base_url: GlobusClient.config.transfer_url,
78
+ path: "#{transfer_path}/stat",
79
+ params: { path: }
80
+ )
81
+ true
82
+ rescue GlobusClient::ResourceNotFound
83
+ false
84
+ end
85
+
64
86
  private
65
87
 
66
88
  attr_reader :path, :user_id, :notify_email
@@ -146,7 +168,7 @@ class GlobusClient
146
168
  end
147
169
 
148
170
  def update_access_request(permissions:)
149
- raise(StandardError, "Access rule not found for #{path}") unless access_rule_id
171
+ raise GlobusClient::AccessRuleNotFound, "Access rule not found for #{path}" unless access_rule_id
150
172
 
151
173
  GlobusClient.instance.put(
152
174
  base_url: GlobusClient.config.transfer_url,
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GlobusClient
4
+ # The namespace for endpoint management API operations
5
+ class EndpointManager
6
+ IN_PROGRESS_STATUSES = %w[ACTIVE INACTIVE].freeze
7
+
8
+ # List tasks for the configured transfer endpoint
9
+ # https://docs.globus.org/api/transfer/advanced_collection_management/#get_tasks
10
+ # Note that this method does not support pagination, as there are unlikely to be many tasks.
11
+ # Also note that if destination_path is provided, only transfer tasks will be returned.
12
+ # @param owner_id [String] the Globus user ID (a UUID, not email address)
13
+ # @param status [Array] the status of the tasks to filter on. Values are ACTIVE, INACTIVE, SUCCEEDED, or FAILED.
14
+ # @param destination_path [String] the destination path to filter tasks by
15
+ # @return [Array] list of task documents
16
+ def task_list(owner_id: nil, status: [], destination_path: nil)
17
+ tasks = GlobusClient.instance.get(
18
+ base_url: GlobusClient.config.transfer_url,
19
+ path: '/v0.10/endpoint_manager/task_list',
20
+ params: task_list_params(owner_id:, status:)
21
+ )['DATA']
22
+ return tasks unless destination_path
23
+
24
+ destination_base_path = destination_path.delete_suffix('/') << '/'
25
+ tasks.select { |task| task['destination_base_path']&.start_with?(destination_base_path) }
26
+ end
27
+
28
+ # @param owner_id [String] the Globus user ID (a UUID, not email address)
29
+ # @param destination_path [String] the destination path to filter tasks by
30
+ # @return [boolean] true if there are tasks in progress
31
+ def tasks_in_progress?(owner_id: nil, destination_path: nil)
32
+ task_list(owner_id:, destination_path:, status: IN_PROGRESS_STATUSES).present?
33
+ end
34
+
35
+ private
36
+
37
+ def task_list_params(owner_id:, status:)
38
+ {
39
+ filter_endpoint: GlobusClient.config.transfer_endpoint_id,
40
+ filter_owner_id: owner_id,
41
+ filter_status: Array(status).join(',').presence
42
+ }.compact
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GlobusClient
4
+ # Holds all of the client's custom exception classes
5
+ module Errors
6
+ # Error raised when the Globus Auth or Transfer API returns a 400 error
7
+ class BadRequestError < StandardError; end
8
+
9
+ # Error raised by the Globus Auth API returns a 401 Unauthorized
10
+ class UnauthorizedError < StandardError; end
11
+
12
+ # Error raised when the Globus Auth or Transfer API returns a 403 Forbidden
13
+ class ForbiddenError < StandardError; end
14
+
15
+ # Error raised when the Globus Auth or Transfer API returns a 404 NotFound
16
+ class ResourceNotFound < StandardError; end
17
+
18
+ # Error raised when a consumer acts upon an access rule that was not found
19
+ class AccessRuleNotFound < StandardError; end
20
+
21
+ # Error raised when response has an unexpected error (e.g., an HTTP 500)
22
+ class InternalServerError < StandardError; end
23
+
24
+ # Error raised when the Globus Transfer API returns a 502 Bad Gateway
25
+ class EndpointError < StandardError; end
26
+
27
+ # Error raised when the remote server returns a 503 Bad Gateway
28
+ class ServiceUnavailable < StandardError; end
29
+ end
30
+ end
@@ -3,24 +3,6 @@
3
3
  class GlobusClient
4
4
  # Handles unexpected responses when communicating with Globus
5
5
  class UnexpectedResponse
6
- # Error raised when the Globus Auth or Transfer API returns a 400 error
7
- class BadRequestError < StandardError; end
8
-
9
- # Error raised by the Globus Auth API returns a 401 Unauthorized
10
- class UnauthorizedError < StandardError; end
11
-
12
- # Error raised when the Globus Auth or Transfer API returns a 403 Forbidden
13
- class ForbiddenError < StandardError; end
14
-
15
- # Error raised when the Globus Auth or Transfer API returns a 404 NotFound
16
- class ResourceNotFound < StandardError; end
17
-
18
- # Error raised when the Globus Transfer API returns a 502 Bad Gateway
19
- class EndpointError < StandardError; end
20
-
21
- # Error raised when the remote server returns a 503 Bad Gateway
22
- class ServiceUnavailable < StandardError; end
23
-
24
6
  # @param [Faraday::Response] response
25
7
  # https://docs.globus.org/api/transfer/file_operations/#common_errors
26
8
  # https://docs.globus.org/api/transfer/file_operations/#errors
@@ -29,19 +11,19 @@ class GlobusClient
29
11
  def self.call(response)
30
12
  case response.status
31
13
  when 400
32
- raise BadRequestError, "Invalid path or another error with the request: #{response.body}"
14
+ raise GlobusClient::BadRequestError, "Invalid path or another error with the request: #{response.body}"
33
15
  when 401
34
- raise UnauthorizedError, "There was a problem with the access token: #{response.body} "
16
+ raise GlobusClient::UnauthorizedError, "There was a problem with the access token: #{response.body} "
35
17
  when 403
36
- raise ForbiddenError, "The operation requires privileges which the client does not have: #{response.body}"
18
+ raise GlobusClient::ForbiddenError, "The operation requires privileges which the client does not have: #{response.body}"
37
19
  when 404
38
- raise ResourceNotFound, "Endpoint ID not found or resource does not exist: #{response.body}"
20
+ raise GlobusClient::ResourceNotFound, "Endpoint ID not found or resource does not exist: #{response.body}"
39
21
  when 502
40
- raise EndpointError, "Other error with endpoint: #{response.status} #{response.body}."
22
+ raise GlobusClient::EndpointError, "Other error with endpoint: #{response.status} #{response.body}."
41
23
  when 503
42
- raise ServiceUnavailable, 'The service is down for maintenance.'
24
+ raise GlobusClient::ServiceUnavailable, 'The service is down for maintenance.'
43
25
  else
44
- raise StandardError, "Unexpected response: #{response.status} #{response.body}."
26
+ raise GlobusClient::InternalServerError, "Unexpected response: #{response.status} #{response.body}."
45
27
  end
46
28
  end
47
29
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class GlobusClient
4
- VERSION = '0.15.0'
4
+ VERSION = '0.17.0'
5
5
  end
data/lib/globus_client.rb CHANGED
@@ -12,6 +12,7 @@ Zeitwerk::Loader.for_gem.setup
12
12
 
13
13
  # Client for interacting with the Globus API
14
14
  class GlobusClient # rubocop:disable Metrics/ClassLength
15
+ include Errors
15
16
  include Singleton
16
17
 
17
18
  class << self
@@ -48,8 +49,9 @@ class GlobusClient # rubocop:disable Metrics/ClassLength
48
49
  end
49
50
  # rubocop:enable Metrics/ParameterLists
50
51
 
51
- delegate :config, :disallow_writes, :delete_access_rule, :file_count, :list_files, :mkdir, :total_size,
52
- :user_valid?, :get_filenames, :has_files?, :delete, :get, :post, :put, to: :instance
52
+ delegate :config, :disallow_writes, :allow_writes, :delete_access_rule, :file_count, :list_files, :mkdir, :rename, :total_size,
53
+ :user_valid?, :get_filenames, :has_files?, :exists?, :task_list, :tasks_in_progress?,
54
+ :delete, :get, :post, :put, to: :instance
53
55
 
54
56
  def default_transfer_url
55
57
  'https://transfer.api.globusonline.org'
@@ -152,12 +154,24 @@ class GlobusClient # rubocop:disable Metrics/ClassLength
152
154
  .disallow_writes
153
155
  end
154
156
 
157
+ def allow_writes(...)
158
+ Endpoint
159
+ .new(...)
160
+ .allow_writes
161
+ end
162
+
155
163
  def delete_access_rule(...)
156
164
  Endpoint
157
165
  .new(...)
158
166
  .delete_access_rule
159
167
  end
160
168
 
169
+ def rename(new_path:, **args)
170
+ Endpoint
171
+ .new(**args)
172
+ .rename(new_path:)
173
+ end
174
+
161
175
  # NOTE: Can't use the `...` (argument forwarding) operator here because we
162
176
  # want to route the keyword args to `Endpoint#new` and the block arg to
163
177
  # `Endpoint#list_files`
@@ -191,12 +205,30 @@ class GlobusClient # rubocop:disable Metrics/ClassLength
191
205
  .has_files?
192
206
  end
193
207
 
208
+ def exists?(...)
209
+ Endpoint
210
+ .new(...)
211
+ .exists?
212
+ end
213
+
194
214
  def user_valid?(...)
195
215
  Identity
196
216
  .new
197
217
  .valid?(...)
198
218
  end
199
219
 
220
+ def task_list(...)
221
+ EndpointManager
222
+ .new
223
+ .task_list(...)
224
+ end
225
+
226
+ def tasks_in_progress?(...)
227
+ EndpointManager
228
+ .new
229
+ .tasks_in_progress?(...)
230
+ end
231
+
200
232
  private
201
233
 
202
234
  Config = Struct.new(:client_id, :auth_url, :client_secret, :transfer_endpoint_id, :transfer_url, :uploads_directory, :token, keyword_init: true)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: globus_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Collier
@@ -9,7 +9,7 @@ authors:
9
9
  - Mike Giarlo
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2025-02-18 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -89,6 +89,8 @@ files:
89
89
  - lib/globus_client.rb
90
90
  - lib/globus_client/authenticator.rb
91
91
  - lib/globus_client/endpoint.rb
92
+ - lib/globus_client/endpoint_manager.rb
93
+ - lib/globus_client/errors.rb
92
94
  - lib/globus_client/identity.rb
93
95
  - lib/globus_client/unexpected_response.rb
94
96
  - lib/globus_client/version.rb
@@ -113,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
115
  - !ruby/object:Gem::Version
114
116
  version: '0'
115
117
  requirements: []
116
- rubygems_version: 3.6.3
118
+ rubygems_version: 3.6.9
117
119
  specification_version: 4
118
120
  summary: Interface for interacting with the Globus API.
119
121
  test_files: []