Google Drive API v3更改文件权限并获取公开共享的链接(Python)

时间:2019-01-12 18:59:21

标签: python python-3.x permissions google-drive-api

我正在尝试将Google Drive API v3与Python 3配合使用,以自动上传文件,将其设置为“公开”并获取任何人都可以查看和下载的共享链接(但不能修改)。

我已经接近了,但是还不太清楚!遵守我的代码。它要求一个名为“ testing.txt”的文本文件与脚本位于同一目录:

from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

from apiclient.http import MediaFileUpload
from apiclient import errors

# https://developers.google.com/drive/api/v2/about-auth#requesting_full_drive_scope_during_app_development
SCOPES = 'https://www.googleapis.com/auth/drive' # https://stackoverflow.com/a/32309750

# https://developers.google.com/drive/api/v2/reference/permissions/update
def update_permission(service, file_id, permission_id, new_role, type):
  """Update a permission's role.

  Args:
    service: Drive API service instance.
    file_id: ID of the file to update permission for.
    permission_id: ID of the permission to update.
    new_role: The value 'owner', 'writer' or 'reader'.

  Returns:
    The updated permission if successful, None otherwise.
  """
  try:
    # First retrieve the permission from the API.
    permission = service.permissions().get(fileId=file_id, permissionId=permission_id).execute()
    permission['role'] = new_role
    permission['type'] = type
    return service.permissions().update(fileId=file_id, permissionId=permission_id, body=permission).execute()
  except errors.HttpError as error:
    print('An error occurred:', error)
  return None

if __name__ == '__main__':
    # credential things
    store = file.Storage('token.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
        creds = tools.run_flow(flow, store)
    drive_service = build('drive', 'v3', http=creds.authorize(Http()))

    # create and upload file
    file_metadata = {'name': 'testing.txt'}
    media = MediaFileUpload('testing.txt',
                            mimetype='text/txt')
    file = drive_service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id, webViewLink, permissions').execute()

    # get information needed to update permissions
    file_id = file['id']
    permission_id = file['permissions'][0]['id']

    print(file_id)
    print(permission_id)

    # update permissions?  It doesn't work!
    update_permission(drive_service, file_id, permission_id, 'reader', 'anyone') # https://stackoverflow.com/a/11669565

    print(file.get('webViewLink'))

运行此代码时,收到以下消息:

1quyzYHc0uCQIEt88gqd4h_jWtlBaoHHH
01486072639937946874
An error occurred: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/1quyzYHc0uCQIEt88gqd4h_jWtlBaoHHH/permissions/01486072639937946874?alt=json returned "The resource body includes fields which are not directly writable.">
https://drive.google.com/file/d/1quyzYHc0uCQIEt88gqd4h_jWtlBaoHHH/view?usp=drivesdk

当我将最终链接复制并粘贴到另一个浏览器中时,它不可用,因此很明显,它未能成功更改文件权限。但是我不明白为什么它失败了。它提到了The resource body includes fields which are not directly writable,但我不知道这意味着什么。

有人可以帮助我了解我做错了什么以及需要解决的问题才能解决?谢谢。

3 个答案:

答案 0 :(得分:1)

选择的答案不够精确(与类型值和角色无关),因此我不得不多读一些文档,这是一个有效的示例,您只需要提供file_id:

def set_permission(service, file_id):
    print(file_id)
    try:
        permission = {'type': 'anyone',
                      'value': 'anyone',
                      'role': 'reader'}
        return service.permissions().create(fileId=file_id,body=permission).execute()
    except errors.HttpError as error:
        return print('Error while setting permission:', error)

答案 1 :(得分:0)

此修改如何?我认为您已经可以上传文件了。因此,我想对update_permission()的功能进行修改。

修改点:

  • 我认为根据您的情况,需要通过创建来添加权限。
    • 因此您可以使用service.permissions().create()
    • 要更新创建的权限时,请使用创建权限时检索到的ID。

修改后的脚本:

请如下修改update_permission()

从:
try:
  # First retrieve the permission from the API.
  permission = service.permissions().get(fileId=file_id, permissionId=permission_id).execute()
  permission['role'] = new_role
  permission['type'] = type
  return service.permissions().update(fileId=file_id, permissionId=permission_id, body=permission).execute()
except errors.HttpError as error:
  print('An error occurred:', error)
return None
至:
try:
  permission = {
      "role": new_role,
      "type": types,
  }
  return service.permissions().create(fileId=file_id, body=permission).execute()
except errors.HttpError as error:
  print('An error occurred:', error)
return None

注意:

  • 此修改后的脚本假定您的环境可以使用Drive API。

参考:

如果我误解了你的问题,对不起。

答案 2 :(得分:0)

错别字:请注意,在初始代码中,它在 update_permission 的函数标头中说“ type”,但是在更正的代码段中,回复使用“ types”。