简体   繁体   English

如何使用 Python 和 Drive API v3 将文件上传到 Google Drive

[英]How to upload a file to Google Drive using Python and the Drive API v3

I have tried uploading file to Google Drive from my local system using a Python script but I keep getting HttpError 403. The script is as follows:我曾尝试使用 Python 脚本将文件从本地系统上传到 Google Drive,但我不断收到 HttpError 403。脚本如下:

from googleapiclient.http import MediaFileUpload
from googleapiclient import discovery
import httplib2
import auth

SCOPES = "https://www.googleapis.com/auth/drive"
CLIENT_SECRET_FILE = "client_secret.json"
APPLICATION_NAME = "test"
authInst = auth.auth(SCOPES, CLIENT_SECRET_FILE, APPLICATION_NAME)
credentials = authInst.getCredentials()
http = credentials.authorize(httplib2.Http())
drive_serivce = discovery.build('drive', 'v3', credentials=credentials)
file_metadata = {'name': 'gb1.png'}
media = MediaFileUpload('./gb.png',
                        mimetype='image/png')
file = drive_serivce.files().create(body=file_metadata,
                                    media_body=media,
                                    fields='id').execute()
print('File ID: %s' % file.get('id'))

The error is :错误是:

googleapiclient.errors.HttpError: <HttpError 403 when requesting
https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&alt=json&fields=id 
returned "Insufficient Permission: Request had insufficient authentication scopes.">

Am I using the right scope in the code or missing anything ?我在代码中使用了正确的范围还是遗漏了什么?

I also tried a script I found online and it is working fine but the issue is that it takes a static token, which expires after some time.我还尝试了我在网上找到的一个脚本,它运行良好,但问题是它需要一个静态令牌,它会在一段时间后过期。 So how can I refresh the token dynamically?那么如何动态刷新令牌呢?

Here is my code:这是我的代码:

import json
import requests
headers = {
    "Authorization": "Bearer TOKEN"}
para = {
    "name": "account.csv",
    "parents": ["FOLDER_ID"]
}
files = {
    'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),
    'file': ('mimeType', open("./test.csv", "rb"))
}
r = requests.post(
    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
    headers=headers,
    files=files
)
print(r.text)

"Insufficient Permission: Request had insufficient authentication scopes." “权限不足:请求的身份验证范围不足。”

Means that the user you have authenticated with has not granted your application permission to do what you are trying to do.意味着您进行身份验证的用户尚未授予您的应用程序权限来执行您尝试执行的操作。

The files.create method requires that you have authenticated the user with one of the following scopes. files.create方法要求您使用以下范围之一对用户进行身份验证。

在此处输入图片说明

while your code does appear to be using the full on drive scope.而您的代码似乎确实使用了完整的驱动范围。 What i suspect has happens is that you have authenticated your user then changed the scope in your code and not promoted the user to login again and grant consent.我怀疑发生的情况是您已经对您的用户进行了身份验证,然后更改了代码中的范围,并且没有促使用户再次登录并授予同意。 You need to remove the users consent from your app either by having them remove it directly in their google account or just deleteing the credeitnals you have stored in your app.您需要通过让用户直接在他们的 Google 帐户中将其删除或仅删除您存储在您的应用程序中的凭据来从您的应用程序中删除用户同意。 This will force the user to login again.这将强制用户再次登录。

There is also an approval prompt force option to the google login but am not a python dev so im not exactly sure how to force that.谷歌登录还有一个批准提示强制选项,但我不是python开发者,所以我不确定如何强制执行。 it should be something like the prompt='consent' line below.它应该类似于下面的 prompt='consent' 行。

flow = OAuth2WebServerFlow(client_id=CLIENT_ID,
                           client_secret=CLIENT_SECRET,
                           scope='https://spreadsheets.google.com/feeds '+
                           'https://docs.google.com/feeds',
                           redirect_uri='http://example.com/auth_return',
                           prompt='consent')

consent screen同意屏幕

If done correctly the user should see a screen like this如果操作正确,用户应该会看到这样的屏幕

在此处输入图片说明

Prompting them to grant you full access to their drive account提示他们授予您对其云端硬盘帐户的完全访问权限

Token pickle令牌泡菜

If you are following googles tutorial here https://developers.google.com/drive/api/v3/quickstart/python you need to delete the token.pickle that contains the users stored consent.如果您在https://developers.google.com/drive/api/v3/quickstart/python上关注 googles 教程,您需要删除包含用户存储同意的 token.pickle。

if os.path.exists('token.pickle'):
    with open('token.pickle', 'rb') as token:
        creds = pickle.load(token)

Answer:回答:

Delete your token.pickle file and re-run your application.删除您的token.pickle文件并重新运行您的应用程序。

More Information:更多信息:

As long as you have the correct set of credentials then all that is required when you update the scopes of your application is to re-obtain a token.只要您拥有正确的凭据集,那么更新应用程序范围时所需的一切就是重新获取令牌。 Delete the token file located in the application's root folder, then run the application again.删除位于应用程序根文件夹中的令牌文件,然后再次运行该应用程序。 If you have the https://www.googleapis.com/auth/drive scope, and the Gmail API enabled in the developer console, you should be good.如果您拥有https://www.googleapis.com/auth/drive范围,并且在开发者控制台中启用了 Gmail API,那么您应该没问题。

References:参考:

You can use the google-api-python-client to build a Drive service for using Drive API .您可以使用google-api-python-client构建Drive 服务以使用Drive API

  • Get your Authorization as by following the first 10 steps of this answer .按照此答案的前 10 个步骤获取您的授权。
  • If you want the user to go through consent screen only once, then store the credentials in a file.如果您希望用户仅通过一次同意屏幕,则将凭据存储在文件中。 They include a refresh token that app can use to request authorization after expired .它们包括一个刷新令牌,应用程序可使用该令牌在过期后请求授权 Example 例子

With a valid Drive Service you can upload a file by calling a function like the following upload_file :使用有效的驱动器服务,您可以通过调用类似以下的函数来上传文件upload_file

def upload_file(drive_service, filename, mimetype, upload_filename, resumable=True, chunksize=262144):
    media = MediaFileUpload(filename, mimetype=mimetype, resumable=resumable, chunksize=chunksize)
    # Add all the writable properties you want the file to have in the body!
    body = {"name": upload_filename} 
    request = drive_service.files().create(body=body, media_body=media).execute()
    if getFileByteSize(filename) > chunksize:
        response = None
        while response is None:
            chunk = request.next_chunk()
            if chunk:
                status, response = chunk
                if status:
                    print("Uploaded %d%%." % int(status.progress() * 100))
    print("Upload Complete!")

Now pass in the parameters and call the function...现在传入参数并调用函数...

# Upload file
upload_file(drive_service, 'my_local_image.png', 'image/png', 'my_imageination.png' )

You will see the file with the name: my_imageination.png in your Google Drive root folder.您将在 Google Drive 根文件夹中看到名称为my_imageination.png 的文件。

More about the Drive API v3 service and available methods here . 在此处详细了解 Drive API v3 服务和可用方法。


getFileSize() function: getFileSize()函数:

def getFileByteSize(filename):
    # Get file size in python
    from os import stat
    file_stats = stat(filename)
    print('File Size in Bytes is {}'.format(file_stats.st_size))
    return file_stats.st_size

Uploading to certain folder(s) in your drive is easy...上传到驱动器中的某些文件夹很容易...

Just add the parent folder Id(s) in the body of the request.只需在请求正文中添加父文件夹 ID。

Here are the properties of a File .这是File属性 文件的父母 [] 属性

Example:例子:

request_body = {
  "name": "getting_creative_now.png",
  "parents": ['myFiRsTPaRentFolderId',
              'MyOtherParentId',
              'IcanTgetEnoughParentsId'],
}

To use the scope 'https://www.googleapis.com/auth/drive' you need to submit the google app for verification.要使用范围“https://www.googleapis.com/auth/drive”,您需要提交谷歌应用程序进行验证。

Find the image for scope查找范围的图像

So use the scope 'https://www.googleapis.com/auth/drive.file' instead of 'https://www.googleapis.com/auth/drive' to upload files without verification.因此,请使用范围“https://www.googleapis.com/auth/drive.file”而不是“https://www.googleapis.com/auth/drive”来上传文件而无需验证。

Also use SCOPES as list.还可以使用 SCOPE 作为列表。

ex: SCOPES = ['https://www.googleapis.com/auth/drive.file']例如: SCOPES = ['https://www.googleapis.com/auth/drive.file']

I can successfully upload and download the files to google drive by using the above SCOPE.我可以使用上述 SCOPE 成功上传和下载文件到谷歌驱动器。

I found the solution for uploading a file to google drive.我找到了将文件上传到谷歌驱动器的解决方案。 Here it is:这里是:

import requests
import json
url = "https://www.googleapis.com/oauth2/v4/token"

        payload = "{\n\"" \
                  "client_id\": \"CLIENT_ID" \
                  "\",\n\"" \
                  "client_secret\": \"CLIENT SECRET" \
                  "\",\n\"" \
                  "refresh_token\": \"REFRESH TOKEN" \
                  "\",\n\"" \
                  "grant_type\": \"refresh_token\"\n" \
                  "}"
        headers = {
            'grant_type': 'authorization_code',
            'Content-Type': 'application/json'
        }

        response = requests.request("POST", url, headers=headers, data=payload)

        res = json.loads(response.text.encode('utf8'))


        headers = {
            "Authorization": "Bearer %s" % res['access_token']
        }
        para = {
            "name": "file_path",
            "parents": "google_drive_folder_id"
        }
        files = {
            'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),
            # 'file': open("./gb.png", "rb")
            'file': ('mimeType', open("file_path", "rb"))
        }
        r = requests.post(
            "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
            headers=headers,
            files=files
        )
        print(r.text)

For generating client id, client secret and refresh token, you can follow the link :- click here要生成客户端 ID、客户端密钥和刷新令牌,您可以点击以下链接:- 单击此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过python的Google Drive api v3文件上传错误 - Google Drive api v3 file upload errors via python 如何使用 Python 和 Drive API v3 从 Google Drive 下载文件 - How to download a file from Google Drive using Python and the Drive API v3 Google Client API v3 - 使用 Python 更新驱动器上的文件 - Google Client API v3 - update a file on drive using Python 如何使用 Python 将文件插入/上传到 Google Drive API v3 中的特定文件夹 - How can I insert/upload files to a specific folder in Google Drive API v3 using Python 如何使用Google Drive API v3上传到Python中的共享驱动器? - How do I upload to a shared drive in Python with Google Drive API v3? 使用gzip通过API v3 Python 3优化上传到云端硬盘 - Using gzip to Optimize Upload to Drive using API v3 Python 3 使用 Python 中的 next_chunk() 上传 Google Drive API v3 错误查看状态的说明? - Explaination on error viewing status of Google Drive API v3 upload using next_chunk() in Python? 如何使用 Python (FLASK) 实现 Google Drive V3 API - How to Implement Google Drive V3 API with Python (FLASK) 如何在 Python 中使用 Google Drive API v3 更改所有者? - How to change the owner with Google Drive API v3 in Python? 如何使用python Telegram Bot API将文件上传到Google驱动器 - How to upload a file to google drive using python Telegram Bot API
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM