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 +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile.lock +48 -41
- data/lib/globus_client/endpoint.rb +24 -2
- data/lib/globus_client/endpoint_manager.rb +45 -0
- data/lib/globus_client/errors.rb +30 -0
- data/lib/globus_client/unexpected_response.rb +7 -25
- data/lib/globus_client/version.rb +1 -1
- data/lib/globus_client.rb +34 -2
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e08e97fbfd4a9b84d55f71a12289777a097f650de25717e9823e6bc8654d2237
|
4
|
+
data.tar.gz: ca58e7a6b52206fa2bef9a57f65fb3481ceac9036d07ff3779f9a23e7fbd4b7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe82ef0a3bf4bf62ba8ea77d5d504915be2ccb860c28afdd7b2fcfab7231df1df205390d712b7ac83ff21346bd6a28c29c00672fa0bc80105a2a57c82e0bb697
|
7
|
+
data.tar.gz: d26b68220d051ab56d04ed21459a29c64b62fe24aa8012760ae80e0e02d8afd28de764248a7ad69e49292683262ecdc6ce268dbd9244e6bd2b48ab5628a6ed90
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
globus_client (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.
|
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.
|
29
|
-
base64 (0.
|
30
|
-
benchmark (0.4.
|
31
|
-
bigdecimal (3.1
|
32
|
-
byebug (
|
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.
|
34
|
+
connection_pool (2.5.3)
|
35
35
|
crack (1.0.0)
|
36
36
|
bigdecimal
|
37
37
|
rexml
|
38
|
-
diff-lcs (1.
|
38
|
+
diff-lcs (1.6.2)
|
39
39
|
docile (1.4.1)
|
40
|
-
drb (2.2.
|
41
|
-
faraday (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.
|
47
|
+
faraday-retry (2.3.1)
|
48
48
|
faraday (~> 2.0)
|
49
|
-
hashdiff (1.
|
49
|
+
hashdiff (1.2.0)
|
50
50
|
i18n (1.14.7)
|
51
51
|
concurrent-ruby (~> 1.0)
|
52
|
-
json (2.
|
53
|
-
language_server-protocol (3.17.0.
|
54
|
-
|
55
|
-
|
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.
|
59
|
-
parser (3.3.
|
59
|
+
parallel (1.27.0)
|
60
|
+
parser (3.3.8.0)
|
60
61
|
ast (~> 2.4.1)
|
61
62
|
racc
|
62
|
-
|
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.
|
67
|
+
rake (13.3.0)
|
66
68
|
regexp_parser (2.10.0)
|
67
|
-
rexml (3.4.
|
68
|
-
rspec (3.13.
|
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.
|
74
|
+
rspec-core (3.13.4)
|
73
75
|
rspec-support (~> 3.13.0)
|
74
|
-
rspec-expectations (3.13.
|
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.
|
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.
|
81
|
-
rubocop (1.
|
82
|
+
rspec-support (3.13.4)
|
83
|
+
rubocop (1.75.8)
|
82
84
|
json (~> 2.3)
|
83
|
-
language_server-protocol (
|
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.
|
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.
|
92
|
-
parser (>= 3.3.
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
rubocop (
|
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.
|
112
|
-
webmock (3.25.
|
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.
|
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.
|
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
|
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
|
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
|
26
|
+
raise GlobusClient::InternalServerError, "Unexpected response: #{response.status} #{response.body}."
|
45
27
|
end
|
46
28
|
end
|
47
29
|
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?, :
|
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.
|
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:
|
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.
|
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: []
|