Running Gunicorn and Django - django

I don't know how to use gunicorn with django. Could you give me some help?
This is how I run the server with django. It is https
python3 manage.py runsslserver xx.8x.x3.x4:443 --certificate /etc/letsencrypt/live/callservicesvps.online/fullchain.pem --key /etc/letsencrypt/live/callserv.com/privkey.pem
And in the gunicorn documentation it is mentioned that it must be executed as follows:
gunicorn myproject.wsgi
And here I have 2 questions. What is myproject.wsgi? Where Can I find it? Because if I look in the directory where the django project is, the only thing I find with wsgi is a file called wsgi.py
Running the server as follows gives me an error
gunicorn /home/proyectdirectory/wsgi.py
It also gives me an error if I put:
gunicorn /home/proyectdirectory/wsgi:Some_directory_where_the_proyec_is

What is myproject.wsgi?
myproject.wsgi IS the wsgi.py file you have located inside your project.
[End of answer]
But a further explanation will clear up why this is..
I imagine most people will look atmyproject.wsgi and see a file with an extension file type .wsgi but this is just because of the way importing of modules is written in python.
I want to clarify what a module and a package before continuing an explanation.
What is a Module
From the jargon heavy python docs
A module is a file containing Python definitions and statements.
Put simply, a module in python is just a python file containing any sort of functions, variables, or classes etc.
What is a Package
A package is just a collection of modules. The most simplest example, a special directory containing python files. In order to tell python that a directory is a package it must have a file named __init__.py inside of it. You will find a few of these inside different directories inside your django project. This is why they are there.
Now, I can say what I want to say which is the structure of the module namespace in python.
package.subpackage.module
If you look inside your wsgi.py file you'll see a good example of importing from django's own wsgi module.
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<project>.settings')
application = get_wsgi_application()
More specifically
from django.core.wsgi import get_wsgi_application
If you look inside the django package you can see how this works.
django (package) core (subpackage) wsgi (module)
Remember, the command gunicorn myproject.wsgi should be run inside the base directory of your django project. I always remember this as the directory containing the manage.py file. That is how gunicorn can find the wsgi.py file using the module namespace in this way. gunicorn is written in python afterall.
gunicorn /home/proyectdirectory/wsgi.py will error because python module imports don't contain / and even if you tried gunicorn home.proyectdirectory.wsgi home and proyectdirectory are not python packages.
Now hopefully this makes sense:
"If gunicorn myproject.wsgi is referring to the wsgi.py file why not just put gunicorn myproject.wsgi.py?"
You can't put a .py extension because this will refer to a module inside the wsgi subpackage with a filename py.py!

Related

Upload Django app to Heroku. ModuleNotFoundError:No Module named 'Name of Project"

I can not upload Django App to Heroku by command: git push heroku master. After uploading I have error: ModuleNotFoundError: No module named 'bot_diller'
Procfile:
web: gunicorn bot_diller.wsgi --log-file -
enter image description here
From the directory structure the root of your Git project is not entirely clear to me.
It seems you reference bot_diller as python module probably in an import statement in one of your Python files, which is outside of the scope of the code you push to Heroku.
The Django project seems to be inside bot_diller/new_project, where you have the top-level files like Procfile, requirements.txt and manage.py.
The Django app you created seems to be called main, which is also a Python module and beside that you have a module named new_project, which probably contains the Django settings.
So inside your Django project you can write import statements like
from main.models import MyModel
and the import error probably originates from a statement like
from bot_diller.new_project.main.models import MyModel

While importing 'myapp.app' an import error was raised

I'm building a flask application, located in a subdirectory within my project called myapp. Running gunicorn --bind 0.0.0.0:$PORT myapp.app:app works fine, no errors, regardless of what FLASK_APP is set to. When I try to use Flask's CLI, however, it fails to find my app (reasonable), but when I set FLASK_APP to myapp.app., it appears to be doubling up the import path, resulting in an import error:
FLASK_APP=myapp.app flask run
* Serving Flask app 'myapp.app' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
Usage: flask run [OPTIONS]
Try 'flask run --help' for help.
Error: While importing 'myapp.myapp.app', an ImportError was raised.
How can I solve this? Is this a bug in Flask?
There was a __init__.py in my project directory that was causing this.
I dug into the source code of flask in cli.py and found the following code in prepare_import:
# move up until outside package structure (no __init__.py)
while True:
path, name = os.path.split(path)
module_name.append(name)
if not os.path.exists(os.path.join(path, "__init__.py")):
break
Because I had an __init__.py in my project directory (also called myapp), this made flask try to import myapp.app from the ancestor of my project, resulting in myapp.myapp.app.

Error running WSGI application, ModuleNotFoundError: No module named 'mysite'. Also not able to find Static files

I'm trying to deploy my website using pythonanywhere. I've given the correct path in wsgi file which is as follows (see code below). Still I'm getting a ModuleNotFoundError.
Also, it's not able to find Static files, however, they are at correct location.
Wsgi file code:
{
path = '/home/divyanshu964/portfolio/Personal_portfolio/'
if path not in sys.path:
sys.path.insert(0, path)
os.environ['DJANGO_SETTINGS_MODULE'] = 'Personal_portfolio.settings'
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
}
Can someone help? Thanks.
Hello #DivyanshuRaghuwanshi to load static files you can set DEBUG=True inside settings.py but it's not a good practice to set DEBUG on in production so another way is to set your DEBUG=False and create STATIC_ROOT and configure it inside project root urls.py and than run python manage.py collectstatic command and than give path of your static root directory in pythonanywhere configuration
Apart from settings directly related to Django, there are some extra steps on PythonAnywhere.
wsgi file: you need to edit the file that is linked on the Web app page, not a file inside your project (check the docs here)
static files: set up static files mappings on the Web app page as well (check the docs here).

ImportError: no module named [directory] Google App Engine

I keep getting an error that says no module named backend, this is the directory where my webapp2 application is.
My folder structure:
/project
/backend
/env #python virtual env libraries
main.py #my main entry point where webapp2 app instance is
requirements.txt
app.yaml
My app.yaml:
service: default
handlers:
- url: /dist
static_dir: dist
- url: /.*
script: backend.main.app
libraries:
- name: webapp2
version: latest
- name: jinja2
version: latest
Before my app.yaml was in backend, but I decided to move to root. Now when I run dev_appserver.py in root, I keep getting ImportError: No module named backend
I created the virualenv and installed the requirements.txt packages inside the backend directory.
EDIT: I am unsure if this makes a difference, but I have already deployed my application when the app.yaml was inside the backend folder. I am guessing this should not matter since I am trying to test locally by moving the app.yaml in my project root and running dev_appserver.py app.yaml, but it seems to not work when I do this.
The directory containing the app.yaml file for a GAE service is the service's top-level directory. The content of this directory is what will be uploaded to GAE when you deploy the service. All paths referenced in the service's code or configurations are relative to this top level dir. So moving the app.yaml file around without updating the related code and configurations accordingly will break the app's functionality.
You don't seem to grasp the meaning of the script: statement very well. From Handlers element:
A script: directive must be a python import path, for example,
package.module.app that points to a WSGI application. The last
component of a script: directive using a Python module path is the
name of a global variable in the module: that variable must be a WSGI
app, and is usually called app by convention.
Note: just like for a Python import statement, each subdirectory that
is a package must contain a file named __init__.py
So, assuming your app.yaml file is located in your project dir, the
script: backend.pythonAttack.app
would mean:
having an __init__.py file inside the backend dir, to make backend a package
having a pythonAttack.py file in the backend dir, with an app variable pointing to your webapp2 application
According to your description you don't meet any of these conditions.
My recommendation:
keep the app.yaml inside the backend dir (which doesn't need to be a python package dir)
update its script line to match your code. Assuming the app variable for your webapp2 app is actually in the main.py file the line would be:
script: main.app
run the app locally by explicitly passing the app.yaml file as argument (in general a good habit and also the only way to run apps with multiple services and/or a dispatch.yaml file):
dev_appserver.py backend/app.yaml
store your service python dependencies inside a backend/lib directory (to follow the naming convention), separated from your virtualenv packages
store the env virtualenv package dir outside the backend directory to prevent unnecessarily uploading them to GAE when deploying the service (and potential interference with the app's operation). The goal of the virtualenv is to properly emulate the GAE sandbox locally so that you can run the development server correctly.
Potentially of interest for structuring a multi-service app: Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?

django simple captcha no such file /usr/share/dict/words

I am deploying my Django project on a virtual machine with Ubuntu Trusty.
To do this I am using Gunicorn (with Supervisor) and Nginx.
Here is the link to the tutorial I followed:
http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/
When I start Nginx and Gunicorn, the website is accessible, but when I try to reach a page that is using an app like django-simple-captcha, I get a "Server Error (500)".
As I am using virtualenv, all these apps (rosetta, easymode, simple-captcha...) installed with pip are stored in myvirtualenv/myproject/lib/python2.7/site-packages.
After some research, I modified my wsgi.py file to add the site-packages directory into the path, like this:
import os, sys, site
# Tell wsgi to add the Python site-packages to its path
site.addsitedir(os.path('/webapps/project/lib/python2.7/site-packages'))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
#activate_this = os.path('/webapps/project/bin/activate_this.py')
#execfile(activate_this, dict(__file__=activate_this))
#sys.path.append(os.path('/webapps/project/'))
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
... but it still doesn't work, knowing that if I uncomment one of the three lines above, I get an error message from gunicorn when restarting it:
project: ERROR (abnormal termination)
Do you think the problem here is that I don't activate the virtualenv?
Should I find another way to activate it?
How can I have some more information about why gunicorn won't start with the execfile or sys.path.append line?
Do you have any suggestions on what to do?
Please let me know if it lacks information, like the gunicorn_start script (even if it is the same as what we can found on many tutorials) :)
UPDATE:
I didn't pay enough attention, the gunicorn_start script is activating the virtualenv, so I don't need to do it in the wsgi.py file.
But the problem is still here: I print sys.path in the wsgi.py file, and when I use the python manage.py runserver my.server.address:8000 command, I can see that all the needed directories are in:
['/webapps/project/project', '/webapps/project/lib/python2.7', '/webapps/project/lib/python2.7/plat-x86_64-linux-gnu', '/webapps/project/lib/python2.7/lib-tk', '/webapps/project/lib/python2.7/lib-old', '/webapps/project/lib/python2.7/lib-dynload', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/webapps/project/local/lib/python2.7/site-packages', '/webapps/project/lib/python2.7/site-packages']
I can't figure out why I get Server Error (500) when I try to load a page that make use of django-simple-captcha app located in /webapps/project/lib/python2.7/site-packages...
After some tests, I saw that it was only django-simple-captcha at the origin of the problem. And don't ask me why I didn't think to do that earlier, but I turned DEBUG on, and I got an IO error:
no such file /usr/share/dict/words
Indeed I was using
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.word_challenge'
in my settings.py...
Two solutions:
Use another generator for django-simple-captcha: http://django-simple-captcha.readthedocs.org/en/latest/advanced.html#generators-and-modifiers
Install needed dictionnaries:
sudo apt-get install wamerican
sudo apt-get install wfrench
...