Flask_Mail和Flask_Restplus的循环依赖关系

时间:2020-05-10 21:34:08

标签: python rest email flask flask-restful

我目前正在为一个简单的Web应用程序构建Flask后端。我要实现以下功能:用户可以注册->用户收到确认邮件->用户在确认其帐户后登录。我已经完成了部分注册和登录,但是现在我在“发送确认电子邮件”部分中苦苦挣扎。 我使用API​​的flask_restplus和flask_mail发送电子邮件。我的问题是,通过使用这些软件包,我最终会循环导入,而实际上我不知道如何解决它。让我详细说明:

这是我app.py的一部分:

import sys
from flask_cors import CORS
from flask import Flask, Blueprint
from flask_mail import Mail
from api import blueprint as api

app = Flask(__name__)
app.config.update(dict(
    DEBUG=False,
    MAIL_DEFAULT_SENDER='*******@gmail.com',
    MAIL_SERVER='smtp.gmail.com',
    MAIL_PORT=465,
    MAIL_USE_TLS=False,
    MAIL_USE_SSL=True,
    MAIL_USERNAME='******@gmail.com',
    MAIL_PASSWORD='**************',
    SECRET_KEY_EMAIL_VERIFY='******',
    SECURITY_PASSWORD_SALT_EMAIL_VERIFY='*********',
    JWT_SECRET_KEY='*************',
    JWT_BLACKLIST_ENABLED=True,
    JWT_BLACKLIST_TOKEN_CHECKS=['access', 'refresh'],
    JSONIFY_PRETTYPRINT_REGULAR=True
))
CORS(app)
cors = CORS(app, resources={
    r"/*": {
        "origins": "*"
    }
})
app.register_blueprint(api, url_prefix='/api/1')
mail = Mail(app)
jwt = JWTManager(app)

您可以在app.py中看到,我正在将API导入为蓝图。在此蓝图中,我将不同的名称空间导入api / init .py

from flask_restplus import Api
from flask import Blueprint
from .user.endpoints.student import ns as ns_student
from .user.endpoints.teacher import ns as ns_teacher
from .auth.authentication import ns as ns_auth

blueprint = Blueprint('api', __name__)
api = Api(blueprint)
api.add_namespace(ns_student)
api.add_namespace(ns_teacher)
api.add_namespace(ns_auth)

现在在命名空间中,我有一个注册用户的方法,在该方法的结尾,我想发送确认电子邮件。这意味着我必须从我的app.py中导入send_mail()方法,因为flask_mail中的邮件依赖于App,因此app.py中的mail = Mail(app)也是如此。见下文:

----
from app import send_email, generate_confirmation_token
----
token = generate_confirmation_token(student.email)
confirm_url = 'http://localhost:4200/confirm/' + token
html = render_template('confirmationEmail.html', confirm_url=confirm_url)
subject = "Please confirm your email"
send_email(student.email, subject, html)
print('A confirmation email has been sent via email.', 'success')
return None, 201
-------
app.py
-------
def send_email(to, subject, template):
    msg = Message(
        subject,
        recipients=[to],
        html=template,
        sender=app.config['MAIL_DEFAULT_SENDER']
    )
    mail.send(msg)

为简化导入圈,如下所示:app.py导入Api-> Api导入命名空间->从app.py导入的命名空间

老实说,我不知道如何解决此问题或如何打破循环。我真的不明白,为什么flask-mail中的Mail必须依赖于要初始化的App。我猜是因为配置原因,但是我不能独立于应用程序加载电子邮件配置吗? flask_mail文档也不是很详细。无论如何,我以何种方式构建应用程序似乎并不重要。我似乎无法正常工作,因为我总是最终从应用程序导入(mail或app.py中使用mail发送电子邮件的方法)。

运行我的应用程序时,我最终遇到导入错误:

  File "***\webapp/app.py", line 8, in <module>
    from api import blueprint as api
  File "***\webapp\api\__init__.py", line 3, in <module>
    from .user.endpoints.student import ns as ns_student
  File "***\webapp\api\user\endpoints\student.py", line 4, in <module>
    from api import api
ImportError: cannot import name 'api' from 'api' (***\webapp\api\__init__.py)

我只用from ... import ....替换了部分import ...就可以在我的机器上运行该应用程序,但是与我一起工作的朋友无法运行它,并且无论他使用哪种导入方式,都遇到了与我之前完全相同的导入错误。 我对此并不陌生,可以通过正确地构建我的应用程序来快速解决该问题。但是我要把头撞在墙上。真令人沮丧。因此,非常感谢所有帮助!!!

0 个答案:

没有答案