使用python的Google API文件权限

使用python的Google API文件权限,python,django,google-api,google-drive-api,google-api-python-client,Python,Django,Google Api,Google Drive Api,Google Api Python Client,我需要为我的网站的不同用户做一些功能,以便自动将html文件上传到谷歌磁盘,并在谷歌文档中打开它们进行查看和编辑。为此,我创建了一个文档,将其传递到google磁盘,并使用创建文档的id在google文档中打开它。 为了访问api,我使用了一个来自服务Google帐户的json文件。我尝试使用所有者和查看权限执行代码,但结果是一样的 class CvView(AuthorizedMixin, View): """Here I check if the file format is htm

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

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)
文件到驱动器

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文档
  • 在这种情况下,您正在使用服务帐户
  • 您希望通过使用带有python的google api python客户端来实现这一点
我可以理解你的上述情况。你的问题有两个问题

  • 您想知道创建的Google文档在您的Google驱动器上看不到的原因
  • 您想知道打开创建的文档需要权限的原因
  • 如果我的理解是正确的,那么这个答案呢?请把这看作是几个答案中的一个

    问题: 作为你这两个问题的主要原因,我认为使用服务帐户是原因。该服务帐户与您自己的Google帐户不同。例如,当文件由服务帐户创建时,该文件将在服务帐户的Google驱动器中创建。这样,在你的谷歌硬盘上就看不到文件了。我想这就是你第一个问题的答案。而且,在服务帐户的Google驱动器中创建的文件无法直接访问,因为只有服务帐户才能访问它。我想这就是你第二个问题的答案

    解决方案: 为了在您的Google驱动器上查看已创建的Google文档,并让用户查看和编辑已创建的Google文档,我建议使用permissions:create In Drive API向已创建的Google文档添加权限。当这反映到脚本中时,它将变成如下所示

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

    发件人: 致:
    • 在此修改中,在创建Google文档后,权限将添加到创建的文档中。
      • permission1
        ,您的帐户被添加为写入者。这样,您就可以在谷歌硬盘上看到创建的文档。请在此处设置您的Google帐户电子邮件
      • permission2
        中,为了使用户能够查看和编辑创建的文档,将权限添加为
        any
        类型。这是一个测试用例如果要将用户的电子邮件添加为权限,请将其设置为
        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
    参考:

    如果我误解了你的问题,而这不是你想要的方向,我很抱歉。

    谢谢你如此详细的回答。我仍然无法检查它的性能,一旦检查,我立即将结果写在这里。@Jekson感谢您的回复。如果这不是你想要的结果,我很抱歉。很好的解决方案,很有效。非常感谢您的支持help@Jekson感谢您的回复和测试。我很高兴你的问题解决了。也谢谢你。
    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")