Это частичный ответ, который касается начального байта диапазона, но не конечного байта.
Как указано в комментариях Tanaike , MediaIoBaseDownload
игнорирует пользователя HTTP Range
Диапазон, указанный следующим образом:
request.headers["Range"] = "bytes={}-{}".format(start, start+length)
фактически добавляется к self._headers
в конструкторе MediaIoBaseDownload
, но быстро перезаписывается при первом вызове метода next_chunk
, где headers['range']
установлен на 'bytes=%d-%d' % (self._progress, self._progress + self._chunksize)
. При первом вызове self._progress=0
(устанавливается конструктором), поэтому метод всегда начнет загрузку с первого (нулевого) байта файла.
Существует несколько простых способов изменить это. Мы могли бы проверить, существует ли request.headers['Range']
и проанализировать ли указанные байтовые позиции. В качестве альтернативы, мы можем представить поведение непосредственно вызывающей стороне, добавив дополнительные аргументы ключевого слова в конструктор для передачи начальных и конечных позиций байтов.
Следующий патч (против версии 1.7.11 googleapiclient
) принимает подход добавления аргумента ключевого слова start
в конструктор MediaIoBaseDownload
, чтобы загрузка могла начинаться с байта Nth
. Если начальный байт не указан, он будет загружен по умолчанию с начала файла. Поскольку поддержка конечной позиции байта не была реализована, загрузка будет продолжаться до EOF
.
--- googleapiclient/http.py.orig 2019-08-05 12:24:31.000000000 -0700
+++ googleapiclient/http.py 2020-01-19 18:31:56.785404831 -0800
@@ -632,7 +632,7 @@
"""
@util.positional(3)
- def __init__(self, fd, request, chunksize=DEFAULT_CHUNK_SIZE):
+ def __init__(self, fd, request, chunksize=DEFAULT_CHUNK_SIZE, start=0):
"""Constructor.
Args:
@@ -646,7 +646,7 @@
self._request = request
self._uri = request.uri
self._chunksize = chunksize
- self._progress = 0
+ self._progress = start
self._total_size = None
self._done = False