问题陈述:
尝试从Google Drive API为我的python应用程序下载文件时,我遇到一个问题。我今天才开始使用它,所以我可能做一些愚蠢的事情,所以请耐心等待:)。
我遇到的问题是,使用drive-api对我的应用进行身份验证后,我可以从Google驱动器中读取文件和元数据,但无法下载它们。相关代码发布在下面,以供参考。
遵循的步骤:
我首先按照说明启用了OAuth2,并获取了certificate.json / client_secrets.json。我确保在权限方面范围是正确的,然后生成了我的pickle文件。从那里,我使用了文档和快速入门指南中的代码来编写代码。从那里,我无法取得任何进展。我以为可能需要对我的应用进行安全评估,但我不打算发布它,因此我认为这种权限级别对开发人员来说很好。我看到了许多其他有关此问题的堆栈溢出帖子,但没有得到任何帮助(我认为我已经按照所有相同的步骤来验证和启用我的应用程序的drive-api权限)。
我还无法下载单个文件,因此我认为我没有达到每日限制。我认为我没有正确执行请求身份验证,但是我找不到关于它的任何文档。我将不胜感激,谢谢。
参考代码:
我拥有的所有代码均直接取自文档。以下是相关链接:
这是初始化代码:
# packages
from __future__ import print_function
import pickle
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from apiclient import errors
from googleapiclient.http import MediaIoBaseDownload
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive'] # set permisions to read/write/delete
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'client_secrets.json', SCOPES)
creds = flow.run_local_server(port=0)
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
drive = build('drive', 'v3', credentials=creds)
这是我的驱动器下载功能:
def download_from_drive_to_local(drive, fname):
# search for image in drive
file_search = drive.files().list(
q=f"name = '{fname}'",
spaces='drive',
fields="nextPageToken, files(id, name)").execute()
items = file_search.get('files', [])
print('Files retrieved: ', items)
# download retrieved image from drive
item_ids = [i['id'] for i in items]
if len(item_ids) > 1: print("Warning: multiple files exist with the same name. Using first file found.")
for i in items:
request = drive.files().get_media(fileId=i)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
break
# delete retrieved image from drive
for i in items:
try:
drive.files().delete(fileId=i).execute()
except errors.HttpError as error:
print(f'An error occured deleting file id <{i}>: {error}.')
# write bytearray to file
with open(os.path.join(self.download_dir, f'{fname}.tif'), 'wb') as file: file.write(fh)
当我看到你的脚本,我认为items
的for i in items:
是从items = file_search.get('files', [])
。在这种情况下,i
就像{'name': '###', 'id': '###'}
。当从此开始使用该文件i
时request = drive.files().get_media(fileId=i)
,该文件将作为{'name': '###', 'id': '###'}
。我认为这是您遇到问题的原因。
并且,当您想使用将下载的数据另存为文件时fh = io.BytesIO()
,用于保存它的脚本如下。
with io.open(filename, 'wb') as f:
fh.seek(0)
f.write(fh.read())
当的长度item_ids
是0
,会发生错误。
当以上几点反映到您的脚本时,它将变为以下内容。
# download retrieved image from drive
item_ids = [i['id'] for i in items]
if len(item_ids) > 1: print("Warning: multiple files exist with the same name. Using first file found.")
for i in items:
request = drive.files().get_media(fileId=i)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
break
# delete retrieved image from drive
for i in items:
try:
drive.files().delete(fileId=i).execute()
except errors.HttpError as error:
print(f'An error occured deleting file id <{i}>: {error}.')
# write bytearray to file
with open(os.path.join(self.download_dir, f'{fname}.tif'), 'wb') as file: file.write(fh)
至:
# download retrieved image from drive
item_ids = [i['id'] for i in items]
if len(item_ids) > 1:
print("Warning: multiple files exist with the same name. Using first file found.")
for i in item_ids:
request = drive.files().get_media(fileId=i)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
break
# delete retrieved image from drive
for i in item_ids:
try:
drive.files().delete(fileId=i).execute()
except errors.HttpError as error:
print(f'An error occured deleting file id <{i}>: {error}.')
# write bytearray to file
if item_ids != []:
with io.open(os.path.join(self.download_dir, f'{fname}.tif'), 'wb') as f:
fh.seek(0)
f.write(fh.read())
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句