404 on any route for Flask app deployed to Elastic Beanstalk - flask

I am trying to host a Flask app that implements a REST API using Flask-RESTful on Elastic Beanstalk through the eb cli. I have successfully deployed my application and I am not getting any error messages on my events log. I can successfully ssh into the instances and run the script to prepopulate my database and everything. But whenever I try to access any routes I keep getting a 404 error.
I initially assumed that it was because it wasn't finding my WSGIPath, so I changed the file name to application.py and updated the EBS software configuration to point to that file. I have also updated all instances of app to application in the codebase based on AWS documentation. Still nothing. Does anyone have any idea what could be wrong?
This is my application.py:
from flask import Flask
from config import Config
CONFIG = Config()
# AWS Elastic Beanstalk expects an `application` variable.
application = Flask(__name__)
if __name__ == "__main__":
# Importing these here to avoid issue with circular imports
from endpoints.v1.exports import exports_api
from endpoints.v1.imports import imports_api
application.register_blueprint(exports_api, url_prefix="/api/v1")
application.register_blueprint(imports_api, url_prefix="/api/v1")
application.run(debug=CONFIG.DEBUG)
Here is where the application.py file lies in the folder structure:
- project root
- ...
- application.py
- ...

Just realized what was going on. I was trying to register the blueprints inside of the if __name__ == "__main__": block. But since the application.py file is not run directly by Elastic Beanstalk, it was never reaching those lines and so the endpoints I was trying to hit didn't exist.
I had to refactor my code so I could move it outside of that block and avoid issues with circular imports, but now it's all working as it should.

Related

How to fix Django "ModuleNotFoundError: No module named 'application'" on AWS?

I am trying to redeploy a Django web application on AWS. My elastic beanstalk environment has been red a couple of times. When I ran eb logs on the cli, I am getting a "ModuleNotFoundError: No module named 'application' error". I think this has got to do with my wsgi configuration.
I have deployed this web app on AWS before. I messed up when I tried deploying a new version then decided to just start over. Here is my wsgi.py configuration:
```import os
from django.core.wsgi import get_wsgi_application
from django.contrib.staticfiles.handlers import StaticFilesHandler
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
application = StaticFilesHandler(get_wsgi_application())```
When I deploy the app, it's giving me a 502: Bad gateway error. Let me know if you would like more info on the issue. Any pointers would be greatly appreciated.
By default, Elastic Beanstalk looks for a file named application.py to start your application. Because this doesn't exist in the Django project that you've created, you need to make some adjustments to your application's environment. You also must set environment variables so that your application's modules can be loaded.
follow these instructions:
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-django.html#python-django-configure-for-eb
I got this error because in an older version the django.config looked like this:
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: ebdjango/wsgi.py
and now it should look like this:
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: ebdjango.wsgi:application
I faced this issue as well. In my case I was getting a 502 nginx error after deploying to AWS EB using eb deploy and my environment had a red flag.
My AWS EB was using Amazon Linux 2 AMI, everything was set correctly BUT after lot of tries and errors I realized my .ebextensions folder was named .ebtextensions.
I wish EB or django would have indicated on its logs that my folder was nanmed incorrectly.
I got this error and also spent days trying to solve it. The problem is from the django.config file.
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: <app name>.wsgi:application
The first value (app name) in the WSGIPath option needs to be the directory that contains the wsgi.py file
Check the WSGIPath in elastic beanstalk configuration (Software Category) in the AWS console too.
It should be
<app_name>.wsgi:application

Python Flask Web application not able to deploy on Heroku using Waitress server

I am trying to deploy my Flask application on Heroku PaaS Cloud Service. It, however, works on localhost with no errors. I am using git for version control and pushing to Heroku. Initially, as a web server, I used 'gunicorn' but later came to know it is useful for UNIX distributions. So I resorted my webserver to 'waitress'. I saw some of the posts and tried everything in the Procfile for hosting to Heroku. My Procfile reads like: web: waitress-serve --port=$PORT app:app. I also know that the first app in this line is the package and the second app is the name of the instance best to my knowledge. I even changed from app to myapp, website and I have all the packages including these mentioned are in my VS code editor. But my application is not getting deployed onto Heroku and it gives Application Error. Now when I check the logs using heroku logs --tail it gives me the following error as in the screenshot. Any help would be highly obliged. I am trying this for 23 hours. Heroku Logs
The Procfile looks correct but the problem could be that the file (app.py) and the variable (app) have the same name.
I suggest the following approach, in app.py
# define Flask app
def create_app():
try:
web_app = Flask(__name__)
logging.info('Starting up..')
return web_app
except Exception as e:
logging.exception(e)
# retrieve port
def get_port():
return int(os.environ.get("PORT", 5000))
# start Flask app
if __name__ == '__main__':
web_app = create_app()
web_app.run(debug=False, port=get_port(), host='0.0.0.0')
The application can be launched from the Procfile with
web: waitress-serve --port=$PORT --call 'app:create_app'

Setting up flask backend in AWS amplify

I want to setup flask backend in aws amplify, my frontend is react js.
Here is the folder structure:
root:
-flask-backend
--flask_app.py
--modules
-react-frontend
Note that my flask backend has app.py which is the core file and is supposed to backend listening to requests and then modules have some of the dependencies (imports) required to run app.py
The flow is like this:
react front end requests and fetches data from flask backend and accordingly the pages open. how to set it up? I referred to this medium article but nowhere it's shown how to configure backend based on your path (currently I have put my files in a git repository) so that both frontend and backend run parallely.

How to fix internal server error in Flask application using elastic beanstalk and aws

When I run my flask application locally, I can connect to MySQL RDS just fine. However, when I try to deploy the app using Elastic Beanstalk, I get a "500 Internal Server Error".
I do not know if this helps or not, but when I use a local sqlite file, my application works as intended both when ran locally and when deployed with Elastic Beanstalk.
I did try and work along with this page, but I did not notice any difference when I included the environment properties. https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-rds.html#python-rds-create
Here is my __init__.py file. I just comment out whichever database URI I do not wish to use when testing.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
application = Flask(__name__)
application.config['SECRET_KEY'] = 'c4633b5a978d282104dbc44c32c9486'
application.config['SQLALCHEMY_DATABASE_URI'] =
'mysql+pymysql://<username>:<password>#garbagero.cuz5hqf0nh5m.us-east-
2.rds.amazonaws.com/ebdb'
#application.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(application)
bcrypt = Bcrypt(application)
login_manager = LoginManager(application)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
from garbageRO import routes
EDIT: I finally figured out that I accidentally left 1 package out of my requirements.txt file. I thought I had already double checked this before posting but apparently I did not.
I do recommend that you debug your application using the verbose mode of Flask and SQLAlchemy, so you can better know whats going on, with this level or detail i can only suggest something to check like the permissions/IAM on AWS, to check if your ElasticBeanstalk can really access the RDS, im assuming the ELB/applcation use a set of credentials, and you tested locally with another credentials, right?
About the "verbose mode", try setting the SQLALCHEMY_ECHO to True: http://flask-sqlalchemy.pocoo.org/2.3/config/
There's also this option ive not tested: https://github.com/pallets/flask-sqlalchemy/pull/208/files?short_path=fd40cf2
And on the Flask app you can set debug to True also.
Another option, is to debug if you can connect on the RDS directly with a client on the machine/container, or a least if a telnet is working.

404 Errors with flask-restless and Amazon Elastic Beanstalk

So I have a Python Flask application. With it I'm using flask-restless and flask-sqlalchemy to provide an api. When running on my localhost the api works just fine, however when trying to access the api on the Amazon server(an ec2 instance created with Elastic Beanstalk and eb) the app throws 404 errors.
config.py:
if 'RDS_HOSTNAME' in os.environ:
SQLALCHEMY_DATABASE_URI = 'mysql://' + os.environ['RDS_USERNAME'] + ':' + os.environ['RDS_PASSWORD'] +'#' + os.environ['RDS_HOSTNAME'] + '/' + os.environ['RDS_DB_NAME']
else:
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(_basedir, 'inspections.db')
So I'm using sqlite on my local machine and mysql(RDS) for the server. As a note everything having to do with the database is working. My app is rendering the content and performing queries.
Does anyone know what can be causing this?
Turns out I was running the wrong file on my configuration file. Since my app was setup like a module, I needed to have EC2 run the run.py file and not app/init.py.