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

Google Drive API报错:'Credentials'对象无'request'属性

解决Google Drive API上传时的AttributeError问题

问题背景

为GUI添加Google Drive同步功能,支持用户上传重要文件夹至云端备份,遵循官方API实现时触发错误,相关问题搜索无匹配案例。

错误回溯

File "D:\Programming Projects\Projects-Manager\main.py", line 96, in <module>
    id_ = upload_zip(zip_created_path, cred_path)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "D:\Programming Projects\Projects-Manager\google_drive\drive.py", line 51, in upload_zip
    fields='id').execute()
                 ^^^^^^^^^

  File "D:\Programming Projects\Projects-Manager\env\Lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^

  File "D:\Programming Projects\Projects-Manager\env\Lib\site-packages\googleapiclient\http.py", line 902, in execute
    _, body = self.next_chunk(http=http, num_retries=num_retries)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "D:\Programming Projects\Projects-Manager\env\Lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^

  File "D:\Programming Projects\Projects-Manager\env\Lib\site-packages\googleapiclient\http.py", line 1007, in next_chunk
    resp, content = _retry_request(
                    ^^^^^^^^^^^^^^^

  File "D:\Programming Projects\Projects-Manager\env\Lib\site-packages\googleapiclient\http.py", line 191, in _retry_request
    resp, content = http.request(uri, method, *args, **kwargs)
                    ^^^^^^^^^^^^

AttributeError: 'Credentials' object has no attribute 'request'

引发错误的代码

import os.path
from pathlib import Path

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
from googleapiclient.http import MediaFileUpload


SCOPES = ["https://www.googleapis.com/auth/drive.file", "https://www.googleapis.com/auth/drive",
          "https://www.googleapis.com/auth/drive.metadata", "https://www.googleapis.com/auth/drive.readonly",
          "https://www.googleapis.com/auth/drive.metadata.readonly"]

drive_folder = "google_drive"

def get_token(cred_path):
    cred_path = Path(cred_path)
    cred = None
    token_file_path = Path(Path.cwd(), drive_folder, "token.json")

    if token_file_path.exists():
        cred = Credentials.from_authorized_user_file(str(token_file_path), SCOPES)

    if not cred or not cred.valid:
        if cred and cred.expired and cred.refresh_token:
            cred.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                str(cred_path), SCOPES
            )
            cred = flow.run_local_server(port=0)
        with open(token_file_path, 'w') as file:
            file.write(cred.to_json())
        return cred

    return cred

def upload_zip(zip_created_path, credential_path):
    cred = get_token(credential_path)
    zip_name = os.path.basename(zip_created_path)
    try:
        service = build("drive", 'v3', cred)

        file_metadata = {"name": zip_name, "mimeType": "application/zip"}
        media = MediaFileUpload(zip_created_path, mimetype="application/zip", resumable=True)

        file = service.files().create(body=file_metadata, media_body=media,
                                      fields='id').execute()
        os.remove(zip_created_path)
        return file.get('id')

    except HttpError as error:
        print(F'An error occurred: {error}')
        return

解决方案

错误根源是调用build方法时参数传递错误:直接将Credentials对象作为位置参数传入,而build的第三个位置参数是http(要求HTTP客户端对象),导致后续代码尝试调用Credentials的request方法触发异常。

核心修正

将build调用中的位置参数改为关键字参数credentials=cred:

service = build("drive", 'v3', credentials=cred)

可选逻辑优化

调整get_token函数的返回逻辑,确保无论分支走向都统一返回凭据:

def get_token(cred_path):
    cred_path = Path(cred_path)
    cred = None
    token_file_path = Path(Path.cwd(), drive_folder, "token.json")

    if token_file_path.exists():
        cred = Credentials.from_authorized_user_file(str(token_file_path), SCOPES)

    if not cred or not cred.valid:
        if cred and cred.expired and cred.refresh_token:
            cred.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                str(cred_path), SCOPES
            )
            cred = flow.run_local_server(port=0)
        with open(token_file_path, 'w') as file:
            file.write(cred.to_json())
    # 统一在此返回,避免分支内return导致的逻辑混乱
    return cred

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:07:55