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

Flask应用导入mail报错ImportError问题求助

Flask邮件发送导入失败问题解决

项目结构

└── my-project
    │
    ├── __init__.py
    ├── app.py
    │
    ├── api
    │   ├── __init__.py
    │   ├── list.py
    │   └── routes.py
    │
    └── mail
        ├── __init__.py
        └── email.py

所有__init__.py文件均为空。

问题重现

在api/list.py中调用sendemail()函数:

<other imports>

from mail.email import sendemail

class FeedApi(Resource):
    
    def get(self, start: int, limit: int) -> Response:
                output = Lists.objects().aggregate(

<... query stuff ...>

                lists = json.loads(json_util.dumps(output))

                sendemail()

                return lists

email.py初始代码可正常运行:

from flask_mail import Message

def sendemail():
    print('\n\n trying to import this function ')

但修改email.py为以下代码时,触发ImportError: cannot import name 'mail' from 'app':

from flask_mail import Message

def sendemail():
    from app import mail
    print('\n\n trying to import this function ')

若将from app import mail放在函数外,会触发循环导入错误。

问题原因

查看app.py代码可知,mail是在get_flask_app函数内部定义的局部变量,并未暴露在app模块的全局作用域中,因此无法通过from app import mail导入。

解决方案

方案1:将mail提升为模块全局变量

修改app.py,把mail的定义移到函数外,在函数内完成初始化:

# flask packages
from flask import Flask, current_app, request, app
from flask_cors import CORS
from flask_restful import Api
from flask_mongoengine import MongoEngine
from flask_jwt_extended import JWTManager
from flask_cors import CORS
from flask_mail import Mail

# 全局声明mail变量
mail = None

# local packages
from api.routes import create_routes

# external packages
import os

# default mongodb configuration
default_config = {'MONGODB_SETTINGS': {
                    'db': '.... ',
                    'host': '....',
                    'port': 27017,
                    'username': '...',
                    'password': '...',
                    'authentication_source': '...'},
                    'JWT_SECRET_KEY': '...'}


def get_flask_app(config: dict = None) -> app.Flask:
    global mail  # 声明使用全局变量
    # init flask
    Flask.logger_name = "listlogger"
    flask_app = Flask(__name__)
    CORS(flask_app)
    

    # configure app
    flask_app.config.from_pyfile('config.py')

    config = default_config if config is None else config
    flask_app.config.update(config)

    # load config variables
    if 'MONGODB_URI' in os.environ:
        flask_app.config['MONGODB_SETTINGS'] = {'host': os.environ['MONGODB_URI'],
                                                'retryWrites': False}
    if 'JWT_SECRET_KEY' in os.environ:
        flask_app.config['JWT_SECRET_KEY'] = os.environ['JWT_SECRET_KEY']
    
    mail = Mail(app=flask_app)  # 初始化全局mail实例

    # init api and routes
    api = Api(app=flask_app)
    create_routes(api=api)


    # init mongoengine
    db = MongoEngine(app=flask_app)

    # init jwt manager
    jwt = JWTManager(app=flask_app)

    return flask_app

if __name__ == '__main__':
    # Main entry point when run in stand-alone mode.
    app = get_flask_app()
    app.run(debug=True, host='0.0.0.0', port=5050)

之后在email.py中即可在函数内安全导入:

from flask_mail import Message

def sendemail():
    from app import mail
    # 这里可以添加邮件发送逻辑,例如:
    # msg = Message('测试邮件', sender='your@email.com', recipients=['target@email.com'])
    # msg.body = '这是一封测试邮件'
    # mail.send(msg)
    print('\n\n trying to import this function ')

方案2:使用Flask current_app获取mail实例

无需修改app.py,直接通过current_app.extensions获取已初始化的mail实例,更符合Flask应用工厂模式的最佳实践:

from flask import current_app
from flask_mail import Message

def sendemail():
    mail = current_app.extensions['mail']
    # 后续添加邮件发送逻辑
    print('\n\n trying to import this function ')

验证

修改完成后,启动Flask应用,触发FeedApi的GET请求,确认sendemail()函数可正常执行且无导入错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:24:41