google-apis-core 0.16.0 → 0.18.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/CHANGELOG.md +16 -0
- data/lib/google/apis/core/base_service.rb +31 -1
- data/lib/google/apis/core/composite_io.rb +1 -1
- data/lib/google/apis/core/download.rb +1 -1
- data/lib/google/apis/core/http_command.rb +3 -3
- data/lib/google/apis/core/multipart.rb +4 -4
- data/lib/google/apis/core/storage_upload.rb +92 -3
- data/lib/google/apis/core/version.rb +1 -1
- data/lib/google/apis/errors.rb +1 -1
- data/lib/google/apis/options.rb +2 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adcaaf904d1c4e3e203b45c527c259c1be63aa675402247297a96ca087b5e14a
|
4
|
+
data.tar.gz: 6bafca376fc6569b0e8ff19071c1729e83310f55d3cb3b99e11d5440448ffd83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a24caabd4a3bfc09f9de6be416165fa6aa4b90f89b7ecf4f948801cba266c81e497f773fe25740a723056db708342a28eb36584a11dc43a436ca90e2eb95234
|
7
|
+
data.tar.gz: 4da89f87e45e5edf5c359aef57878e044c90411638c899744efe5235215fa576b2cd3eb46fa61b1678a4b57dda521b6f9fb386c8868a3b9118ddc494757f8a9a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.18.0 (2025-05-22)
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Restart & delete resumable upload ([#21896](https://github.com/googleapis/google-api-ruby-client/issues/21896))
|
8
|
+
|
9
|
+
### 0.17.0 (2025-04-30)
|
10
|
+
|
11
|
+
#### Features
|
12
|
+
|
13
|
+
* ruby 3.1 minimum, 3.4 default ([#22594](https://github.com/googleapis/google-api-ruby-client/issues/22594))
|
14
|
+
#### Bug Fixes
|
15
|
+
|
16
|
+
* Fixed a method redefined warning ([#21572](https://github.com/googleapis/google-api-ruby-client/issues/21572))
|
17
|
+
* Ensure compatibility with frozen string literals ([#21648](https://github.com/googleapis/google-api-ruby-client/issues/21648))
|
18
|
+
|
3
19
|
### 0.16.0 (2025-01-12)
|
4
20
|
|
5
21
|
#### Features
|
@@ -151,7 +151,7 @@ module Google
|
|
151
151
|
|
152
152
|
# HTTP client
|
153
153
|
# @return [HTTPClient]
|
154
|
-
|
154
|
+
attr_writer :client
|
155
155
|
|
156
156
|
# General settings
|
157
157
|
# @return [Google::Apis::ClientOptions]
|
@@ -350,6 +350,36 @@ module Google
|
|
350
350
|
true
|
351
351
|
end
|
352
352
|
|
353
|
+
# Restarts An interrupted Resumable upload
|
354
|
+
# @param [String] bucket
|
355
|
+
# Name of the bucket where the upload is being performed.
|
356
|
+
# @param [IO, String] upload_source
|
357
|
+
# IO stream or filename containing content to upload
|
358
|
+
# @param [IO, String] upload_id
|
359
|
+
# unique id generated for an ongoing upload
|
360
|
+
|
361
|
+
def restart_resumable_upload(bucket, upload_source, upload_id, options: nil)
|
362
|
+
command = make_storage_upload_command(:put, 'b/{bucket}/o', options)
|
363
|
+
command.upload_source = upload_source
|
364
|
+
command.upload_id = upload_id
|
365
|
+
command.params['bucket'] = bucket unless bucket.nil?
|
366
|
+
execute_or_queue_command(command)
|
367
|
+
end
|
368
|
+
|
369
|
+
# Deletes An interrupted Resumable upload
|
370
|
+
# @param [String] bucket
|
371
|
+
# Name of the bucket where the upload is being performed.
|
372
|
+
# @param [IO, String] upload_id
|
373
|
+
# unique id generated for an ongoing upload
|
374
|
+
|
375
|
+
def delete_resumable_upload(bucket, upload_id, options: nil)
|
376
|
+
command = make_storage_upload_command(:delete, 'b/{bucket}/o', options)
|
377
|
+
command.upload_id = upload_id
|
378
|
+
command.params['bucket'] = bucket unless bucket.nil?
|
379
|
+
command.delete_upload = options[:delete_upload] unless options[:delete_upload].nil?
|
380
|
+
execute_or_queue_command(command)
|
381
|
+
end
|
382
|
+
|
353
383
|
protected
|
354
384
|
|
355
385
|
# Create a new upload command.
|
@@ -283,7 +283,7 @@ module Google
|
|
283
283
|
# @yield [nil, err] if block given
|
284
284
|
# @raise [StandardError] if no block
|
285
285
|
def error(err, rethrow: false, &block)
|
286
|
-
logger.debug { sprintf('Error - %s', PP.pp(err, '')) }
|
286
|
+
logger.debug { sprintf('Error - %s', PP.pp(err, +'')) }
|
287
287
|
if err.is_a?(HTTPClient::BadResponseError)
|
288
288
|
begin
|
289
289
|
res = err.res
|
@@ -385,7 +385,7 @@ module Google
|
|
385
385
|
end
|
386
386
|
|
387
387
|
def safe_pretty_representation obj
|
388
|
-
out = ""
|
388
|
+
out = +""
|
389
389
|
printer = RedactingPP.new out, 79
|
390
390
|
printer.guard_inspect_key { printer.pp obj }
|
391
391
|
printer.flush
|
@@ -393,7 +393,7 @@ module Google
|
|
393
393
|
end
|
394
394
|
|
395
395
|
def safe_single_line_representation obj
|
396
|
-
out = ""
|
396
|
+
out = +""
|
397
397
|
printer = RedactingSingleLine.new out
|
398
398
|
printer.guard_inspect_key { printer.pp obj }
|
399
399
|
printer.flush
|
@@ -31,7 +31,7 @@ module Google
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def to_io(boundary)
|
34
|
-
part = ''
|
34
|
+
part = +''
|
35
35
|
part << "--#{boundary}\r\n"
|
36
36
|
part << "Content-Type: application/json\r\n"
|
37
37
|
@header.each do |(k, v)|
|
@@ -59,7 +59,7 @@ module Google
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def to_io(boundary)
|
62
|
-
head = ''
|
62
|
+
head = +''
|
63
63
|
head << "--#{boundary}\r\n"
|
64
64
|
@header.each do |(k, v)|
|
65
65
|
head << "#{k}: #{v}\r\n"
|
@@ -67,7 +67,7 @@ module Google
|
|
67
67
|
head << "Content-Length: #{@length}\r\n" unless @length.nil?
|
68
68
|
head << "Content-Transfer-Encoding: binary\r\n"
|
69
69
|
head << "\r\n"
|
70
|
-
Google::Apis::Core::CompositeIO.new(StringIO.new(head), @io, StringIO.new("\r\n"))
|
70
|
+
Google::Apis::Core::CompositeIO.new(StringIO.new(head), @io, StringIO.new(+"\r\n"))
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -126,7 +126,7 @@ module Google
|
|
126
126
|
# @return [IO]
|
127
127
|
# IO stream
|
128
128
|
def assemble
|
129
|
-
@parts << StringIO.new("--#{@boundary}--\r\n\r\n")
|
129
|
+
@parts << StringIO.new(+"--#{@boundary}--\r\n\r\n")
|
130
130
|
Google::Apis::Core::CompositeIO.new(*@parts)
|
131
131
|
end
|
132
132
|
end
|
@@ -49,6 +49,14 @@ module Google
|
|
49
49
|
# @return [Integer]
|
50
50
|
attr_accessor :upload_chunk_size
|
51
51
|
|
52
|
+
# Unique upload_id of a resumable upload
|
53
|
+
# @return [String]
|
54
|
+
attr_accessor :upload_id
|
55
|
+
|
56
|
+
# Boolean Value to specify is a resumable upload is to be deleted or not
|
57
|
+
# @return [Boolean]
|
58
|
+
attr_accessor :delete_upload
|
59
|
+
|
52
60
|
# Ensure the content is readable and wrapped in an IO instance.
|
53
61
|
#
|
54
62
|
# @return [void]
|
@@ -61,7 +69,6 @@ module Google
|
|
61
69
|
# asserting that it already has a body. Form encoding is never used
|
62
70
|
# by upload requests.
|
63
71
|
self.body = '' unless self.body
|
64
|
-
|
65
72
|
super
|
66
73
|
if streamable?(upload_source)
|
67
74
|
self.upload_io = upload_source
|
@@ -73,6 +80,8 @@ module Google
|
|
73
80
|
self.upload_content_type = type&.content_type
|
74
81
|
end
|
75
82
|
@close_io_on_finish = true
|
83
|
+
elsif !upload_id.nil? && delete_upload
|
84
|
+
@close_io_on_finish = false
|
76
85
|
else
|
77
86
|
fail Google::Apis::ClientError, 'Invalid upload source'
|
78
87
|
end
|
@@ -80,7 +89,7 @@ module Google
|
|
80
89
|
|
81
90
|
# Close IO stream when command done. Only closes the stream if it was opened by the command.
|
82
91
|
def release!
|
83
|
-
upload_io.close if @close_io_on_finish
|
92
|
+
upload_io.close if @close_io_on_finish && !upload_io.nil?
|
84
93
|
end
|
85
94
|
|
86
95
|
# Execute the command, retrying as necessary
|
@@ -96,8 +105,16 @@ module Google
|
|
96
105
|
prepare!
|
97
106
|
opencensus_begin_span
|
98
107
|
@upload_chunk_size = options.upload_chunk_size
|
108
|
+
if upload_id.nil?
|
109
|
+
res = do_retry :initiate_resumable_upload, client
|
110
|
+
elsif delete_upload && !upload_id.nil?
|
111
|
+
construct_resumable_upload_url upload_id
|
112
|
+
res = do_retry :cancel_resumable_upload, client
|
113
|
+
else
|
114
|
+
construct_resumable_upload_url upload_id
|
115
|
+
res = do_retry :reinitiate_resumable_upload, client
|
116
|
+
end
|
99
117
|
|
100
|
-
do_retry :initiate_resumable_upload, client
|
101
118
|
while @upload_incomplete
|
102
119
|
res = do_retry :send_upload_command, client
|
103
120
|
end
|
@@ -131,6 +148,22 @@ module Google
|
|
131
148
|
error(e, rethrow: true)
|
132
149
|
end
|
133
150
|
|
151
|
+
# Reinitiating resumable upload
|
152
|
+
def reinitiate_resumable_upload(client)
|
153
|
+
logger.debug { sprintf('Restarting resumable upload command to %s', url) }
|
154
|
+
check_resumable_upload client
|
155
|
+
upload_io.pos = @offset
|
156
|
+
end
|
157
|
+
|
158
|
+
# Making resumable upload url from upload_id
|
159
|
+
def construct_resumable_upload_url(upload_id)
|
160
|
+
query_params = query.dup
|
161
|
+
query_params['uploadType'] = RESUMABLE
|
162
|
+
query_params['upload_id'] = upload_id
|
163
|
+
resumable_upload_params = query_params.map { |key, value| "#{key}=#{value}" }.join('&')
|
164
|
+
@upload_url = "#{url}&#{resumable_upload_params}"
|
165
|
+
end
|
166
|
+
|
134
167
|
# Send the actual content
|
135
168
|
#
|
136
169
|
# @param [HTTPClient] client
|
@@ -160,6 +193,9 @@ module Google
|
|
160
193
|
@offset += current_chunk_size if @upload_incomplete
|
161
194
|
success(result)
|
162
195
|
rescue => e
|
196
|
+
logger.warn {
|
197
|
+
"error occured please use uploadId-#{response.headers['X-GUploader-UploadID']} to resume your upload"
|
198
|
+
} unless response.nil?
|
163
199
|
upload_io.pos = @offset
|
164
200
|
error(e, rethrow: true)
|
165
201
|
end
|
@@ -182,6 +218,59 @@ module Google
|
|
182
218
|
super(status, header, body)
|
183
219
|
end
|
184
220
|
|
221
|
+
def check_resumable_upload(client)
|
222
|
+
# Setting up request header
|
223
|
+
request_header = header.dup
|
224
|
+
request_header[CONTENT_RANGE_HEADER] = "bytes */#{upload_io.size}"
|
225
|
+
request_header[CONTENT_LENGTH_HEADER] = '0'
|
226
|
+
# Initiating call
|
227
|
+
response = client.put(@upload_url, header: request_header, follow_redirect: true)
|
228
|
+
handle_resumable_upload_http_response_codes(response)
|
229
|
+
end
|
230
|
+
|
231
|
+
# Cancel resumable upload
|
232
|
+
def cancel_resumable_upload(client)
|
233
|
+
# Setting up request header
|
234
|
+
request_header = header.dup
|
235
|
+
request_header[CONTENT_LENGTH_HEADER] = '0'
|
236
|
+
# Initiating call
|
237
|
+
response = client.delete(@upload_url, header: request_header, follow_redirect: true)
|
238
|
+
handle_resumable_upload_http_response_codes(response)
|
239
|
+
|
240
|
+
if !@upload_incomplete && (400..499).include?(response.code.to_i)
|
241
|
+
@close_io_on_finish = true
|
242
|
+
true # method returns true if upload is successfully cancelled
|
243
|
+
else
|
244
|
+
logger.debug { sprintf("Failed to cancel upload session. Response: #{response.code} - #{response.body}") }
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
def handle_resumable_upload_http_response_codes(response)
|
250
|
+
code = response.code.to_i
|
251
|
+
|
252
|
+
case code
|
253
|
+
when 308
|
254
|
+
if response.headers['Range']
|
255
|
+
range = response.headers['Range']
|
256
|
+
@offset = range.split('-').last.to_i + 1
|
257
|
+
logger.debug { sprintf("Upload is incomplete. Bytes uploaded so far: #{range}") }
|
258
|
+
else
|
259
|
+
logger.debug { sprintf('No bytes uploaded yet.') }
|
260
|
+
end
|
261
|
+
@upload_incomplete = true
|
262
|
+
when 400..499
|
263
|
+
# Upload is canceled
|
264
|
+
@upload_incomplete = false
|
265
|
+
when 200, 201
|
266
|
+
# Upload is complete.
|
267
|
+
@upload_incomplete = false
|
268
|
+
else
|
269
|
+
logger.debug { sprintf("Unexpected response: #{response.code} - #{response.body}") }
|
270
|
+
@upload_incomplete = true
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
185
274
|
def streamable?(upload_source)
|
186
275
|
upload_source.is_a?(IO) || upload_source.is_a?(StringIO) || upload_source.is_a?(Tempfile)
|
187
276
|
end
|
data/lib/google/apis/errors.rb
CHANGED
data/lib/google/apis/options.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google-apis-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Google LLC
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: representable
|
@@ -164,7 +164,7 @@ licenses:
|
|
164
164
|
metadata:
|
165
165
|
bug_tracker_uri: https://github.com/googleapis/google-api-ruby-client/issues
|
166
166
|
changelog_uri: https://github.com/googleapis/google-api-ruby-client/tree/main/google-apis-core/CHANGELOG.md
|
167
|
-
documentation_uri: https://googleapis.dev/ruby/google-apis-core/v0.
|
167
|
+
documentation_uri: https://googleapis.dev/ruby/google-apis-core/v0.18.0
|
168
168
|
source_code_uri: https://github.com/googleapis/google-api-ruby-client/tree/main/google-apis-core
|
169
169
|
rdoc_options: []
|
170
170
|
require_paths:
|
@@ -173,14 +173,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
173
173
|
requirements:
|
174
174
|
- - ">="
|
175
175
|
- !ruby/object:Gem::Version
|
176
|
-
version: '
|
176
|
+
version: '3.1'
|
177
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
178
|
requirements:
|
179
179
|
- - ">="
|
180
180
|
- !ruby/object:Gem::Version
|
181
181
|
version: '0'
|
182
182
|
requirements: []
|
183
|
-
rubygems_version: 3.6.
|
183
|
+
rubygems_version: 3.6.9
|
184
184
|
specification_version: 4
|
185
185
|
summary: Common utility and base classes for legacy Google REST clients
|
186
186
|
test_files: []
|