简体   繁体   中英

Trouble deploying Flask app using Elastic Beanstalk

I'm trying to deploy my flask app using Elastic Beanstalk. When I deploy it and go to the site, I get an "Internal Server Error". I checked the logs and found I was getting "ModuleNotFoundErrors" but only with local imports. My file structure looks like this:

backend
   -alembic
   -libs
   -common
   -models
     -user.py
   -__init__.py
   -application.py
   -requirements.txt

So for example, I would get a `ModuleNotFoundError: No module named 'backend.models.user'. Just out of curiosity, I changed the imports from the absolute path to relative path ('backend.models.user' -> '.models.user'). Now I'm getting the errors below:

[Sun Oct 04 15:26:10.439457 2020] [:error] [pid 23422] [remote 127.0.0.1:12] mod_wsgi (pid=23422): Target WSGI script '/opt/python/current/app/application.py' cannot be loaded as Python module.
[Sun Oct 04 15:26:10.439510 2020] [:error] [pid 23422] [remote 127.0.0.1:12] mod_wsgi (pid=23422): Exception occurred processing WSGI script '/opt/python/current/app/application.py'.
[Sun Oct 04 15:26:10.439610 2020] [:error] [pid 23422] [remote 127.0.0.1:12] Traceback (most recent call last):
[Sun Oct 04 15:26:10.439639 2020] [:error] [pid 23422] [remote 127.0.0.1:12]   File "/opt/python/current/app/application.py", line 1, in <module>
[Sun Oct 04 15:26:10.439644 2020] [:error] [pid 23422] [remote 127.0.0.1:12]     from .config import BaseConfig
[Sun Oct 04 15:26:10.439659 2020] [:error] [pid 23422] [remote 127.0.0.1:12] ImportError: attempted relative import with no known parent package
[Sun Oct 04 15:26:11.442790 2020] [:error] [pid 23422] [remote 127.0.0.1:2576] mod_wsgi (pid=23422): Target WSGI script '/opt/python/current/app/application.py' cannot be loaded as Python module.
[Sun Oct 04 15:26:11.442839 2020] [:error] [pid 23422] [remote 127.0.0.1:2576] mod_wsgi (pid=23422): Exception occurred processing WSGI script '/opt/python/current/app/application.py'.

I also tried taking out all imports to modules within the same directory while keeping the imports of built-in or installed modules. When I did that, the deployment worked with no Internal Server Error. Any ideas on why I'm having these issues?

1st Update I went back and followed the AWS tutorial ( https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-flask.html ), but added a models package with test.py file to see if I could replicate my issue with the AWS code. In this example the file structure looks like this:

~/eb-flask/
|-- virt
|-- models
   |-- test.py
|-- application.py
`-- requirements.txt

I then redeployed the code and got the same error:

[Sun Oct 04 23:31:28.271209 2020] [:error] [pid 3349] [remote 172.31.29.168:12] mod_wsgi (pid=3349): Target WSGI script '/opt/python/current/app/application.py' cannot be loaded as Python module.
[Sun Oct 04 23:31:28.271276 2020] [:error] [pid 3349] [remote 172.31.29.168:12] mod_wsgi (pid=3349): Exception occurred processing WSGI script '/opt/python/current/app/application.py'.
[Sun Oct 04 23:31:28.271361 2020] [:error] [pid 3349] [remote 172.31.29.168:12] Traceback (most recent call last):
[Sun Oct 04 23:31:28.271386 2020] [:error] [pid 3349] [remote 172.31.29.168:12]   File "/opt/python/current/app/application.py", line 2, in <module>
[Sun Oct 04 23:31:28.271391 2020] [:error] [pid 3349] [remote 172.31.29.168:12]     from .models import test
[Sun Oct 04 23:31:28.271406 2020] [:error] [pid 3349] [remote 172.31.29.168:12] ImportError: attempted relative import with no known parent package

2nd Update Below is the code for my Flask app's application.py (minus a couple of the endpoints) and then the code for the AWS Flask tutorial's application.py (with the additional import I put in.) As stated in the first update, both my app and the tutorial's app had the same local import error.

My application.py

from flask import Flask, render_template
from flask import request, session
from flask_cors import CORS
import os
from .common.api import api
from .journal_blueprint import journal_blueprint
from .manuscript_blueprint import manuscript_blueprint
from .user_blueprint import user_blueprint
from .models.decorators import requires_login
from .models.user import User
from .models.manuscript import Manuscript
from .models.journal import Journal
from .config_file import BaseConfig

application=Flask(__name__)

application.secret_key = BaseConfig.SECRET_KEY
application.config['SQLALCHEMY_DATABASE_URI'] = os.environ["DATABASE_URL"]

CORS(application)

application.register_blueprint(journal_blueprint, url_prefix='/journal')
application.register_blueprint(user_blueprint, url_prefix='/user')
application.register_blueprint(manuscript_blueprint, url_prefix='/manuscript')
application.register_blueprint(api, url_prefix="/api")


@application.route('/')
def home_template():
    return render_template('index.html')


@application.route('/login')
def login_template():
    return render_template('user/login.html')


@application.route('/register')
def register_template():
    return render_template('user/register.html')


@application.route('/search')
@requires_login
def search():
    return render_template("search.html")


if __name__ == '__main__':
    # application.run(debug=True)
    application.run()

AWS Tutorial application.py

from flask import Flask
from .models import test

# print a nice greeting.
def say_hello(username = "World"):
    return '<p>Hello %s!</p>\n' % username

# some bits of text for the page.
header_text = '''
    <html>\n<head> <title>EB Flask Test</title> </head>\n<body>'''
instructions = '''
    <p><em>Hint</em>: This is a RESTful web service! Append a username
    to the URL (for example: <code>/Thelonious</code>) to say hello to
    someone specific.</p>\n'''
home_link = '<p><a href="/">Back</a></p>\n'
footer_text = '</body>\n</html>'

# EB looks for an 'application' callable by default.
application = Flask(__name__)

# add a rule for the index page.
application.add_url_rule('/', 'index', (lambda: header_text +
    say_hello() + instructions + footer_text))

# add a rule when the page is accessed with a name appended to the site
# URL.
application.add_url_rule('/<username>', 'hello', (lambda username:
    header_text + say_hello(username) + home_link + footer_text))

# run the app.
if __name__ == "__main__":
    # Setting debug to True enables debug output. This line should be
    # removed before deploying a production app.
    application.debug = True
    application.run()

In your second attempt you are missing __init__.py . Thus it should be:

~/eb-flask/
|-- virt
|-- models
   |-- __init__.py
   |-- test.py
|-- application.py
`-- requirements.txt

And in your application it should be (no dot):

from models import test

Regarding my initial issue, I figured out how to fix it but I'm not sure how the issue came about in the first place. By looking at the sys.path , I found that the path that my app was looking for the modules in was starting at a directory one level higher than my application folder. Not sure why that happened. Maybe I did some weird copy/paste thing when I started the project 6 months ago. Anyway, when I would work on my machine, I would have to call my imports like this from .models.users import User instead of from models.user import User . When I deployed the code on AWS, I'm assuming the path was set correctly at the application directory level, so my relative imports were incorrect. I had to change all my imports to fix this issue. My IDE still highlights the imports as errors, but the code runs fine now, so I'll have to figure out why that is happening.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM