google-apis-core 0.15.1 → 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 +22 -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 +9 -4
- 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 -9
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,27 @@
|
|
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
|
+
|
19
|
+
### 0.16.0 (2025-01-12)
|
20
|
+
|
21
|
+
#### Features
|
22
|
+
|
23
|
+
* add ECONNRESET error as retriable error ([#20354](https://github.com/googleapis/google-api-ruby-client/issues/20354))
|
24
|
+
|
3
25
|
### 0.15.1 (2024-07-29)
|
4
26
|
|
5
27
|
#### Bug Fixes
|
@@ -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
|
@@ -292,7 +292,12 @@ module Google
|
|
292
292
|
rescue Google::Apis::Error => e
|
293
293
|
err = e
|
294
294
|
end
|
295
|
-
elsif err.is_a?(HTTPClient::TimeoutError) ||
|
295
|
+
elsif err.is_a?(HTTPClient::TimeoutError) ||
|
296
|
+
err.is_a?(SocketError) ||
|
297
|
+
err.is_a?(HTTPClient::KeepAliveDisconnected) ||
|
298
|
+
err.is_a?(Errno::ECONNREFUSED) ||
|
299
|
+
err.is_a?(Errno::ETIMEDOUT) ||
|
300
|
+
err.is_a?(Errno::ECONNRESET)
|
296
301
|
err = Google::Apis::TransmissionError.new(err)
|
297
302
|
end
|
298
303
|
block.call(nil, err) if block_given?
|
@@ -380,7 +385,7 @@ module Google
|
|
380
385
|
end
|
381
386
|
|
382
387
|
def safe_pretty_representation obj
|
383
|
-
out = ""
|
388
|
+
out = +""
|
384
389
|
printer = RedactingPP.new out, 79
|
385
390
|
printer.guard_inspect_key { printer.pp obj }
|
386
391
|
printer.flush
|
@@ -388,7 +393,7 @@ module Google
|
|
388
393
|
end
|
389
394
|
|
390
395
|
def safe_single_line_representation obj
|
391
|
-
out = ""
|
396
|
+
out = +""
|
392
397
|
printer = RedactingSingleLine.new out
|
393
398
|
printer.guard_inspect_key { printer.pp obj }
|
394
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,14 +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
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: representable
|
@@ -126,7 +125,6 @@ dependencies:
|
|
126
125
|
- - ">="
|
127
126
|
- !ruby/object:Gem::Version
|
128
127
|
version: '0'
|
129
|
-
description:
|
130
128
|
email: googleapis-packages@google.com
|
131
129
|
executables: []
|
132
130
|
extensions: []
|
@@ -166,9 +164,8 @@ licenses:
|
|
166
164
|
metadata:
|
167
165
|
bug_tracker_uri: https://github.com/googleapis/google-api-ruby-client/issues
|
168
166
|
changelog_uri: https://github.com/googleapis/google-api-ruby-client/tree/main/google-apis-core/CHANGELOG.md
|
169
|
-
documentation_uri: https://googleapis.dev/ruby/google-apis-core/v0.
|
167
|
+
documentation_uri: https://googleapis.dev/ruby/google-apis-core/v0.18.0
|
170
168
|
source_code_uri: https://github.com/googleapis/google-api-ruby-client/tree/main/google-apis-core
|
171
|
-
post_install_message:
|
172
169
|
rdoc_options: []
|
173
170
|
require_paths:
|
174
171
|
- lib
|
@@ -176,15 +173,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
176
173
|
requirements:
|
177
174
|
- - ">="
|
178
175
|
- !ruby/object:Gem::Version
|
179
|
-
version: '
|
176
|
+
version: '3.1'
|
180
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
178
|
requirements:
|
182
179
|
- - ">="
|
183
180
|
- !ruby/object:Gem::Version
|
184
181
|
version: '0'
|
185
182
|
requirements: []
|
186
|
-
rubygems_version: 3.
|
187
|
-
signing_key:
|
183
|
+
rubygems_version: 3.6.9
|
188
184
|
specification_version: 4
|
189
185
|
summary: Common utility and base classes for legacy Google REST clients
|
190
186
|
test_files: []
|