如何使用服务帐户凭据将文件上传到 google 驱动器
How to upload file to google drive with service account credential
我想使用 Google 服务帐户凭据将文件上传到我的 Google 驱动器。
我从 Google 开发者控制台将凭据下载为 JSON 文件,并从中获取了凭据。
这是我的代码片段。
google_drive_service = discovery.build('drive', 'v3',
credentials=ServiceAccountCredentials.from_json_keyfile_name
os.path.join(settings.CLIENT_PATH, settings.CLIENT_SECRET_FILE),
scopes=settings.SCOPES))
media = MediaFileUpload(tmp_file_path, mimetype=tmp_file.content_type, resumable=True)
google_drive_service.files().create(body=file_metadata, media_body=media, fields='id').execute()
代码运行没有错误,但是我找不到上传到我的 Google 云端硬盘帐户的文件。我不确定为什么没有上传文件。你愿意帮我解决这个问题吗?
试试这个 Python 终端客户端 Google 驱动器,以便轻松上传、删除、列出、共享文件或文件夹。
client_secret.json
{"installed":{"client_id":"698477346386-5kbs1fh3c6eu46op4qvf30ehp6md8o56.apps.googleusercontent.com","project_id":"proven-dryad-122714","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"9j4oMk4HI0ZyPvQrz0jFFA4q","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
GDrive.py
from __future__ import print_function
import sys
import io
import pip
import httplib2
import os
from mimetypes import MimeTypes
try:
from googleapiclient.errors import HttpError
from apiclient import discovery
import oauth2client
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
from oauth2client import client
from oauth2client import tools
except ImportError:
print('goole-api-python-client is not installed. Try:')
print('sudo pip install --upgrade google-api-python-client')
sys.exit(1)
import sys
class Flag:
auth_host_name = 'localhost'
noauth_local_webserver = False
auth_host_port = [8080, 8090]
logging_level = 'ERROR'
try:
import argparse
# flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
flags = Flag()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/drive-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'GDrive'
def get_credentials():
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'drive-python-quickstart.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
# if flags:
credentials = tools.run_flow(flow, store, flags)
# else: # Needed only for compatibility with Python 2.6
# credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def upload(path, parent_id=None):
mime = MimeTypes()
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
file_metadata = {
'name': os.path.basename(path),
# 'mimeType' : 'application/vnd.google-apps.spreadsheet'
}
if parent_id:
file_metadata['parents'] = [parent_id]
media = MediaFileUpload(path,
mimetype=mime.guess_type(os.path.basename(path))[0],
resumable=True)
try:
file = service.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
except HttpError:
print('corrupted file')
pass
print(file.get('id'))
def share(file_id, email):
def callback(request_id, response, exception):
if exception:
# Handle error
print(exception)
else:
print(response.get('id'))
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
batch = service.new_batch_http_request(callback=callback)
user_permission = {
'type': 'user',
'role': 'reader',
'emailAddress': email
}
batch.add(service.permissions().create(
fileId=file_id,
body=user_permission,
fields='id',
))
batch.execute()
def listfiles():
results = service.files().list(fields="nextPageToken, files(id, name,mimeType)").execute()
items = results.get('files', [])
if not items:
print('No files found.')
else:
print('Files:')
print('Filename (File ID)')
for item in items:
print('{0} ({1})'.format(item['name'].encode('utf-8'), item['id']))
print('Total=', len(items))
def delete(fileid):
service.files().delete(fileId=fileid).execute()
def download(file_id, path=os.getcwd()):
request = service.files().get_media(fileId=file_id)
name = service.files().get(fileId=file_id).execute()['name']
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print(int(status.progress() * 100))
f = open(path + '/' + name, 'wb')
f.write(fh.getvalue())
print('File downloaded at', path)
f.close()
def createfolder(folder, recursive=False):
if recursive:
print('recursive ON')
ids = {}
for root, sub, files in os.walk(folder):
par = os.path.dirname(root)
file_metadata = {
'name': os.path.basename(root),
'mimeType': 'application/vnd.google-apps.folder'
}
if par in ids.keys():
file_metadata['parents'] = [ids[par]]
print(root)
file = service.files().create(body=file_metadata,
fields='id').execute()
id = file.get('id')
print(id)
ids[root] = id
for f in files:
print(root+'/'+f)
upload(root + '/' + f, id)
else:
print('recursive OFF')
file_metadata = {
'name': os.path.basename(folder),
'mimeType': 'application/vnd.google-apps.folder'
}
file = service.files().create(body=file_metadata,
fields='id').execute()
print(file.get('id'))
if __name__ == '__main__':
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
method = sys.argv[1]
if method == 'upload':
if os.path.isdir(sys.argv[2]):
if len(sys.argv) == 4 and sys.argv[3] == 'R':
createfolder(sys.argv[2], True)
else:
createfolder(os.path.basename(sys.argv[2]))
else:
upload(sys.argv[2])
elif method == 'list':
listfiles()
elif method == 'delete':
delete(sys.argv[2])
elif method == 'download':
download(sys.argv[2], sys.argv[3])
elif method == 'share':
share(sys.argv[2], sys.argv[3])
elif method == 'folder':
createfolder(sys.argv[2])
elif method == 'debug':
print(os.getcwd())
您遇到的问题是服务帐户不是您本人。您已将文件上传到服务帐户 Google 驱动器帐户,而不是您的个人驱动器帐户。尝试执行 file list 您应该会看到该文件。
建议。获取服务帐户电子邮件地址并在您的个人 Google 驱动器帐户上共享一个目录,就像您与任何其他用户共享一样。然后服务帐户将能够上传到该目录。只需确保在上传文件后设置文件的权限,授予您的个人驱动器帐户访问该文件的权限。上传文件后,它将归服务帐户所有。
我想使用 Google 服务帐户凭据将文件上传到我的 Google 驱动器。
我从 Google 开发者控制台将凭据下载为 JSON 文件,并从中获取了凭据。
这是我的代码片段。
google_drive_service = discovery.build('drive', 'v3',
credentials=ServiceAccountCredentials.from_json_keyfile_name
os.path.join(settings.CLIENT_PATH, settings.CLIENT_SECRET_FILE),
scopes=settings.SCOPES))
media = MediaFileUpload(tmp_file_path, mimetype=tmp_file.content_type, resumable=True)
google_drive_service.files().create(body=file_metadata, media_body=media, fields='id').execute()
代码运行没有错误,但是我找不到上传到我的 Google 云端硬盘帐户的文件。我不确定为什么没有上传文件。你愿意帮我解决这个问题吗?
试试这个 Python 终端客户端 Google 驱动器,以便轻松上传、删除、列出、共享文件或文件夹。
client_secret.json
{"installed":{"client_id":"698477346386-5kbs1fh3c6eu46op4qvf30ehp6md8o56.apps.googleusercontent.com","project_id":"proven-dryad-122714","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"9j4oMk4HI0ZyPvQrz0jFFA4q","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
GDrive.py
from __future__ import print_function
import sys
import io
import pip
import httplib2
import os
from mimetypes import MimeTypes
try:
from googleapiclient.errors import HttpError
from apiclient import discovery
import oauth2client
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
from oauth2client import client
from oauth2client import tools
except ImportError:
print('goole-api-python-client is not installed. Try:')
print('sudo pip install --upgrade google-api-python-client')
sys.exit(1)
import sys
class Flag:
auth_host_name = 'localhost'
noauth_local_webserver = False
auth_host_port = [8080, 8090]
logging_level = 'ERROR'
try:
import argparse
# flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
flags = Flag()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/drive-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'GDrive'
def get_credentials():
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'drive-python-quickstart.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
# if flags:
credentials = tools.run_flow(flow, store, flags)
# else: # Needed only for compatibility with Python 2.6
# credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def upload(path, parent_id=None):
mime = MimeTypes()
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
file_metadata = {
'name': os.path.basename(path),
# 'mimeType' : 'application/vnd.google-apps.spreadsheet'
}
if parent_id:
file_metadata['parents'] = [parent_id]
media = MediaFileUpload(path,
mimetype=mime.guess_type(os.path.basename(path))[0],
resumable=True)
try:
file = service.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
except HttpError:
print('corrupted file')
pass
print(file.get('id'))
def share(file_id, email):
def callback(request_id, response, exception):
if exception:
# Handle error
print(exception)
else:
print(response.get('id'))
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
batch = service.new_batch_http_request(callback=callback)
user_permission = {
'type': 'user',
'role': 'reader',
'emailAddress': email
}
batch.add(service.permissions().create(
fileId=file_id,
body=user_permission,
fields='id',
))
batch.execute()
def listfiles():
results = service.files().list(fields="nextPageToken, files(id, name,mimeType)").execute()
items = results.get('files', [])
if not items:
print('No files found.')
else:
print('Files:')
print('Filename (File ID)')
for item in items:
print('{0} ({1})'.format(item['name'].encode('utf-8'), item['id']))
print('Total=', len(items))
def delete(fileid):
service.files().delete(fileId=fileid).execute()
def download(file_id, path=os.getcwd()):
request = service.files().get_media(fileId=file_id)
name = service.files().get(fileId=file_id).execute()['name']
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print(int(status.progress() * 100))
f = open(path + '/' + name, 'wb')
f.write(fh.getvalue())
print('File downloaded at', path)
f.close()
def createfolder(folder, recursive=False):
if recursive:
print('recursive ON')
ids = {}
for root, sub, files in os.walk(folder):
par = os.path.dirname(root)
file_metadata = {
'name': os.path.basename(root),
'mimeType': 'application/vnd.google-apps.folder'
}
if par in ids.keys():
file_metadata['parents'] = [ids[par]]
print(root)
file = service.files().create(body=file_metadata,
fields='id').execute()
id = file.get('id')
print(id)
ids[root] = id
for f in files:
print(root+'/'+f)
upload(root + '/' + f, id)
else:
print('recursive OFF')
file_metadata = {
'name': os.path.basename(folder),
'mimeType': 'application/vnd.google-apps.folder'
}
file = service.files().create(body=file_metadata,
fields='id').execute()
print(file.get('id'))
if __name__ == '__main__':
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
method = sys.argv[1]
if method == 'upload':
if os.path.isdir(sys.argv[2]):
if len(sys.argv) == 4 and sys.argv[3] == 'R':
createfolder(sys.argv[2], True)
else:
createfolder(os.path.basename(sys.argv[2]))
else:
upload(sys.argv[2])
elif method == 'list':
listfiles()
elif method == 'delete':
delete(sys.argv[2])
elif method == 'download':
download(sys.argv[2], sys.argv[3])
elif method == 'share':
share(sys.argv[2], sys.argv[3])
elif method == 'folder':
createfolder(sys.argv[2])
elif method == 'debug':
print(os.getcwd())
您遇到的问题是服务帐户不是您本人。您已将文件上传到服务帐户 Google 驱动器帐户,而不是您的个人驱动器帐户。尝试执行 file list 您应该会看到该文件。
建议。获取服务帐户电子邮件地址并在您的个人 Google 驱动器帐户上共享一个目录,就像您与任何其他用户共享一样。然后服务帐户将能够上传到该目录。只需确保在上传文件后设置文件的权限,授予您的个人驱动器帐户访问该文件的权限。上传文件后,它将归服务帐户所有。