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

使用PyDrive跨GDrive账号上传文件遇400 Bad Request错误求助

解决PyDrive跨Google Drive账号上传时的400 Bad Request错误

问题场景

你用PyDrive实现跨账号文件迁移,下载操作正常,但上传时触发400错误:

pydrive.files.ApiRequestError: <HttpError 400 when requesting https://www.googleapis.com/upload/drive/v2/files?alt=json&uploadType=resumable returned "Bad Request">

你的代码片段

ListFolder函数

def ListFolder(parent, drive1, drive2):
    filecount = 0
    filelist=[]
    file_list = drive1.ListFile({'q': "'%s' in parents and trashed=false" % parent}).GetList()
    for f in file_list:
        filecount +=1
        print("Still working %s" % filecount)
        if f['mimeType']!='application/vnd.google-apps.folder': # if regular file
            print("I've found a file - passing %s to download" % f['title'])
            download_file(drive1, f, drive2) # Download the file

download_file函数

def download_file(drive1, f, drive2):
    """This function will download a file from the source drive1 to the local hard drive, just before uploading it to the destination drive- i.e. drive2"""
    dirpath = tempfile.mkdtemp()
    print ("Downloading a file %s" % f['title'])
    filesource = drive1.CreateFile({'id': f['id']})
    filesource.GetContentFile(f['title'], f['mimeType'])
    upload_file(drive2, f)
    os.remove(f['title'])

upload_file函数

def upload_file(drive2, f):
    #Will copy files over until it detects a directory
    """This function accepts the destination drive, filetitle (which has previously been downloaded from download_file function) and the file mimetype. This function uploads the local file to the destination drive"""
    filename = f['title']
    print("file title: %s" % f['title']) #filetitle)
    file = drive2.CreateFile()
    file.SetContentFile(f['title'])
    file.Upload()

核心排查方向&修复建议

1. 上传时未指定必要的文件元数据

你的upload_file函数里,创建drive2.CreateFile()时没有传入任何元数据(比如文件标题、MIME类型),Google Drive的API可能因为缺失必填字段返回400错误。

修复代码:

def upload_file(drive2, f):
    filename = f['title']
    print("file title: %s" % filename)
    
    # 先确认本地文件存在(避免找不到文件导致的隐式错误)
    if not os.path.exists(filename):
        print(f"Error: Local file {filename} not found!")
        return
    
    # 显式指定文件元数据
    file_metadata = {
        'title': filename,
        'mimeType': f['mimeType']
    }
    file = drive2.CreateFile(file_metadata)
    file.SetContentFile(filename)
    
    # 添加详细错误捕获,获取Google返回的具体原因
    try:
        file.Upload()
        print(f"Successfully uploaded {filename}")
    except pydrive.files.ApiRequestError as e:
        print(f"Upload failed with details: {e.content}")

2. 临时目录与文件路径不匹配

你在download_file里创建了临时目录dirpath,但下载文件时直接用了f['title']作为路径(文件会存在当前工作目录,而非临时目录),如果后续操作清理了当前目录或者文件路径不对,会导致上传时找不到文件,间接触发400错误。

修复代码:

def download_file(drive1, f, drive2):
    """Download file to temp dir then upload"""
    dirpath = tempfile.mkdtemp()
    # 拼接完整的临时文件路径
    local_file_path = os.path.join(dirpath, f['title'])
    print(f"Downloading file to {local_file_path}")
    
    filesource = drive1.CreateFile({'id': f['id']})
    filesource.GetContentFile(local_file_path, f['mimeType'])
    
    # 传入完整路径给上传函数
    upload_file(drive2, f, local_file_path)
    
    # 清理临时文件和目录
    os.remove(local_file_path)
    os.rmdir(dirpath)

# 对应修改upload_file函数接收路径参数
def upload_file(drive2, f, local_file_path):
    filename = f['title']
    print("file title: %s" % filename)
    
    if not os.path.exists(local_file_path):
        print(f"Error: Local file {local_file_path} not found!")
        return
    
    file_metadata = {
        'title': filename,
        'mimeType': f['mimeType']
    }
    file = drive2.CreateFile(file_metadata)
    file.SetContentFile(local_file_path)
    
    try:
        file.Upload()
        print(f"Successfully uploaded {filename}")
    except pydrive.files.ApiRequestError as e:
        print(f"Upload failed with details: {e.content}")

3. 目标账号的授权范围不足

检查drive2对应的授权凭证(client_secrets.json),确保授权范围包含https://www.googleapis.com/auth/drive或至少https://www.googleapis.com/auth/drive.file。如果授权范围太窄(比如只读权限),上传操作会被拒绝返回400。

4. 获取更详细的错误信息

Google Drive API返回的"Bad Request"只是通用错误,你可以在捕获异常时打印e.content(如上面代码所示),这会显示具体的错误原因(比如"Missing required field: title"、"Invalid mime type"等),能快速定位问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:10:55