You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Gmail API创建草稿时遇GOOGLE_APPLICATION_CREDENTIALS未找到错误求助

Gmail API 创建草稿时触发 DefaultCredentialsError 问题解决

我在使用Gmail API创建邮件草稿时,反复触发DefaultCredentialsError错误,提示无法自动确定凭据,需要设置GOOGLE_APPLICATION_CREDENTIALS环境变量或显式创建凭据。我已经下载了对应的JSON凭据文件、按要求创建凭据并添加测试邮箱,且能完成登录授权流程,但加入官方示例的创建草稿代码后依然报错。

报错信息

ERROR:
Traceback (most recent call last):
File "C:\Users\carlo\PycharmProjects\pythonProject3\quickstart.py", line 61, in 
gmail_create_draft()
File "C:\Users\carlo\PycharmProjects\pythonProject3\quickstart.py", line 25, in gmail_create_draft
creds, _ = google.auth.default()
File "C:\Users\carlo\PycharmProjects\pythonProject3\venv\lib\site-packages\google\auth_default.py", line 616, in default
raise exceptions.DefaultCredentialsError(_HELP_MESSAGE)
google.auth.exceptions.DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or explicitly create credentials and re-run the application. For more information, please see <a href="https://cloud.google.com/docs/authentication/getting-started" rel="nofollow noreferrer">https://cloud.google.com/docs/authentication/getting-started</a>

Process finished with exit code 1

完整代码

from __future__ import print_function
import os.path
import base64
from email.message import EmailMessage
import google.auth
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']

def gmail_create_draft():
    """Create and insert a draft email.
       Print the returned draft's message and id.
       Returns: Draft object, including draft id and message meta data.

      Load pre-authorized user credentials from the environment.
      TODO(developer) - See https://developers.google.com/identity
      for guides on implementing OAuth2 for the application.
    """
    creds, _ = google.auth.default()

    try:
        # create gmail api client
        service = build('gmail', 'v1', credentials=creds)

        message = EmailMessage()

        message.set_content('This is automated draft mail')

        message['To'] = 'carlosmedina239@gmail.com'
        message['From'] = 'selenytesting123@gmail.com'
        message['Subject'] = 'Automated draft'

        # encoded message
        encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()

        create_message = {
            'message': {
                'raw': encoded_message
            }
        }
        # pylint: disable=E1101
        draft = service.users().drafts().create(userId="me",
                                                body=create_message).execute()

        print(F'Draft id: {draft["id"]}\nDraft message: {draft["message"]}')

    except HttpError as error:
        print(F'An error occurred: {error}')
        draft = None

    return draft


if __name__ == '__main__':
    gmail_create_draft()



def main():
    """Shows basic usage of the Gmail API.
    Lists the user's Gmail labels.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
    # You don't have to care about anything on top of this comment

    try:
        # Call the Gmail API
        service = build('gmail', 'v1', credentials=creds)
        results = service.users().labels().list(userId='me').execute()
        labels = results.get('labels', [])

        if not labels:
            print('No labels found.')
            return
        print('Labels:')
        for label in labels:
            print(label['name'])

    except HttpError as error:
        # TODO(developer) - Handle errors from gmail API.
        print(f'An error occurred: {error}')


if __name__ == '__main__':
    main()

问题原因及解决方案

核心问题

  1. 认证方式不匹配:gmail_create_draft函数使用google.auth.default()(服务账号认证逻辑),但你的代码中main函数采用的是OAuth2授权码流程(桌面应用适用),两种认证方式不兼容。
  2. 权限范围不足:当前SCOPES仅设置了gmail.readonly,创建草稿需要gmail.compose权限,权限不足会导致后续操作失败。

修复步骤

  1. 统一认证逻辑:将gmail_create_draft的认证部分替换为和main一致的OAuth2凭据加载逻辑,复用已有的token.json或重新获取授权:

    def gmail_create_draft():
        """Create and insert a draft email.
           Print the returned draft's message and id.
           Returns: Draft object, including draft id and message meta data.
        """
        creds = None
        # 加载已保存的token.json
        if os.path.exists('token.json'):
            creds = Credentials.from_authorized_user_file('token.json', SCOPES)
        # 无有效凭据时重新授权
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    'credentials.json', SCOPES)
                creds = flow.run_local_server(port=0)
            # 保存凭据
            with open('token.json', 'w') as token:
                token.write(creds.to_json())
    
        try:
            # create gmail api client
            service = build('gmail', 'v1', credentials=creds)
    
            message = EmailMessage()
    
            message.set_content('This is automated draft mail')
    
            message['To'] = 'carlosmedina239@gmail.com'
            message['From'] = 'selenytesting123@gmail.com'
            message['Subject'] = 'Automated draft'
    
            # encoded message
            encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
    
            create_message = {
                'message': {
                    'raw': encoded_message
                }
            }
            # pylint: disable=E1101
            draft = service.users().drafts().create(userId="me",
                                                    body=create_message).execute()
    
            print(F'Draft id: {draft["id"]}\nDraft message: {draft["message"]}')
    
        except HttpError as error:
            print(F'An error occurred: {error}')
            draft = None
    
        return draft
    
  2. 更新权限范围:修改SCOPES为包含创建草稿的权限,修改后删除原有token.json并重新运行授权:

    SCOPES = ['https://www.googleapis.com/auth/gmail.compose']
    
  3. 调整入口函数:保留gmail_create_draft的入口,注释或删除main函数的入口,避免运行冲突。

内容的提问来源于stack exchange,提问作者CarlosM239

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:58:03