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

添加FastAPI后Python视频生成脚本遇openai模块找不到问题求助

问题

我写了一个能生成视频的Python脚本,依赖openai、gTTS、moviepy等库。为了把这个功能通过REST API对外提供,我引入了FastAPI框架,但添加后启动服务时出现ModuleNotFoundError: No module named 'openai'错误。PyCharm里代码没有报错提示,删掉FastAPI相关代码后脚本能正常运行,试过多种办法都没解决。

相关代码

import openai
from fastapi import FastAPI
import re
import shutil
import urllib.request
import os  # 原代码遗漏os模块导入,此处补上

from gtts import gTTS
from moviepy.editor import *

openai.api_key = "API_KEY"
app = FastAPI()


@app.get("/generate-video")
async def generate_video():
    return generateResultVideo("")


def generateResultVideo(text):
    try:
        paragraphs = re.split(r"[,.]", text)
        initTemporaryFolders()
        generateTemporaryVideoSnapshots(paragraphs)

        result_video = concatTempSnapshots()

        return result_video
    finally:
        removeTemporaryFolders()


def initTemporaryFolders():
    # 添加exist_ok=True避免重复创建文件夹报错
    os.makedirs("audio", exist_ok=True)
    os.makedirs("images", exist_ok=True)
    os.makedirs("videos", exist_ok=True)


def removeTemporaryFolders():
    # 添加ignore_errors=True避免文件夹不存在时报错
    shutil.rmtree("videos", ignore_errors=True)
    shutil.rmtree("images", ignore_errors=True)
    shutil.rmtree("audio", ignore_errors=True)


def generateTemporaryVideoSnapshots(paragraphs):
    i = 1
    for para in paragraphs[:-1]:
        response = openai.Image.create(
            prompt=para.strip(),
            n=1,
            size="1024x1024"
        )
        print("Generate New AI Image From Paragraph...")
        image_url = response['data'][0]['url']
        urllib.request.urlretrieve(image_url, f"images/image{i}.jpg")
        print("The Generated Image Saved in Images Folder!")

        # Create gTTS instance and save to a file
        tts = gTTS(text=para, lang='en', slow=False)
        tts.save(f"audio/voiceover{i}.mp3")
        print("The Paragraph Converted into VoiceOver & Saved in Audio Folder!")

        # Load the audio file using moviepy
        print("Extract voiceover and get duration...")
        audio_clip = AudioFileClip(f"audio/voiceover{i}.mp3")
        audio_duration = audio_clip.duration

        # Load the image file using moviepy
        print("Extract Image Clip and Set Duration...")
        image_clip = ImageClip(f"images/image{i}.jpg").set_duration(audio_duration)

        # Use moviepy to create a text clip from the text
        print("Customize The Text Clip...")
        text_clip = TextClip(para,
                             fontsize=65,
                             color="white",
                             size=(1024, 1024),
                             method="caption",
                             align="South"
                             )
        text_clip = text_clip.set_pos('center').set_duration(audio_duration)

        print("Concatenate Audio, Image, Text to Create Final Clip...")
        clip = image_clip.set_audio(audio_clip)
        video = CompositeVideoClip([clip, text_clip])

        # Save the final video to a file
        video = video.write_videofile(f"videos/video{i}.mp4", fps=24)
        print(f"The Video{i} Has Been Created Successfully!")
        i += 1


def concatTempSnapshots():
    clips = []
    l_files = os.listdir("videos")
    for file in l_files:
        clip = VideoFileClip(f"videos/{file}")
        clips.append(clip)

    print("Concatenate All The Clips to Create a Final Video...")
    final_video = concatenate_videoclips(clips, method="compose")
    final_video = final_video.write_videofile("final_video.mp4")
    print("The Final Video Has Been Created Successfully!")

    return final_video

异常信息

INFO:     Will watch for changes in these directories: ['/Users/admin/Video-AI-Startup/ShortsGeneratorV2']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [40071] using WatchFiles
Process SpawnProcess-1:
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.10/3.10.11/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/usr/local/Cellar/python@3.10/3.10.11/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.10/site-packages/uvicorn/_subprocess.py", line 76, in subprocess_started
    target(sockets=sockets)
  File "/usr/local/lib/python3.10/site-packages/uvicorn/server.py", line 60, in run
    return asyncio.run(self.serve(sockets=sockets))
  File "/usr/local/Cellar/python@3.10/3.10.11/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "uvloop/loop.pyx", line 1517, in uvloop.loop.Loop.run_until_complete
  File "/usr/local/lib/python3.10/site-packages/uvicorn/server.py", line 67, in serve
    config.load()
  File "/usr/local/lib/python3.10/site-packages/uvicorn/config.py", line 477, in load
    self.loaded_app = import_from_string(self.app)
  File "/usr/local/lib/python3.10/site-packages/uvicorn/importer.py", line 24, in import_from_string
    raise exc from None
  File "/usr/local/lib/python3.10/site-packages/uvicorn/importer.py", line 21, in import_from_string
    module = importlib.import_module(module_str)
  File "/usr/local/Cellar/python@3.10/3.10.11/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/Users/admin/Video-AI-Startup/ShortsGeneratorV2/./main.py", line 1, in <module>
    import openai
ModuleNotFoundError: No module named 'openai'
解决方案

1. 对齐Uvicorn和PyCharm的Python环境

从错误日志看,Uvicorn用的是/usr/local/Cellar/python@3.10/3.10.11这个环境,而PyCharm可能用了另一个虚拟环境或全局环境:

  • 在PyCharm终端执行which python,拿到当前项目的Python路径。
  • 用这个完整路径启动Uvicorn,比如:/path/to/your/python -m uvicorn main:app --reload。

2. 关闭自动重载排查问题

Uvicorn的自动重载会启动子进程,容易出现环境不一致的情况,先尝试不带--reload启动:

uvicorn main:app

如果能正常运行,说明是自动重载的环境问题,后续可以用--reload-dir指定监听目录,或者确保子进程继承正确的环境变量。

3. 重新安装所有依赖

不管用的是虚拟环境还是全局环境,重新安装一遍依赖:

pip install openai fastapi gTTS moviepy uvicorn

如果用了虚拟环境,先激活环境再执行命令。

4. 检查PyCharm解释器配置

  • 打开PyCharm的File > Settings > Project: [你的项目名] > Python Interpreter。
  • 确认当前解释器已安装openai、fastapi等所有依赖包。
  • 若未安装,点击+号手动添加缺失的包,或者切换到正确的解释器。

5. 修复代码中的小问题

原代码遗漏了os模块的导入,且创建/删除文件夹时未做异常处理,已在上面的代码示例中修正,避免后续运行时出现额外报错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:16:58