JasTonAChair JasTonAChair - 10 days ago 6
Python Question

ImportError - deploy Falcon app to AWS Elastic Beanstalk

I'm having an ImportError after deploying to Elastic Beanstalk. We're running Falcon to make an API. I have successfully used the EB CLI to initialise an app, create the environment and deploy my code. We use Python 2.7 (for now).

The AWS EB site for the app/environment says everything went well, but when I send a request to the api, the logs show this error:

[Wed Nov 30 06:02:25.555507 2016] [:error] [pid 29352] [remote 127.0.0.1:56624] Traceback (most recent call last):
[Wed Nov 30 06:02:25.555524 2016] [:error] [pid 29352] [remote 127.0.0.1:56624] File "/opt/python/current/app/api/app.py", line 12, in <module>
[Wed Nov 30 06:02:25.555549 2016] [:error] [pid 29352] [remote 127.0.0.1:56624] from middlewares import require_json
[Wed Nov 30 06:02:25.555566 2016] [:error] [pid 29352] [remote 127.0.0.1:56624] ImportError: No module named middlewares
[Wed Nov 30 06:02:26.558411 2016] [:error] [pid 29352] [remote 127.0.0.1:60720] mod_wsgi (pid=29352): Target WSGI script '/opt/python/current/app/api/app.py' cannot be loaded as Python module.


Locally my imports work just fine. The relevant parts of the api look like this:

-api/
-__init__.py #import app
-app.py
-middlewares/
-__init__.py #import require_json
-require_json.py


Line 12 of my app.py file:

from middlewares import require_json


But the logs are consistently saying this is an ImportError. Any thoughts on what's happened here? I'm baffled.

As for the
__init__.py
files importing modules; this is a legacy code base and I'm not sure what the implications are for changing that just yet, other than the tests will fail.

EDIT

This morning I've tried commenting out those import lines, but that just gives me errors on the next import:

[Wed Nov 30 21:52:00.699228 2016] [:error] [pid 11254] [remote 172.31.8.163:37352] Traceback (most recent call last):
[Wed Nov 30 21:52:00.699245 2016] [:error] [pid 11254] [remote 172.31.8.163:37352] File "/opt/python/current/app/api/app.py", line 15, in <module>
[Wed Nov 30 21:52:00.699270 2016] [:error] [pid 11254] [remote 172.31.8.163:37352] import resources
[Wed Nov 30 21:52:00.699288 2016] [:error] [pid 11254] [remote 172.31.8.163:37352] ImportError: No module named resources


I've also done what's recommended in this article.

import sys
sys.path.insert(0, '/opt/python/current/app')

Answer

With the way your code appears to be structured, you shouldn't be pointing WSGIScriptAlias directive of Apache at your app.py file directly.

What you need to do is create a separate WSGI script file to use with WSGIScriptAlias and in it have:

from api.app import application

You will also need to configure mod_wsgi so that the parent directory of the api directory is in the Python module search path. You can do in the mod_wsgi configuration, or do it in this new WSGI script file.

Presuming you had added the WSGI script file as app.wsgi in the same directory as api appears as a subdirectory, it could include:

import os
import sys

sys.path.insert(0, os.path.dirname(__file__))

from api.app import application