Google API 文件权限使用 python

Google API file permissions using python

我需要为我网站的不同用户做一些功能,以自动将 html 文件上传到 google 磁盘并打开它们以在 google 文档中查看和编辑。为此,我创建了一个文档,将其传递到 google 磁盘并使用创建文档的 ID 在 google docs.
中打开它 要访问 api,我使用从服务 Google 帐户获取的 json 文件。我尝试使用 ownerview 权限执行我的代码,但结果是一样的。

class CvView(AuthorizedMixin, View):
    """Here I check if the file format is html, I temporarily save it on disk and pass it to the file_to_drive function (to save it to google disk and open it in google docs) and delete it from disk"""


    def get(self, request, employee_id, format_):
        """Returns employee's CV in format which is equal to `format_`
        parameter."""

        employee = get_object_or_404(Employee, pk=employee_id)
        user = request.user
        content_type, data = Cv(employee, format_, user).get()

        if isinstance(data, BytesIO):
            return FileResponse(
                data, as_attachment=True, filename=f'cv.{format_}',
                content_type=content_type)
        if content_type == 'text/html':
            try:
                name = uuid.uuid4().hex + '.html'
                with open(name, 'w+') as output:
                    output.write(str(data))
                return HttpResponseRedirect(file_to_drive(import_file=name))
            finally:
                os.remove(os.path.join(settings.BASE_DIR, name))
        return HttpResponse(data, content_type=content_type)

file_to_drive

from google.oauth2 import service_account
from django.conf import settings
from googleapiclient.discovery import build

SCOPES = [
    'https://www.googleapis.com/auth/documents',
    'https://www.googleapis.com/auth/drive',
]
ACCOUNT_FILE = os.path.join(settings.BASE_DIR, 'cv-base-gapi.json')
def file_to_drive(import_file=None):
    credentials=service_account.Credentials.from_service_account_file(ACCOUNT_FILE, scopes=SCOPES)
    service = build('drive', 'v3', credentials=credentials)
    file_metadata = {
        'name': 'My Report',
        'mimeType': 'application/vnd.google-apps.spreadsheet'
    }
    media = MediaFileUpload(import_file,
                            mimetype='text/html',
                            resumable=True)
    file = service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id').execute()
    print('File ID: %s' % file.get('id'))
    return (f"https://docs.google.com/document/d/{file.get('id')}/edit")

它似乎有效,但有一个不清楚的时刻。

首先,我没有在 Google 磁盘上看到保存的文件,但是 print('File ID: %s' % file.get('id')) 行给了我新文档的 ID。

第二个最重要的问题是我收到一条关于缺少查看文档的权限的消息。

  • 您想从 HTML 数据创建新的 Google 文档。
  • 您想让用户查看和编辑创建的 Google 文档。
  • 您正在为这种情况使用服务帐户。
  • 您想使用 google-api-python-client 和 Python.
  • 来实现此目的

我能理解你上面的情况。你的问题有2个问题。

  1. 您想知道在您的 Google 驱动器上无法看到创建的 Google 文档的原因。
  2. 您想知道打开创建的文档需要权限的原因。

如果我的理解是正确的,这个答案怎么样?请将此视为几个答案之一。

问题:

作为你这两个问题的主要原因,我认为服务帐户的使用是原因。该服务帐户不同于您自己的 Google 帐户。因此,例如,当文件由服务帐户创建时,该文件将在服务帐户的 Google 驱动器中创建。这样,您的 Google 驱动器上就看不到该文件了。我认为这就是问题 1 的答案。而且,在服务帐户的 Google 驱动器中创建的文件不能直接访问,因为只有服务帐户可以访问它。我认为这就是您问题 2 的答案。

解决方案:

为了在您的 Google 驱动器上看到创建的 Google 文档并让用户查看和编辑创建的 Google 文档,我建议将权限添加到使用权限创建的 Google 文档:在云端硬盘 API 中创建。当这反映到您的脚本中时,它会变成如下。

修改后的脚本:

请按如下方式修改您的脚本。

从:
def file_to_drive(import_file=None):
    credentials=service_account.Credentials.from_service_account_file(ACCOUNT_FILE, scopes=SCOPES)
    service = build('drive', 'v3', credentials=credentials)
    file_metadata = {
        'name': 'My Report',
        'mimeType': 'application/vnd.google-apps.spreadsheet'
    }
    media = MediaFileUpload(import_file,
                            mimetype='text/html',
                            resumable=True)
    file = service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id').execute()
    print('File ID: %s' % file.get('id'))
    return (f"https://docs.google.com/document/d/{file.get('id')}/edit")
到:
def file_to_drive(import_file=None):
    credentials=service_account.Credentials.from_service_account_file(ACCOUNT_FILE, scopes=SCOPES)
    service = build('drive', 'v3', credentials=credentials)
    file_metadata = {
        'name': 'My Report',
        'mimeType': 'application/vnd.google-apps.document'  # Modified
    }
    media = MediaFileUpload(import_file,
                            mimetype='text/html',
                            resumable=True)
    file = service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id').execute()
    fileId = file.get('id')  # Added
    print('File ID: %s' % fileId)

    # --- I added below script.
    permission1 = {
        'type': 'user',
        'role': 'writer',
        'emailAddress': '###',  # Please set your email of Google account.
    }
    service.permissions().create(fileId=fileId, body=permission1).execute()
    permission2 = {
        'type': 'anyone',
        'role': 'writer',
    }
    service.permissions().create(fileId=fileId, body=permission2).execute()
    # ---

    return (f"https://docs.google.com/document/d/{file.get('id')}/edit")
  • 本次修改,在创建GoogleDocument后,为创建的Document添加权限。
    • permission1,您的帐户被添加为作者。这样,您就可以在 Google 驱动器中看到创建的文档。请在此处设置您的 Google 帐户的电子邮件。
    • permission2,为了让用户查看和编辑创建的Document,权限添加为anyone类型。这是一个测试用例。 如果要将用户的邮箱添加为权限,请设置为permission1

注:

  • 如果要创建Google文件,请将application/vnd.google-apps.spreadsheet修改为application/vnd.google-apps.document。但在你的情况下,当 text/html 转换为 application/vnd.google-apps.spreadsheet 时,它会自动转换为 application/vnd.google-apps.document。因为text/html只能转换成application/vnd.google-apps.document.

参考:

如果我误解了您的问题并且这不是您想要的方向,我深表歉意。