Running Django with gunicorn: Bad Request (400) - python

I am following this tutorial to set up a Django application and serve it with Gunicorn on a Debian DigitalOcean server: http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/
I have got as far as the section starting "Now that you have gunicorn, you can test whether it can serve your Django application by running the following command". Now I'm stuck.
In other words, I can successfully run the application using python manage.py runserver, but not by using gunicorn.
I've successfully accessed my app with:
$ python manage.py runserver xx.xx.xx.xx:8000
Now from the same directory, I'm trying to run:
$ gunicorn my_django.wsgi:application --bind xx.xx.xx.xx:8001
It appears to start OK, but when I go to http://xx.xx.xx.xx:8001, I see:
Bad Request (400)
I'm not sure how to debug this: there's nothing in /var/log/gunicorn/.
I have set ALLOWED_HOSTS=['xx.xx.xx.xx'] in my settings file.
UPDATE: Being an idiot: gunicorn was looking in production settings file, not local settings file. Setting the ALLOWED_HOSTS in production settings fixed it.
I'd still really like to know how to debug problems like this though.

The answer: gunicorn was looking in production settings file, not local settings file. Setting the ALLOWED_HOSTS in production settings fixed it.

Related

What is the command for starting a WSGI server for Django?

I've developed an application in Django that I usually run in development mode:
python manage.py runserver
I do the same for my deployed instances - obviously a security issue that I now want to resolve.
From the Django docs, its not clear to me how to:
For simplicity sake, I picked wsgi (over asgi): https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ . From this page, its not clear to me how my 'runserver' command changes to run the wsgi server over the development server. Should I run the wsgi.py file? That doesn't seem to do anything.
From the page above, its not clear whether wsgi is actually a server, or more a platform/type of servers. Do I need to use uwsgi/uvicorn/etc. instead?
I'm testing on windows - uvicorn is unix only, so I tried uwsgi, but thats giving me this error message: AttributeError: module 'os' has no attribute 'uname' - I guess its Unix only as well
So I'm using the docker image I was already building for deployment - uwsgi is giving me issues again because my docker image has no compiler, so I try now with gunicorn.
that should be easy: gunicorn project.wsgi, which gives me:
ModuleNotFoundError: No module named 'project/wsgi'
my folder structure looks like:
root-folder
project
wsgi.py
settings.py
django_app_1
django_app_2
manage.py
As the manual says, the gunicorn command should work as long as you run the gunicorn command from the same location as manage.py - which is what I'm doing.
I guess I'm missing something very obvious - who knows what?
The wsgi.py file just gives you a WSGI compatible application that a WSGI HTTP server (such as Gunicorn) can run.
I guess you have to run gunicorn project.wsgi from the root folder (that one containing the project module).
Typically, the directory containing manage.py and the module in which wsgi.py resides are one and the same. But not in your case.

Deplying Django to Heroku - DisallowedHost Error despite Heroku URL in DJANGO_ALLOWED_HOSTS

I've been at this for hours and need help. Initially I thought it was because I had mistakenly done something small that caused it, so I deleted the app, and created everything - virtual env, heroku app, django projects/apps - fresh.
I get the same error.
I made a cookiecutter django app and deployed it to heroku. Everything goes smoothly until it's time to actually use the site.
When I run heroku open, I get the DisallowedHosts error:
DisallowedHost at /
Invalid HTTP_HOST header: 'MY-NEW-APP.herokuapp.com'. You may need to add 'MY-NEW-APP.herokuapp.com' to ALLOWED_HOSTS.
heroku config shows that DJANGO_ALLOWED_HOSTS=MY-NEW-APP.herokuapp.com. I don't overwrite it in my settings file.
I have import django_heroku and django_heroku.settings(locals()) in my settings file.
DJANGO_SETTINGS_MODULE is correctly set to that file.
What's more, I get a warning about DEBUG=True, when DEBUG=False in my settings file and in the heroku environment.
What am I missing? Are hyphens a bad thing? Should I be using herokuapp.com instead of the full URL?
Solved my own question. I just had to:
heroku config:set DJANGO_ALLOWED_HOSTS=.MY-NEW-APP.COM,MY-NEW-APP.herokuapp.com,.herokuapp.com

Why is Flask giving me the same output? [duplicate]

I'm investigating how to develop a decent web app with Python. Since I don't want some high-order structures to get in my way, my choice fell on the lightweight Flask framework. Time will tell if this was the right choice.
So, now I've set up an Apache server with mod_wsgi, and my test site is running fine. However, I'd like to speed up the development routine by making the site automatically reload upon any changes in py or template files I make. I see that any changes in site's .wsgi file causes reloading (even without WSGIScriptReloading On in the apache config file), but I still have to prod it manually (ie, insert extra linebreak, save). Is there some way how to cause reload when I edit some of the app's py files? Or, I am expected to use IDE that refreshes the .wsgi file for me?
Run the flask run CLI command with debug mode enabled, which will automatically enable the reloader. As of Flask 2.2, you can pass --app and --debug options on the command line.
$ flask --app main.py --debug run
--app can also be set to module:app or module:create_app instead of module.py. See the docs for a full explanation.
More options are available with:
$ flask run --help
Prior to Flask 2.2, you needed to set the FLASK_APP and FLASK_ENV=development environment variables.
$ export FLASK_APP=main.py
$ export FLASK_ENV=development
$ flask run
It is still possible to set FLASK_APP and FLASK_DEBUG=1 in Flask 2.2.
If you are talking about test/dev environments, then just use the debug option. It will auto-reload the flask app when a code change happens.
app.run(debug=True)
Or, from the shell:
$ export FLASK_DEBUG=1
$ flask run
http://flask.palletsprojects.com/quickstart/#debug-mode
In test/development environments
The werkzeug debugger already has an 'auto reload' function available that can be enabled by doing one of the following:
app.run(debug=True)
or
app.debug = True
You can also use a separate configuration file to manage all your setup if you need be. For example I use 'settings.py' with a 'DEBUG = True' option. Importing this file is easy too;
app.config.from_object('application.settings')
However this is not suitable for a production environment.
Production environment
Personally I chose Nginx + uWSGI over Apache + mod_wsgi for a few performance reasons but also the configuration options. The touch-reload option allows you to specify a file/folder that will cause the uWSGI application to reload your newly deployed flask app.
For example, your update script pulls your newest changes down and touches 'reload_me.txt' file. Your uWSGI ini script (which is kept up by Supervisord - obviously) has this line in it somewhere:
touch-reload = '/opt/virtual_environments/application/reload_me.txt'
I hope this helps!
If you're running using uwsgi look at the python auto reload option:
uwsgi --py-autoreload 1
Example uwsgi-dev-example.ini:
[uwsgi]
socket = 127.0.0.1:5000
master = true
virtualenv = /Users/xxxx/.virtualenvs/sites_env
chdir = /Users/xxx/site_root
module = site_module:register_debug_server()
callable = app
uid = myuser
chmod-socket = 660
log-date = true
workers = 1
py-autoreload = 1
site_root/__init__.py
def register_debug_server():
from werkzeug.debug import DebuggedApplication
app = Flask(__name__)
app.debug = True
app = DebuggedApplication(app, evalex=True)
return app
Then run:
uwsgi --ini uwsgi-dev-example.ini
Note: This example also enables the debugger.
I went this route to mimic production as close as possible with my nginx setup. Simply running the flask app with it's built in web server behind nginx it would result in a bad gateway error.
For Flask 1.0 until 2.2, the basic approach to hot re-loading is:
$ export FLASK_APP=my_application
$ export FLASK_ENV=development
$ flask run
you should use FLASK_ENV=development (not FLASK_DEBUG=1)
as a safety check, you can run flask run --debugger just to make sure it's turned on
the Flask CLI will now automatically read things like FLASK_APP and FLASK_ENV if you have an .env file in the project root and have python-dotenv installed
app.run(use_reloader=True)
we can use this, use_reloader so every time we reload the page our code changes will be updated.
I got a different idea:
First:
pip install python-dotenv
Install the python-dotenv module, which will read local preference for your project environment.
Second:
Add .flaskenv file in your project directory. Add following code:
FLASK_ENV=development
It's done!
With this config for your Flask project, when you run flask run and you will see this output in your terminal:
And when you edit your file, just save the change. You will see auto-reload is there for you:
With more explanation:
Of course you can manually hit export FLASK_ENV=development every time you need. But using different configuration file to handle the actual working environment seems like a better solution, so I strongly recommend this method I use.
Use this method:
app.run(debug=True)
It will auto-reload the flask app when a code change happens.
Sample code:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "Hello World"
if __name__ == '__main__':
app.run(debug=True)
Well, if you want save time not reloading the webpage everytime when changes happen, then you can try the keyboard shortcut Ctrl + R to reload the page quickly.
From the terminal you can simply say
export FLASK_APP=app_name.py
export FLASK_ENV=development
flask run
or in your file
if __name__ == "__main__":
app.run(debug=True)
Enable the reloader in flask 2.2:
flask run --reload
Flask applications can optionally be executed in debug mode. In this mode, two very convenient modules of the development server called the reloader and the debugger are enabled by default.
When the reloader is enabled, Flask watches all the source code files of your project and automatically restarts the server when any of the files are modified.
By default, debug mode is disabled. To enable it, set a FLASK_DEBUG=1 environment variable before invoking flask run:
(venv) $ export FLASK_APP=hello.py for Windows use > set FLASK_APP=hello.py
(venv) $ export FLASK_DEBUG=1 for Windows use > set FLASK_DEBUG=1
(venv) $ flask run
* Serving Flask app "hello"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 273-181-528
Having a server running with the reloader enabled is extremely useful during development, because every time you modify and save a source file, the server automatically restarts and picks up the change.
To achieve this in PyCharm set 'Environment Variables' section to:
PYTHONUNBUFFERED=1;
FLASK_DEBUG=1
For Flask 'run / debug configurations'.
To help with fast automatic change in browser:
pip install livereload
from livereload import Server
if __name__ == '__main__':
server = Server(app.wsgi_app)
server.serve()
Next, Start your server again:
eg. your .py file is app.py
python app.py
I believe a better solution is to set the app configuration. For me, I built the tool and then pushed it to a development server where I had to set up a WSGI pipeline to manage the flask web app. I had some data being updated to a template and I wanted it to refresh every X minutes (WSGI deployment for the Flask site through APACHE2 on UBUNTU 18). In your app.py or whatever your main app is, add app.config.update dictionary below and mark TEMPLATES_AUTO_RELOAD=True, you will find that any templates that are automatically updated on the server will be reflected in the browser. There is some great documentation on the Flask site for configuration handling found here.
app = Flask(__name__)
app.config.update(
TEMPLATES_AUTO_RELOAD=True
)

Newrelic error in Django : Configuration has already been done

I am getting this error when i am trying to run
python manage.py runserver for my Django Project,
newrelic.api.exceptions.ConfigurationError: Configuration has already been done against differing configuration file or environment. Prior configuration file used was "/home/project/newrelic.ini" and environment "staging".'
What does it mean ?? How to approach it?
Have you just setup New Relic?
I believe this is a problem with your procfile. Which you most likely just have edited.
Your procfile should look something like this, depending on your wsgi.
web: newrelic-admin run-program gunicorn hello.wsgi --log-file -

Heroku looking for the wrong wsgi file. Django

I'm on Django, but I'm not sure if it matters. Anyway, I get an Application Error, and when I check the logs I see the error:
ImportError: No module named redlibros.wsgi
And it is fine cause the wsgi file is not name "redlibros.wsgi", I don't even know where it gets that name. The module is named
WSGI_APPLICATION = 'letrasclub.wsgi.application' # on my settings
web: gunicorn letrasclub.wsgi --log-file - # on my procfile
and on my folders it looks like this:
LetrasClub
letrasclub
wsgi.py
templates
static
...
Any idea where to find the error?
EDIT
Ok, some extra info: I have a different repo, with a different Heroku remote. I copied that repo, changed the app, created a new Heroku remote and then pushed to the new one.
So, if I write
git remote -v
heroku https://git.heroku.com/letrasclub2.git (fetch)
heroku https://git.heroku.com/letrasclub2.git (push)
origin https://github.com/Alejoss/LetrasClub2.0.git (fetch)
origin https://github.com/Alejoss/LetrasClub2.0.git (push)
Looks fine, if I go to the old app location and write the same command I get the old remote, the one that is related to the "redlibros.wsgi" app, perfect.
Now, why when I try to push the new app to the new heroku remote, I get the error that means Heroku is looking for the Old wsgi file, I changed the wsgi name, I changed the Procfile, I changed the wsgi file declaration on the settings, what am I missing?
You look at wrong project.
You look at https://github.com/Alejoss/redlibros (I guess it's Your project), not at https://github.com/Alejoss/LetrasClub2.0

Categories