如何使用服务帐户凭据将文件上传到Google云端硬盘

时间:2018-04-05 02:48:43

标签: python google-api google-drive-api google-api-python-client service-accounts

我想使用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云端硬盘帐户的文件。我不确定为什么不上传文件。你想帮我解决这个问题吗?

2 个答案:

答案 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')