我想使用Google服务帐户凭据将文件上传到我的Google云端硬盘。
我从Google Developer Console下载了凭证作为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云端硬盘帐户的文件。我不确定为什么不上传文件。你想帮我解决这个问题吗?
答案 0 :(得分:7)
您遇到的问题是服务帐户不是您。您已将文件上传到服务帐户Google云端硬盘帐户,而不是您的个人云端硬盘帐户。尝试执行file list您应该看到该文件。
建议。获取服务帐户电子邮件地址并与您共享个人Google云端硬盘帐户中的目录,就像您与其他任何用户共享一样。然后,服务帐户将能够上载到此目录。只需确保在上传文件后设置文件权限,授予您个人驱动器帐户访问该文件的权限。上传文件时,它将归服务帐户所有。
答案 1 :(得分:-2)
为Google云端硬盘试用此终端客户端,以便轻松上传,删除,列出,共享文件或文件夹。
client_secret.json
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())
GDrive.py
@login_required
def enter_queue(request):
# get the user from the Django request & map to variable
django_user = request.user
#link user_profile to django users profile model & get user's profile
user_profile = django_user.profile
#user_profile = Profile.objects.get(user=request.user)
#Map user_availabilities variable to profile from Availability model
users_availabilities = Availability.objects.filter(profile=user_profile)
#mapping user_avail to user profile
#creating an array to store all matching sessions
all_matching_sessions = []
# avail is each Availability object
for avail in users_availabilities:
if avail.end_time:
return HttpResponseRedirect(render(request,'mysite/profile.html'))
else:
matching_sessions = Session.objects.filter(end_time__lte=avail.end_time)#looping through all the sessions end times that match to availability
#adding them to the array
all_matching_sessions = all_matching_sessions + matching_sessions
#If no matching sessions are available
if len(all_matching_sessions) == 0:
#create a session
player_session = Session(
game = 'random_game',
start_time = users_availabilities[0].start_time,
end_time = users_availabilities[0].end_time,
)
player_session.save()
return render(request, 'mysite/profile.html')
else:
player_session = Session(
session = all_matching_sessions[0],
profile = user_profile
)
player_session.save()
#return HttpResponse('Waiting in queue')
return render(request, 'mysite/profile.html')