当前位置: 首页 > 知识库问答 >
问题:

如何使用服务帐户凭据将文件上载到google drive

沈永新
2023-03-14

我想上传文件到我的谷歌驱动器使用谷歌服务号凭据。

我从谷歌开发者控制台下载了一个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 Drive帐户的文件。我不知道为什么文件没有上传。你愿意帮我解决这个问题吗?

共有2个答案

伊飞光
2023-03-14

试试这个用于Google Drive的Python终端客户端,可以轻松地上传、删除、列出、共享文件或文件夹。

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())
叶富
2023-03-14

你的问题是一个服务号不是你。你已经上传了一个文件到服务帐户谷歌驱动器帐户,而不是你的个人驱动器帐户。试着做一个文件列表,你应该看到这个文件。

建议获取服务帐户的电子邮件地址,并与它共享您个人Google drive帐户上的目录,就像您与任何其他用户共享一样。然后,服务帐户将能够上载到此目录。只需确保在上传文件后设置文件权限,并授予您的个人驱动器帐户对该文件的访问权限。上传文件后,该文件将归服务帐户所有。

 类似资料:
  • 我正在尝试使用Google Drive Java API v3为我们的应用程序实现一项新服务,该服务负责将文件上传到Google Team Drive中的特定文件夹。我使用我的公司专门为这个项目创建的服务帐户,还从谷歌开发者控制台生成了一个包含私钥的JSON文件。我还使用该服务帐户的电子邮件将该文件夹共享给该服务帐户xxxxx@xxxx.iam.gserviceaccount.com并授予Cont

  • 我正在构建一个功能,将文件从我的web应用程序上传到我的客户google drive。我不希望应用程序对用户进行身份验证。谁曾经上传过我文件中的任何文件?我想上传到我客户的谷歌硬盘。 我假设服务帐户是用于此目的的帐户。我说得对吗? 当我使用以下代码上传文件时,它会成功上传,但在“我的驱动器”下不可见。然后我添加了一个权限,基本上与我的gmail帐户共享该文件。然后它在“与我共享”部分可见。 我希望

  • 我正在构建一个需要读取普通Gmail收件箱(不是域的一部分)的Web服务。 代码: 错误: 我看不出这有什么原因不起作用,但读完这篇文章后,你似乎不能在个人@gmail帐户上使用服务帐户凭据。有谁知道这是真的还是我做错了什么? 感谢您的帮助! 更新 如果我将更改为,我可以查看邮件,但无法修改标签,这是我的要求。

  • 我想用java将文件上传到共享驱动器。我已创建了一个服务帐户,并已将共享驱动器(名称为DB drive)与服务帐户的地址共享。 全局变量 主功能(初始化和列出文件) 授权码 上传代码 我正在将DB Drive(teamdrive或shareddrive)设置为上传文件的父级,但我仍然无法在共享驱动器文件夹中查看该文件。。请帮帮我。 我正在添加完整的流程:- 1.)我使用https://develo

  • 因此,我正在尝试在我的本地主机上获取服务应用程序凭据,并且遇到了一些问题。我创建并下载了json密钥,我想保护它们,而不是让它们变成纯文本。 我想知道最好的方法。我有这个代码: 这里的问题是我的JSON文件在我的存储库中以纯文本形式公开。

  • 我有一个使用OAuth客户端从GDrive文件导出文本的脚本,它运行得非常好- 但是每次都要通过OAuth流是一件痛苦的事情,因为只有我在使用这个脚本,所以我想简化一些事情,使用一个服务帐户来代替它,从这篇文章开始- Google Drive API Python服务帐户示例 我的新服务帐户脚本执行完全相同的操作,如下所示- 但是当我为同一个运行它时,我会得到以下结果- 感觉服务帐户脚本正在通过身