0

I've recently been struggling to deploy my Flask app to AWS ElasticBeanstalk. I'm fairly new to web projects and AWS so every day is a struggle. Every once in a while I deploy my project to EB (I have been able to solve problems in the past) but since I restructured my app from a monolithic application.py to a more structured approach, I've been struggling. The deployment itself has succeeded but I'm faced with a 500 error. The log says:

[Wed Apr 19 00:11:57.895790 2017] [:error]  mod_wsgi (pid=15947): Target WSGI script '/opt/python/current/app/app/members/views.py' cannot be loaded as Python module.
[Wed Apr 19 00:11:57.895846 2017] [:error]  mod_wsgi (pid=15947): Exception occurred processing WSGI script '/opt/python/current/app/app/members/views.py'.
[Wed Apr 19 00:11:57.895865 2017] [:error]  Traceback (most recent call last):
[Wed Apr 19 00:11:57.895881 2017] [:error]    File "/opt/python/current/app/app/members/views.py", line 14, in 
[Wed Apr 19 00:11:57.895903 2017] [:error]      @application.route('/')
[Wed Apr 19 00:11:57.895909 2017] [:error]   File "/opt/python/run/venv/lib/python2.7/site-packages/flask/app.py", line 1080, in decorator
[Wed Apr 19 00:11:57.895921 2017] [:error]      self.add_url_rule(rule, endpoint, f, **options)
[Wed Apr 19 00:11:57.895935 2017] [:error]   File "/opt/python/run/venv/lib/python2.7/site-packages/flask/app.py", line 64, in wrapper_func
[Wed Apr 19 00:11:57.895944 2017] [:error]      return f(self, *args, **kwargs)
[Wed Apr 19 00:11:57.895949 2017] [:error]   File "/opt/python/run/venv/lib/python2.7/site-packages/flask/app.py", line 1051, in add_url_rule
[Wed Apr 19 00:11:57.895956 2017] [:error]     'existing endpoint function: %s' % endpoint)
[Wed Apr 19 00:11:57.895969 2017] [:error]  AssertionError: View function mapping is overwriting an existing endpoint function: index

My apps structure is:

myApp/
   runServer.py
   requirements.txt
   app/
      __init__.py
      config.py
      static/
      members/
         __init__.py
         views.py
         models.py
      templates/

My .ebextensions/<env-name>.config contains:

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

Lastly, my views.py file contains all my url routings. I have made sure all of the function names are the same.

Does anybody know what kind of problem/solution I'm looking at? Is there any more info I can provide to help?

Thanks!

Edit: Changing my def index() function in views.py to def newFunctionForTesting() yields AssertionError: View function mapping is overwriting an existing endpoint function: newFunctionForTesting

Edit 2: It may be similar to this one, but in that case the proposed solution was to write everything in a single file, which isn't the approach I was looking for... Maybe Blueprints could work better...

Edit 3: Here's what my app looks like.

app\__init__.py


    from flask import Flask, flash, request
    from urlparse import urlparse, urljoin
    from urllib2 import urlopen
    from flask_user import SQLAlchemyAdapter, UserManager, current_user
    import os
    from apscheduler.schedulers.background import BackgroundScheduler
    import pandas as pd
    from app.members.models import db, User, AcademicData, Role, UserRoles, Query
    from passlib.hash import bcrypt
    import datetime
    import json

    # Initializes application
    application = Flask(__name__)
    application.config.from_object("app.config.Config")

    # Initializes db
    db.init_app(application)

    # Registers user model with db
    with application.app_context():
        db.create_all() # Creates tables defined
        db_adapter = SQLAlchemyAdapter(db, User)        # Register the User model

    @application.before_first_request
    def initialize():
        scheduler = BackgroundScheduler()
        scheduler.start()
        scheduler.add_job(updateData, trigger = "interval", days = 1)



    def updateData():
        ...


    @application.context_processor
    def injectFunction():
        def getDataTable(id):
            ...

    import members.views

    # Initialize flask-user
    user_manager = UserManager(db_adapter, application,register_view_function = members.views.protected_register)

app\members\views.py


    from flask import redirect, url_for, render_template, request
    from flask_user import login_required, roles_required, views as user_views
    from app import application, SITE_ROOT
    import json
    import os
    import pandas as pd

    @application.route('/')
    def index():
        """
        Index view. Currently the dashboard.
        :return: 
        """
        return redirect(url_for('dashboard'))

    @application.route('/dashboard')
    @login_required
    def dashboard():
        ...
        return render_template('dashboard.html')

    @application.route('/table')
    @login_required
    def table():
        return render_template('table.html')

    @application.errorhandler(404)
    def not_found(error):
         return render_template('404.html')

    @application.errorhandler(500)
    @application.errorhandler(503)
    def server_error(error):
        return render_template('503.html')

    @roles_required('admin')
    def protected_register():
        return user_views.register()

Community
  • 1
  • 1
  • The error says `AssertionError: View function mapping is overwriting an existing endpoint function: index` - are you importing your `app` in `views.py` from anywhere, and (either way) are you defining another route on a function named `index` anywhere (regardless of whether the *URL* is different, what's the name of the *function*). – Sean Vieira Apr 19 '17 at 00:39
  • There is no route outside of `views.py` (at least not defined by me) and no other functions named `index` in the project. I do `from app import application` for the routing and `import app`. This last import is a temporary measure to access a shared global variable. This seems like a terrible pattern and will be changed in time. I should also mention that the application works fine locally with the built-in server. – Gabriel Siqueira Apr 19 '17 at 00:48
  • Thank you for the input and your work on Flask. I will work on the example and include one once I have it. I have checked all view functions and routes and there is no conflict. This doesn't happen when ran with the built-in server from Flask. I've made that mistake before (which gave me an error with the built-in server) but at least now it's not that kind of accidentally naming two view functions the same. Maybe this has something to do with including `views.py` at the bottom of my `__init.py__` and including `app` in `views.py`? – Gabriel Siqueira Apr 19 '17 at 17:16
  • Changing my `def index()` function in `views.py` to `def newFunctionForTesting()` yields `AssertionError: View function mapping is overwriting an existing endpoint function: newFunctionForTesting`. I also removed the `import app` from my `views.py` just in case. – Gabriel Siqueira Apr 19 '17 at 18:53

1 Answers1

0

I was following this example to set my WSGIPath, but since @davidism pointed it out, I tried a different approach and it worked. I created a app.wsgi file that basically just imports my application object and set WSGIPath: app/app.wsgi in my .ebextensions/<env-name>.config. The application now deploys and launches successfully through Elastic Beanstalk. My static resources stopped working but I had to update the mapping of the static folder under Configuration > Software Configuration > Static Files in the Elastic Beanstalk console.

Thanks!

Community
  • 1
  • 1