Google python api: экспорт никогда не завершается.

Резюме:

У меня проблема, когда иногда файл google-drive-sdk для python не обнаруживает конца экспортируемого документа. Кажется, что документ Google имеет бесконечный размер.

Фон, исходный код и учебные пособия Я придерживался:

Я работаю над собственной резервной копией google-drive на основе python script (с удобным интерфейсом CLI для просмотра). git ссылка на исходный код

Он все еще находится в процессе создания и в настоящее время только находит новые файлы и загружает их (с командой "pull" ).

Чтобы выполнить самые важные команды google-drive, я следил за официальными руководствами Google для загрузки файлов. здесь

Что работает:

Когда документ или файл является документом, отличным от Google, документ загружается должным образом. Однако, когда я пытаюсь "экспортировать" файл. Я вижу, что мне нужно использовать другой mimeType. У меня есть словарь для этого.

Например: Я экспортирую application/vnd.google-apps.document в application/vnd.openxmlformats-officedocument.wordprocessingml.document при экспорте документа.

Когда загружает документы документов google с Google Drive, это работает нормально. Под этим я подразумеваю: мой цикл while с кодом status, done = downloader.next_chunk() будет иметь конечный набор done до true и загрузка завершается.

Что не работает:

Однако в некоторых файлах флаг done никогда не попадает в true и script будет загружаться навсегда. Это в конечном итоге составляет несколько Гб. Возможно, я ищу неправильный флаг, который говорит, что файл завершен при выполнении экспорта. Я удивлен, что google-drive никогда не выдает ошибку. Кто-нибудь знает, что может вызвать это?

Текущее состояние

Теперь у меня есть экспорт документов Google, отключенных в моем коде.

Когда я использую сценарии типа диск от rakyll" (по крайней мере, у меня есть версия), просто добавляется ссылка на онлайн-копию. Мне бы очень хотелось сделать правильный экспорт, чтобы моя автономная система могла поддерживать полную резервную копию всего на диске.

P.s. Это прекрасно, чтобы поставить "вы должны использовать эту службу вместо api" ради других, которые находят эту страницу. Я знаю, что для этого есть другие сервисы, но я действительно хочу изучить функции drive-api для интеграции с моими другими системами.

1 ответ

OK. Я нашел здесь псевдо-решение.

Проблема заключается в том, что API Google никогда не возвращает Content-Length, и ответ выполняется в Chunks. Однако либо возвращенный фрагмент неверен, либо API Python не может правильно его обработать.

Что я сделал, возьмите код для MediaIoBaseDownload отсюда

Я все равно оставил, но изменил эту часть:

if 'content-range' in resp:
 content_range = resp['content-range']
 length = content_range.rsplit('/', 1)[1]
 self._total_size = int(length)
elif 'content-length' in resp:
 self._total_size = int(resp['content-length'])
else:
 # PSEUDO BUG FIX: No content-length, no chunk info, cut the response here.
 self._total_size = self._progress

else в конце - это то, что я добавил. Я также изменил размер блока по умолчанию, установив DEFAULT_CHUNK_SIZE = 2*1024*1024. Также вам придется скопировать несколько импортных файлов из этого файла, включая этот from googleapiclient.http import _retry_request, _should_retry_response

Конечно, это не решение, оно просто говорит "если я не понимаю ответ, просто останови его". Вероятно, это приведет к тому, что некоторый экспорт не будет работать, но, по крайней мере, он не убивает сервер. Это только до тех пор, пока мы не сможем найти хорошее решение.

UPDATE:

Ошибка уже сообщается здесь: https://github.com/google/google-api-python-client/issues/15

и по состоянию на январь 2017 года единственным обходным решением является не использование MediaIoBaseDownload и вместо этого сделать это (не подходит для больших файлов):

req = service.files().export(fileId=file_id, mimeType=mimeType)
resp = req.execute(http=http)

licensed under cc by-sa 3.0 with attribution.