I've been trying to deploy my Flask app to Heroku for over a day, watching/reading several tutorials, and digging through all the stackoverflow questions i could find and still haven't found a solution for my issue. When i deploy my app, I get the error "gunicorn.errors.AppImportError: Failed to find attribute 'app' in 'app'." I've changed my Procfile many times to get heroku to run my app but i always get the same error.
This is how my app is structured: enter image description here
My Procfile includes this statement:
web: gunicorn app:app --preload
I am thinking my issues could be how im creating my app, but could not find a solution. My main app file looks like this:
from venv import create
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os.path import join, dirname, realpath
from flask_login import LoginManager
db = SQLAlchemy()
def create_app():
app = Flask(__name__, static_folder='static')
app.debug = True
app.config['SECRET_KEY'] = 'abcde12568901fghij'
#app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite3'
app.config['SQLALCHEMY_DATABASE_URI'] = '[removed for privacy]'
app.config['UPLOAD_DIRECTORY'] = join(dirname(realpath(__file__)), 'uploads/')
app.config['MAX_CONTENT_LENGTH'] = 16*1024*1024 #16mb
app.config['ALLOWED_EXTENSIONS'] = ['.jpg','.jpeg','.png','.gif','.mp4']
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
from models import User
@login_manager.user_loader
def load_user(user_id):
# since the user_id is just the primary key of our user table, use it in the query for the user
return User.query.get(int(user_id))
from auth import auth
app.register_blueprint(auth)
from views import main
app.register_blueprint(main)
return app
if __name__ == '__main__':
db.create_all(app=create_app())
Screenshot of full logs: enter image description here
Any help would be greatly appreciated, thanks all!
CodePudding user response:
app:app
tells Gunicorn to look for a variable called app
in your app.py
file (strictly speaking, in your app
module), but you don't have a variable with that name.
Instead, you have a function create_app()
that returns your app object. Gunicorn allows you to use that directly:
The variable name can also be a function call. In that case the name will be imported from the module, then called to get the application object. This is commonly referred to as the "application factory" pattern.
Update your Procfile
accordingly:
web: gunicorn 'app:create_app()' --preload
CodePudding user response:
Do you have another file in your root directory that is creating the app or is the code above the file that you run to run the app? This will normally just be a Python file with the name of your project, and this will have something like app = create_app()
.
Then your Procfile
needs to look for the app in that file.
For example if that file was called mainApp.py
you would then use
web: gunicorn mainApp:app --preload