Gmail附件上传至Google Drive代码报403权限不足与NameError问题咨询
问题1:403权限不足错误修复
- 权限范围配置错误:当前Drive API使用的scope是
https://www.googleapis.com/auth/drive.metadata.readonly,仅允许读取Drive元数据,没有文件创建、写入权限,替换为https://www.googleapis.com/auth/drive.file(仅允许操作当前应用创建的文件,权限更安全)或https://www.googleapis.com/auth/drive(全量Drive权限)。 - 鉴权变量存储错误:Drive鉴权逻辑中,新授权得到的凭证变量是
creds1,但写入token_drive.pickle的是旧的空值creds,导致后续加载的凭证无效,需要统一变量名,同时补充代码中缺失的Credentials_drive.json前导单引号,修正后Drive鉴权部分代码如下:
# 修正后的Drive鉴权部分 SCOPES_DRIVE = ['https://www.googleapis.com/auth/drive.file'] creds_drive = None if os.path.exists('token_drive.pickle'): with open('token_drive.pickle', 'rb') as token_drive: creds_drive = pickle.load(token_drive) if not creds_drive or not creds_drive.valid: if creds_drive and creds_drive.expired and creds_drive.refresh_token: creds_drive.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'Credentials_drive.json', SCOPES_DRIVE) creds_drive = flow.run_local_server(port=0) with open('token_drive.pickle', 'wb') as token_drive: pickle.dump(creds_drive, token_drive) # 统一使用creds_drive初始化service,移出if分支 drive_service = build('drive', 'v3', credentials=creds_drive)
- 文件夹创建逻辑缺失:原
create_folder_in_drive函数仅定义了元数据,没有执行创建请求也没有返回文件夹ID,会导致后续上传文件时父目录参数无效,修正后函数代码如下:
def create_folder_in_drive(service,folder_name,parent_folder=[]): file_metadata ={ 'name': folder_name, 'parents': parent_folder, 'mimeType':'application/vnd.google-apps.folder' } # 执行创建请求并返回文件夹ID folder = service.files().create(body=file_metadata, fields='id').execute() return folder.get('id')
问题2:NameError: name 'service' is not defined修复
该错误是因为Gmail的service初始化代码写在了if not creds or not creds.valid的分支内,当本地已有有效token.pickle时,该分支不会执行,service变量就不会被定义。需要将Gmail service初始化代码移出if分支,修正后Gmail鉴权部分代码如下:
# 修正后的Gmail鉴权部分 SCOPES_GMAIL = ['https://www.googleapis.com/auth/gmail.readonly'] creds_gmail = None if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds_gmail = pickle.load(token) if not creds_gmail or not creds_gmail.valid: if creds_gmail and creds_gmail.expired and creds_gmail.refresh_token: creds_gmail.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'Credentials.json', SCOPES_GMAIL) creds_gmail = flow.run_local_server(port=0) with open('token.pickle', 'wb') as token: pickle.dump(creds_gmail, token) # 移出if分支,无论是否走授权逻辑都初始化service service = build('gmail', 'v1', credentials=creds_gmail)
注意:修改完成后请删除本地旧的
token.pickle和token_drive.pickle文件,重新运行代码完成授权,新的权限配置才会生效。
内容的提问来源于stack exchange,提问作者user14178341
相关产品推荐
相关产品推荐

