Flask 和 Elastic Beanstalk-AssertionError:视图函数映射正在覆盖现有端点函数

Posted

技术标签:

【中文标题】Flask 和 Elastic Beanstalk-AssertionError:视图函数映射正在覆盖现有端点函数【英文标题】:Flask and Elastic Beanstalk- AssertionError: View function mapping is overwriting an existing endpoint function 【发布时间】:2021-08-08 01:36:47 【问题描述】:

我在 Stack Overflow 上阅读了很多关于此错误的问题,但没有一个解决方案适用于我。

上下文

我的应用程序在本地运行时运行没有任何错误。但是,在将我的应用程序部署到 AWS Elastic Beanstalk 时,我收到以下错误,当我运行 eb logs 时看到。

[Tue May 18 18:36:13.563576 2021] [:error] [pid 3428] [remote 127.0.0.1:0] mod_wsgi (pid=3428): Target WSGI script '/opt/python/current/app/app/routes.py' cannot be loaded as Python module.
[Tue May 18 18:36:13.563640 2021] [:error] [pid 3428] [remote 127.0.0.1:0] mod_wsgi (pid=3428): Exception occurred processing WSGI script '/opt/python/current/app/app/routes.py'.
[Tue May 18 18:36:13.564335 2021] [:error] [pid 3428] [remote 127.0.0.1:0] Traceback (most recent call last):
[Tue May 18 18:36:13.564370 2021] [:error] [pid 3428] [remote 127.0.0.1:0]   File "/opt/python/current/app/app/routes.py", line 16, in <module>
[Tue May 18 18:36:13.564376 2021] [:error] [pid 3428] [remote 127.0.0.1:0]     @application.route('/api/login', methods=['POST'], endpoint='login')
[Tue May 18 18:36:13.564383 2021] [:error] [pid 3428] [remote 127.0.0.1:0]   File "/opt/python/run/venv/local/lib/python3.6/site-packages/flask/app.py", line 1315, in decorator
[Tue May 18 18:36:13.564387 2021] [:error] [pid 3428] [remote 127.0.0.1:0]     self.add_url_rule(rule, endpoint, f, **options)
[Tue May 18 18:36:13.564392 2021] [:error] [pid 3428] [remote 127.0.0.1:0]   File "/opt/python/run/venv/local/lib/python3.6/site-packages/flask/app.py", line 98, in wrapper_func
[Tue May 18 18:36:13.564396 2021] [:error] [pid 3428] [remote 127.0.0.1:0]     return f(self, *args, **kwargs)
[Tue May 18 18:36:13.564402 2021] [:error] [pid 3428] [remote 127.0.0.1:0]   File "/opt/python/run/venv/local/lib/python3.6/site-packages/flask/app.py", line 1284, in add_url_rule
[Tue May 18 18:36:13.564415 2021] [:error] [pid 3428] [remote 127.0.0.1:0]     "existing endpoint function: %s" % endpoint
[Tue May 18 18:36:13.564432 2021] [:error] [pid 3428] [remote 127.0.0.1:0] AssertionError: View function mapping is overwriting an existing endpoint function: login

以下是我的routes.py,在本地运行时不会出错,但部署到Elastic Beanstalk时会出错:

from flask import request, jsonify
from app.application import application
from app.extensions import db
from app.models import User, Subreddit, Keyword
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from sqlalchemy.exc import IntegrityError
import re
from functools import wraps

@application.route('/')

@application.route('/index')

@application.route('/api/login', methods=['POST'], endpoint='login')
def login():
    # Parse the incoming request
    incoming = request.get_json()
    email = incoming["email"]
    password = incoming["password"]

    # Check the database to see if the user exists. If successful, the route sends
    # a token back to the action, which stores the token into the redux state (reducer).
    user = User.query.filter_by(email=email).one()
    if user and user.check_password(password):
        # Generate a token for the user to send back to the frontend for authentication purposes.
        s = Serializer(application.config['SECRET_KEY'], expires_in=36000)
        token = s.dumps(
            'id': user.id,
            'email': user.email,
        ).decode('utf-8')

        # Return the user to the frontend in order to populate the loggedInUser redux state.
        return jsonify(token=token, user=user.serialize())
    elif user and not user.check_password(password):
        return jsonify(error=True), 401

    # If the user doesn't exist
    return jsonify(error=True), 404

//...

问题

我该如何解决这个错误:AssertionError: View function mapping is overwriting an existing endpoint function: login

我的尝试

我已经确认没有其他装饰函数可以共享 带有login() 的名称。 我尝试将login() 重命名为随机名称,例如login2(),以确认没有命名冲突。错误消息仍然使用随机名称生成。 我使用 .route() 参数endpoint 明确指定 视图。 我已经确认没有相同的函数名称 在我所有的路线中。 我已尝试确保没有循环导入。以下是每个文件的导入:

我的项目目录/结构:

> app/
>> __init__.py
>> application.py
>> extensions.py
>> models.py
>> routes.py
> migrations/
> venv/
> .flaskenv
> app.db
> config.py
> requirements.txt
> script.py

我的__init__.py

from app import routes

我的application.py

from flask import Flask
from config import Config


application = Flask(__name__)

application.config.from_object(Config)

我的extensions.py

from app.application import application
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from apscheduler.schedulers.background import BackgroundScheduler

db = SQLAlchemy(application)

migrate = Migrate(application, db, render_as_batch=True)

scheduler = BackgroundScheduler(daemon=True) 

我的routes.py

from app.application import application
from app.extensions import db
from app.models import User, Subreddit, Keyword

我的models.py

from app.extensions import db

完整项目:https://github.com/boxcarcoder/Reddalerts

我还尝试删除 extensions.py 中的 scheduler,以防它导致我的 api 路由的多个实例化(尽管这不太可能,但我对导致此问题的潜在想法不足)。

可能的解决方案?

我看到提到使用wraps 的解决方案,但是我该如何包装 route() 装饰器?使用wraps的目的是什么?当我在本地和 Elastic Beanstalk 之外运行我的应用程序时,我的代码没有问题。

【问题讨论】:

据我所知,端点参数在这里是多余的。如果你只是删除它会发生什么? 删除端点参数后没有变化。我也认为这可能是多余的,但在 Stack Overflow 上看到了一个解决方案,说明它可能会有所帮助。但是,这不适用于我的情况。 这是整个代码吗?您是否查看过包含的文件,以及目录结构中可能存在的其他文件?看到您的路径包含应用程序/应用程序,我不会对您不知不觉地导入其他作为模块徘徊的文件感到惊讶。 我已更新我的帖子以显示我包含的文件。我相信我没有重复的函数名称。 【参考方案1】:

问题在于 Elastic Beanstalk 如何配置其环境。当我应该考虑整个代码库时,我只考虑了我的应用程序的代码。以下是我的目录结构,包括 Elastic Beanstalk 所需的目录。

> app/
>> .ebextensions/
>>> reddalerts.config
>> .elasticbeanstalk/
>>> config.yml
>> __init__.py
>> application.py
>> extensions.py
>> models.py
>> routes.py
> migrations/
> venv/
> .flaskenv
> app.db
> config.py
> requirements.txt
> script.py

.ebextensions 目录中,我有一个配置文件reddalerts.config 来指定Elastic Beanstalk 的WSGIPath:

option_settings:
  "aws:elasticbeanstalk:container:python":
    WSGIPath: app/routes.py

按照这个问题/解决方案:How to deploy structured Flask app on AWS elastic beanstalk,我认为 WSGIPath 应该指向我的视图文件 (app/routes.py),但这不适合我的情况。它应该指向应用程序模块 (application.py)。

将我的reddalerts.config 更改为以下内容后,问题解决了。

option_settings:
  "aws:elasticbeanstalk:container:python":
    WSGIPath: application.py

【讨论】:

以上是关于Flask 和 Elastic Beanstalk-AssertionError:视图函数映射正在覆盖现有端点函数的主要内容,如果未能解决你的问题,请参考以下文章

使用 Elastic Beanstalk 设置 Flask 数据库迁移

在 Elastic BeanStalk 上部署 Flask 应用程序时遇到问题

Flask 应用程序 - 部署到 AWS Elastic Beanstalk 时出错

带有 SSL 的 Elastic Beanstalk 上的 Flask 提供 403 Forbidden

使用 Elastic Beanstalk 部署 Flask 应用程序时遇到问题

上传 Flask 应用程序时出现 AWS Elastic Beanstalk 错误