Google API 文件权限使用 python
Google API file permissions using python
我需要为我网站的不同用户做一些功能,以自动将 html 文件上传到 google 磁盘并打开它们以在 google 文档中查看和编辑。为此,我创建了一个文档,将其传递到 google 磁盘并使用创建文档的 ID 在 google docs.
中打开它
要访问 api,我使用从服务 Google 帐户获取的 json 文件。我尝试使用 owner 和 view 权限执行我的代码,但结果是一样的。
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个问题。
- 您想知道在您的 Google 驱动器上无法看到创建的 Google 文档的原因。
- 您想知道打开创建的文档需要权限的原因。
如果我的理解是正确的,这个答案怎么样?请将此视为几个答案之一。
问题:
作为你这两个问题的主要原因,我认为服务帐户的使用是原因。该服务帐户不同于您自己的 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
.
参考:
如果我误解了您的问题并且这不是您想要的方向,我深表歉意。
我需要为我网站的不同用户做一些功能,以自动将 html 文件上传到 google 磁盘并打开它们以在 google 文档中查看和编辑。为此,我创建了一个文档,将其传递到 google 磁盘并使用创建文档的 ID 在 google docs.
中打开它
要访问 api,我使用从服务 Google 帐户获取的 json 文件。我尝试使用 owner 和 view 权限执行我的代码,但结果是一样的。
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个问题。
- 您想知道在您的 Google 驱动器上无法看到创建的 Google 文档的原因。
- 您想知道打开创建的文档需要权限的原因。
如果我的理解是正确的,这个答案怎么样?请将此视为几个答案之一。
问题:
作为你这两个问题的主要原因,我认为服务帐户的使用是原因。该服务帐户不同于您自己的 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
.
参考:
如果我误解了您的问题并且这不是您想要的方向,我深表歉意。