我是一名新手 Python 爱好者程序员,他正在尝试为我的学生自动化一些词汇测试。除了与电子邮件列表共享之外,以下代码中的所有内容均有效。我知道一个事实,即驱动器 ID 与我通过测试手动检查过的表单 ID 相同。我可以使用
FORM_ID
在脚本中添加所有问题,但由于某种原因我无法使用相同的 FORM_ID
设置权限。我总是收到以下错误。我也曾尝试使用创建 Google 项目的同一封电子邮件进行身份验证,但我遇到了同样的错误,因此我认为这与身份验证电子邮件的 Google 云端硬盘权限无关。我在这个错误上花了很多时间,请帮忙。
An error occurred: <HttpError 404 when requesting https://www.googleapis.com/drive/v3/files/FORM_ID/permissions?alt=json returned "File not found: FORM_ID.". Details: "[{'message': 'File not found: FORM_ID.', 'domain': 'global', 'reason': 'notFound', 'location': 'fileId', 'locationType': 'parameter'}]">
完整代码
from __future__ import print_function
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from googleapiclient.discovery import build
import time
def share_form_with_emails(service_account_file, form_id, emails):
SCOPES_DRIVE = ["https://www.googleapis.com/auth/drive"]
credentials = service_account.Credentials.from_service_account_file(service_account_file, scopes=SCOPES_DRIVE)
drive_service = build('drive', 'v3', credentials=credentials)
def share_form(attempt):
if attempt > 2:
print("Failed to share the form after 5 attempts.")
return
try:
for email in emails:
user_permission = {
'type': 'user',
'role': 'reader', # sufficient to submit and view the form
'emailAddress': email
}
drive_service.permissions().create(fileId=form_id, body=user_permission).execute()
print(f'Successfully shared form with {len(emails)} email addresses.')
except HttpError as error:
print(f'An error occurred: {error}')
if "File not found" in str(error):
print(f"Attempt {attempt}: Retrying in {2 ** attempt} seconds...")
time.sleep(2 ** attempt)
share_form(attempt + 1)
else:
return None
share_form(attempt=1)
def __main__():
import pandas as pd
from apiclient import discovery
from httplib2 import Http
from oauth2client import client, file, tools
EMAILS = ['[email protected]']
SCOPES = "https://www.googleapis.com/auth/forms.body"
DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1"
SERVICE_ACCOUNT_FILE = r'service_account_keys.json'
store = file.Storage('token.json')
creds = None
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets(r'credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
form_service = discovery.build('forms', 'v1', http=creds.authorize(
Http()), discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False)
file_name = r'output.xlsx'
dfs = pd.read_excel(file_name, sheet_name=None)
for df in dfs:
if df == 'U2W2' or df == 'U2W3': # TODO: Update this each time to avoid duplicates
print(f"Setting up Spelling Test: {df}")
name_title = f"Spelling Test: {df}"
class_name = 'Green Bears'
# TODO: Figure out how to share this automatically with list of emails or something
NEW_FORM = {
"info": {
"title": name_title,
"documentTitle": name_title,
}
}
result = form_service.forms().create(body=NEW_FORM).execute() # Create the new spelling test form
FORM_ID = result['formId']
print("FORM_ID", FORM_ID)
share_form_with_emails(SERVICE_ACCOUNT_FILE, FORM_ID, EMAILS) # Share the newly created forms
NEW_FORM_EDITED_INFO = {
"requests": [
{
"updateFormInfo": {
"info": {
"title": name_title,
"description": f"Type the correct word for the given definition. Good luck, {class_name}!",
},
"updateMask": "*",
}
}
]
}
NEW_FORM_EDITED_SETTINGS = {
"requests": [
{
"updateSettings": {
"settings": {
"quizSettings": {
"isQuiz": True
}
},
"updateMask": "*",
}
}
]
}
print(f"-- Setting up Form Info: {df}")
form_service.forms().batchUpdate(formId=result["formId"], body=NEW_FORM_EDITED_INFO).execute() # Update form info
print(f"-- Setting up Form Settings: {df}")
form_service.forms().batchUpdate(formId=result["formId"], body=NEW_FORM_EDITED_SETTINGS).execute() # Update form settings
# Add definition questions
for index, row in dfs[df].iterrows(): # Iterate over each row as each row is a spelling test question
print(f"---- Adding question {index + 1} / 20")
NEW_QUESTION = {
"requests": [{
"createItem": {
"item": {
"title": f"𝐃𝐞𝐟𝐢𝐧𝐢𝐭𝐢𝐨𝐧: {dfs[df]['DEFINITION'][index]}",
"questionItem": {
"question": {
"required": False, # Students don't have to answer any of the questions
"textQuestion": { # Create text question
"paragraph": False # False means short text
},
"grading": {
"pointValue": 1,
"correctAnswers": {
"answers": [
{
"value": dfs[df]['WORD'][index].lower()
},
{
"value": dfs[df]['WORD'][index].upper()
},
{
"value": dfs[df]['WORD'][index].title()
}
]
}
}
}
},
},
"location": {
"index": index
}
}
}]
}
question_setting = form_service.forms().batchUpdate(formId=result["formId"], body=NEW_QUESTION).execute() # Add the question
# Add paragraph questions
for i in range(5):
print(f"---- Adding sentence question {i + 1} / 5")
NEW_QUESTION_SENTENCE = {
"requests": [{
"createItem": {
"item": {
"title": "Create an original sentence using any of the above vocabulary words.",
"questionItem": {
"question": {
"required": False, # Students don't have to answer any of the questions
"textQuestion": { # Create text question
"paragraph": True # False means short text
},
"grading": {
"pointValue": 1,
}
}
},
},
"location": {
"index": i + 20
}
}
}]
}
question_setting = form_service.forms().batchUpdate(formId=result["formId"], body=NEW_QUESTION_SENTENCE).execute() # Add the question
print("\n\n ~~~~~ FINISHED ~~~~~ \n\n")
__main__()