I have a Flask app I am trying to serve via Gunicorn.
I am using virtualenv and python3. If I activate my venv cd to my app base dir then run:
gunicorn mysite:app
I get:
Starting gunicorn
Listening at http://127.0.0.1:8000
DEBUG:mysite.settings:>>Config()
...
Failed to find application: 'mysite'
Worker exiting
Shutting down: master
Reason: App failed to load
Looking in /etc/nginx/sites-available I only have the file 'default'. In sites-enabled I have no file.
In my nginx.conf file I have:
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
App structure:
mysite #this is where I cd to and run gunicorn mysite:app
--manage.py
--/mysite
----settings.py
----__init__.py
in manage.py for mysite I have following:
logger.debug("manage.py entry point")
app = create_app(app_name)
manager = Manager(app)
if __name__ == "__main__":
manager.run()
In __init__.py file:
def create_app(object_name):
app = Flask(__name__)
#more setup here
return app
In my settings.py in the app directory
class Config(object):
logger.debug(">>Config()") #this logs OK so gunicorn is at least starting in correct directory
From inside the virtualenv if I run
print(sys.path)
I find a path to python and site-packages for this virtualenv.
From what I have read to start gunicorn it's just a matter of installing it and running gunicorn mysite:app
Running gunicorn from the parent directory of mysite I get the same failed to find application: 'mysite', App failed to load error, but don't get the DEBUG...Config() logged (as we are clearly in the wrong directory to start in). Running gunicorn from mysite/mysite (clearly wrong) I get and Exception in worker process ereor, ImportError: No module named 'mysite'.
Any clues as to how I can get gunicorn running?
You're pointing gunicorn at mysite:app, which is equivalent to from mysite import app. However, there is no app object in the top (__init__.py) level import of mysite. Tell gunicorn to call the factory.
gunicorn "mysite:create_app()"
You can pass arguments to the call as well.
gunicorn "mysite:create_app('production')"
Internally, this is equivalent to:
from mysite import create_app
app = create_app('production')
Alternatively, you can use a separate file that does the setup. In your case, you already initialized an app in manage.py.
gunicorn manage:app
Related
I am following the instructions here to deploy an app in Google App Engine. Everything works correctly.
Nevertheless, Google, by default, looks for the main folder (where app = Flask(__name__) is defined) in main.py. How could I redefine this? I would like to define this main folder as app.py.
Rename main.py to app.py
Add entrypoint: gunicorn -b :$PORT app:app to your app.yaml file. This is where you are telling Google to find the app object in a file called app
Add gunicorn to your requirements.txt file
Notes:
i. Because you're changing from main.py to app.py, you need to specify an entrypoint. GAE documentation says
If your app meets the following requirements, App Engine will start
your app with the gunicorn web server if you don't specify the
entrypoint field:
The root of your app directory contains a main.py file with a WSGI-compatible object called app.
Your app does not contain Pipfile or Pipfile.lock files.
ii. If you add an entrypoint, then you need to include gunicorn in your requirements.txt file
iii. I just tested the above configuration (the answer I gave) on a dev environment (Python 3.9 environment on Macbook using dev_appserver.py) and it works
Trying to follow best practices for a Flask app running in Heroku so I'm moving things from app.py to working with blueprints.
The current directory structure is as follows:
--root
--application
--admin_blueprint
--another_blueprint
--wsgi.py (app = create_app())
--__init__.py (this has def create_app, which handles creating my app)
--migration
--Procfile
--requirements.txt
--runtime.txt
--config.py
--manage.py
This is init.py
from flask import Flask
...
def create_app():
app = Flask(...)
...
return app
and this is wsgi.py
from application import create_app
app = create_app()
if __name__ == '__main__':
app.run(host='0.0.0.0')
I cannot for the life of me figure out how to do the Procfile correctly, this is what I previously had when I had app.py and wsgi.py in my root directory and it was working fine on Heroku:
web: gunicorn app:wsgi
I've tried some of these:
web: gunicorn application:wsgi
web: gunicorn application.wsgi
web: gunicorn --pythonpath application application:wsgi
web: gunicorn application.wsgi.py
web: gunicorn "application.wsgi.py"
web: gunicorn "application/wsgi.py"
flask run works because I've exported FLASK_APP=application.wsgi.py
Thank you.
Use application.wsgi:app
application.wsgi (the part before the colon) instructs gunicorn how to resolve the module.
and app (the part after the colon) gives the name of the WSGI application declared in the resolved module.
:app can be omitted and gunicorn defaults to looking in the module for a WSGI application with the name application.
I use gunicorn --workers 3 wsgi to run my Flask app. If I change the variable application to myapp, Gunicorn gives the error AppImportError: Failed to find application: 'wsgi'. Why am I getting this error and how do I fix it?
myproject.py:
from flask import Flask
myapp = Flask(__name__)
#myapp.route("/")
def hello():
return 'Test!'
if __name__ == "__main__":
myapp.run(host='0.0.0.0')
wsgi.py:
from myproject import myapp
if __name__ == "__main__":
myapp.run()
Gunicorn (and most WSGI servers) defaults to looking for the callable named application in whatever module you point it at. Adding an alias from myproject import myapp as application or application = myapp will let Gunicorn discover the callable again.
However, the wsgi.py file or the alias aren't needed, Gunicorn can be pointed directly at the real module and callable.
gunicorn myproject:myapp --workers 16
# equivalent to "from myproject import myapp as application"
Gunicorn can also call an app factory, optionally with arguments, to get the application object. (This briefly did not work in Gunicorn 20, but was added back in 20.0.1.)
gunicorn 'myproject.app:create_app("production")' --workers 16
# equivalent to:
# from myproject.app import create_app
# application = create_app("production")
For WSGI servers that don't support calling a factory, or for other more complicated imports, a wsgi.py file is needed to do the setup.
from myproject.app import create_app
app = create_app("production")
gunicorn wsgi:app --workers 16
If you're trying to serve an app with variable name app within server/cats.py, you can start the server on port 8000 as follows:
gunicorn server.cats:app -b 0.0.0.0:8000
my heroku app runs into application error with the following logs:
Starting process with command `gunicorn run:app`
Failed to find application: run
here is my Procfile
web: gunicorn run:flask_app
run.py file
from app import create_app, db
from app.auth.models import User
if __name__ == '__main__':
flask_app = create_app('prod')
with flask_app.app_context():
db.create_all()
if not User.query.filter_by(user_name='harry').first():
User.create_user(user='harry', email='harry#potters.com', password='secret')
flask_app.run()
Your main-method does not get executed (AFAIK) because Gunicorn is calling your script, you are not executing it as the main-file. Try moving the flask_app out of your main-method to the top of the file so Gunicorn can actually find it when importing your run.py!
I use gunicorn --workers 3 wsgi to run my Flask app. If I change the variable application to myapp, Gunicorn gives the error AppImportError: Failed to find application: 'wsgi'. Why am I getting this error and how do I fix it?
myproject.py:
from flask import Flask
myapp = Flask(__name__)
#myapp.route("/")
def hello():
return 'Test!'
if __name__ == "__main__":
myapp.run(host='0.0.0.0')
wsgi.py:
from myproject import myapp
if __name__ == "__main__":
myapp.run()
Gunicorn (and most WSGI servers) defaults to looking for the callable named application in whatever module you point it at. Adding an alias from myproject import myapp as application or application = myapp will let Gunicorn discover the callable again.
However, the wsgi.py file or the alias aren't needed, Gunicorn can be pointed directly at the real module and callable.
gunicorn myproject:myapp --workers 16
# equivalent to "from myproject import myapp as application"
Gunicorn can also call an app factory, optionally with arguments, to get the application object. (This briefly did not work in Gunicorn 20, but was added back in 20.0.1.)
gunicorn 'myproject.app:create_app("production")' --workers 16
# equivalent to:
# from myproject.app import create_app
# application = create_app("production")
For WSGI servers that don't support calling a factory, or for other more complicated imports, a wsgi.py file is needed to do the setup.
from myproject.app import create_app
app = create_app("production")
gunicorn wsgi:app --workers 16
If you're trying to serve an app with variable name app within server/cats.py, you can start the server on port 8000 as follows:
gunicorn server.cats:app -b 0.0.0.0:8000