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

FastAPI后台启动子进程报错:'function' object has no attribute 'submit'

解决AttributeError: 'function' object has no attribute 'submit'问题

错误根源

你把loop.run_in_executor的参数顺序搞反了:

  • run_in_executor的第一个参数是执行器对象(可选,留空则用默认线程池),第二个参数才是要在执行器中运行的函数,后续是该函数的参数。
  • 你错误地将subprocess.run作为第一个参数传入,导致asyncio把它当成执行器调用submit方法,但subprocess.run是普通函数,没有这个方法,因此触发报错。

另外还有两个潜在问题:

  1. subprocess.run本身会阻塞直到子进程完成,返回的是CompletedProcess对象,不是Popen对象,调用process.communicate()会报错。
  2. 未捕获子进程输出,无法正确获取执行日志或错误信息。

修正步骤

  1. 调整run_in_executor的参数顺序,将执行器参数设为None(使用默认线程池),再传入subprocess.run和它的参数。
  2. 给subprocess.run添加capture_output=True和text=True参数,方便捕获并读取输出内容。
  3. 删除错误的process.communicate()调用,直接通过process.stdout和process.stderr获取输出。

修正后的完整代码

import asyncio
import os
import subprocess
from fastapi import APIRouter

router = APIRouter()
temp_dir = "./temp"  # 根据实际情况修改路径

@router.get("/testdo")
async def do():
    asyncio.create_task(editing())
    return {"message": "Video processing started in the background!"}

async def editing():
    recordingFile = os.path.join(temp_dir, "test.mp4")
    webFile = os.path.join(temp_dir, "keeptest.mp4")
    ffmpeg_change_bitrate = ['ffmpeg', '-i', recordingFile, '-b:v', '5M', '-y', webFile]
    
    loop = asyncio.get_event_loop()
    # 修正run_in_executor参数顺序,添加捕获输出的参数
    process = await loop.run_in_executor(
        None,
        subprocess.run,
        ffmpeg_change_bitrate,
        capture_output=True,
        text=True
    )
    
    if process.returncode == 0:
        print('Completed Editing')
        print(f"FFmpeg output: {process.stdout}")
    else:
        print(f'Error occurred: {process.stderr}')
    
    print('It will take more x seconds')
    await asyncio.sleep(20)  # 模拟上传S3的处理时间
    print('It took x seconds')
    print('Completed Editing, it took x minutes')

额外说明

  • 如果需要自定义线程池,可以提前创建ThreadPoolExecutor实例,传入run_in_executor的第一个参数,例如:
    from concurrent.futures import ThreadPoolExecutor
    
    executor = ThreadPoolExecutor(max_workers=2)
    process = await loop.run_in_executor(executor, subprocess.run, ...)
    
  • 确保temp_dir路径存在,且ffmpeg命令能在系统PATH中找到,或者使用完整路径调用(如'C:/ffmpeg/bin/ffmpeg.exe')。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 12:50:19