404 Errors with flask-restless and Amazon Elastic Beanstalk - amazon-web-services

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.

Related

When I ssh into my django ElasticBeanstalk server and try to enter the shell I get the error: The SECRET_KEY setting must not be empty

I have a ElasticBeanstalk server that is running my Django Rest Framework. The server is working properly when I make requests with Postman. However when I ssh into the server and try to enter the shell with ./manage shell_plus I receive the error:
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
On the server /opt/python/current/env contains export DJANGO_SETTINGS_MODULE="myproject.settings.production"
myproject/settings/production.py contains from myproject.settings.base import * which contains the secret_key settings. And like I said my endpoints are working properly.
I can't figure out why I am only having this issue with the server when I ssh and try to do any ./manage commands.

SQLite Flask - Can't open database file in EC2 when running db.create_all() command

I just deployed a flask app to EC2 AWS, and when trying to initialise a sqlite db by using the db.create_all(bind=['layout']) method, an error was shown
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
Here is my code
application.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://{}:{}#{}/{}".format(os.getenv('DB_USER'), os.getenv('DB_PASSWORD'), os.getenv('DB_SERVER'), os.getenv('DB_NAME'))
application.config['SQLALCHEMY_BINDS'] = {
'dashboard': "postgresql://{}:{}#{}/{}".format(os.getenv('DB_USER'), os.getenv('DB_PASSWORD'), os.getenv('DB_SERVER'), os.getenv('DB_NAME')),
'layout': "sqlite:///layout.db"
}
I ran db.create_all(bind=['layout']) in the python shell within the ec2 terminal, and I am not sure why I ran into the error, as it worked perfectly fine on my localhost.
The postgresql database works fine, and can be accessed properly, but the sqlite database, which is the one im trying to initialise with db.create_all(bind=['layout']) leads to the error shown above, and I am not sure why it isnt creating a 'layout.db' file within the current directory.
I am new to deployment, and am not sure if I did anything wrong, do let me know if I configured anything wrongly, thank you!
"sqlite:///layout.db" may end up pointing to a place where your applications doesn't have permission to write. Instead try something like
basedir = os.path.abspath(os.path.dirname(__file__))
...
layout': 'sqlite:///' + os.path.join(basedir, 'layout.db')

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'

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 on any route for Flask app deployed to Elastic Beanstalk

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.