Django / Apache / mod_wsgi: No module named importlib - django

After working with django's dev server for the past two months, the time finally came to move to apache + mod_wsgi.
The problem is when I go to my site (let's call it junux), to the URL mapped to the django app, things do not seem to work. When running the dev server on the server things work properly.
The bottom-line of the error is given to me in the apache error_log:
ImportError: Could not import settings 'junux_site.settings' (Is it on
sys.path?): No module named importlib
I'm aware this is similar to many other questions on the matter (there are so many that I won't even quote them here), but I still haven't found the answer. I have read quite a few guides on moving to production, including django's deployment docs, mod_wsgi's guides, some pycon presentation and have been googling the issue all day...
Lots of fun and exciting details below.
Any help will be appreciated.
Thanks in advance.
The configuration:
Apache 2.2.15 with mod_wsgi on CentOS 6
Python 2.7.3 compiled from source
The site uses a virtualenv
This is the error page apache returns:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Apache/2.2.15 (CentOS) Server at junux.net Port 80
The apache error_log reveals the following information:
mod_wsgi (pid=22502): Create interpreter 'junux.net|/dev'.
mod_wsgi (pid=22502): Exception occurred processing WSGI script '/var/www/junux_dev/junux_site/wsgi.py'.
Traceback (most recent call last):
File "/var/www/junux_dev/venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 219, in __call__
self.load_middleware()
File "/var/www/junux_dev/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 39, in load_middleware
for middleware_path in settings.MIDDLEWARE_CLASSES:
File "/var/www/junux_dev/venv/lib/python2.7/site-packages/django/utils/functional.py", line 184, in inner
self._setup()
File "/var/www/junux_dev/venv/lib/python2.7/site-packages/django/conf/__init__.py", line 42, in _setup
self._wrapped = Settings(settings_module)
File "/var/www/junux_dev/venv/lib/python2.7/site-packages/django/conf/__init__.py", line 95, in __init__
raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'junux_site.settings' (Is it on sys.path?): No module named importlib
The relevant wsgi.py:
import os
import sys
import site
# use our virtual environment
SITE_DIR = os.path.dirname(__file__)
PROJECT_ROOT = os.path.dirname(SITE_DIR)
site_packages = os.path.join(PROJECT_ROOT, 'venv/lib/python2.7/site-packages')
site.addsitedir(os.path.abspath(site_packages))
sys.path.insert(0, SITE_DIR)
sys.path.insert(1, PROJECT_ROOT)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "junux_site.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
And httpd.conf:
(more stuff here from the default apache configuration file)
<VirtualHost *:80>
ServerName junux.net
ServerAlias junux.net
ServerAdmin admin#junux.net
WSGIScriptAlias /test /var/www/test/hello.py
WSGIScriptAlias /dev /var/www/junux_dev/junux_site/wsgi.py
<Directory /var/www/test >
Order allow,deny
Allow from all
</Directory>
<Directory /var/www/junux_dev >
Options FollowSymLinks
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
LogLevel info
There's a WSGIScriptAlias to /test to provide a sanity-check that mod_wsgi indeed works. It does. When opening that URL the (very simple) application works (a typical hello world).
I have set permissions to chmod o+r on my wsgi file and chmod o+rx on the entire /var/www/junux_dev dir, as instructed in the pycon-sydney-2010 presentation refered to from here.

What version of Python was mod_wsgi compiled against? Looks like you might have multiple Python installations on the system and your virtual environment is using Python 2.7, but your mod_wsgi is compiled against 2.6.
Am basing this guess on fact that importlib was only added in Python 2.7, so if mod_wsgi was compiled for 2.6 and using that base installation, then would fail to find importlib.
Run checks:
http://code.google.com/p/modwsgi/wiki/CheckingYourInstallation#Python_Shared_Library
http://code.google.com/p/modwsgi/wiki/CheckingYourInstallation#Python_Installation_In_Use

Related

How to install a server at home with django&postgre

Please help me to set my home PC as a server (Windows 10 + Python + Django + Postgre SQL + Anaconda)
There are several instructions on how to set the server on the Internet, and surprisingly, many instructions differ from each other. I have absolutely no experience in setting a server. Probably, I’m making a stupid mistake somewhere that I can’t identify for 3 days. I am lost.
I believe that most useful instructions are these (they are complete and new):
https://www.codementor.io/aswinmurugesh/deploying-a-django-application-in-windows-with-apache-and-mod_wsgi-uhl2xq09e
https://ostrokach.gitlab.io/post/apache-django-anaconda/
I followed the instructions and successfully downloaded the necessary modules, installed Wamp, made the changes as displayed in the guide and started it. What I see now: the Wamp icon glows green. When I load a localhost, the page loads endlessly but does not load.
Wamp error log shows following: [Fri Oct 11 14:50:33.823752 2019]
[core:notice] [pid 1364:tid 808] AH00094: Command line:
'c:\wamp64\bin\apache\apache2.4.39\bin\httpd.exe -d
C:/wamp64/bin/apache/apache2.4.39' [Fri Oct 11 14:50:33.840681 2019]
[mpm_winnt:notice] [pid 1364:tid 808] AH00418: Parent: Created child
process 15052 [Fri Oct 11 14:50:34.981629 2019] [mpm_winnt:notice]
[pid 15052:tid 800] AH00354: Child: Starting 64 worker threads.
Project name: turiumasina
path D:/Users/PycharmProjects/turiumasina/
path to wsgi:D:/Users/PycharmProjects/turiumasina/turiumasina/wsgi_windows.py (I renamed wsgi to wsgi_windows, settings file is in turiumasina/turiumasina/)
I copied the output generated by the mod_wsgi-express command and pasted it at the end of C:\wamp64\bin\apache\apache\conf\httpd.conf
my httpd-vhosts.conf
ServerName localhost
WSGIPassAuthorization On
ErrorLog "logs/turiumasina.error.log"
CustomLog "logs/turiumasina.access.log" combined
WSGIScriptAlias / "D:/Users/PycharmProjects/turiumasina/turiumasina/wsgi_windows.py"
<Directory "D:/Users/PycharmProjects/turiumasina">
<Files wsgi_windows.py>
Require all granted
</Files>
</Directory>
Alias /static "D:/Users/PycharmProjects/turiumasina/static"
<Directory "D:/Users/PycharmProjects/turiumasina/static">
Require all granted
</Directory>
wsgi_windows.py
import os
import sys
import site
from django.core.wsgi import get_wsgi_application
site.addsitedir("C:/users/.conda/envs/turiumasina/Lib/site-packages")
sys.path.append('D:/Users/PycharmProjects/turiumasina')
sys.path.append('D:/Users/PycharmProjects/turiumasina/turiumasina')
os.environ['DJANGO_SETTINGS_MODULE'] = 'turiumasina.settings'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "turiumasina.settings")
application = get_wsgi_application()
I generated the "static" folder, wrote a line in the settings.py:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
If I enter python manage.py runserver via pycharm, I can see my site through a browser (http://127.0.0.1:8000/). the Wamp icon glows green. When I load a localhost, the page loads endlessly but does not load.
I would like my site to be visible not only to me, but also to Internet users by entering my external IP.
If you need, I can send you the whole project and project settings
I would get rid of WAMP altogether, I don't see why you need it if you're not using PHP or MySql.
If you just need to play/debug the Django app over the local network just run ./manage.py runserver 0.0.0.0:8000 (or any other port). Make sure your Windows firewall is allowing incoming connections to the port.
The connect to it you need the computer's actual IP not '0.0.0.0:8000'. Type 'ipconfig' at the command prompt to see what your actual IP is an then connect to Your_actual_IP:8000
If you need something more solid than the build-in Django server (to run in non-debug mode) then you can install Waitress (https://docs.pylonsproject.org/projects/waitress/en/latest/).

Apache with virtualenv and mod_wsgi : ImportError : No module named 'django'

I'm trying to serve a little django project with the following Apache configuration :
Apache virtualhost configuration :
<VirtualHost *>
ServerName servername
[...]
<Directory "/path/to/project/project">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess project python-path=/path/to/project:/path/to/Envs/venv/lib/python3.5/site-packages
WSGIScriptAlias / /path/to/project/project/wsgi.py
</VirtualHost>
I also have the following wsgi.py :
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings")
application = get_wsgi_application()
I have no problem to serve STATIC files and MEDIA files.
I also checked permissions and tried to recursively use 755, then 777 to my virtualenv's site-package directory. It didn't work.
But when trying to reach the root of my site I get the following :
from django.core.wsgi import get_wsgi_application
ImportError: No module named 'django'
I guessed that it was a Python path related problem since django is installed in my virtualenv. But I added the relevant python paths to the WSGIDaemonProcess's python-path attribute so I don't get why it doesn't work.
I also guess I could add the relevant directory to my Python path in my wsgi.py by using the site module, but I'd like to understand why the Apache configuration I tried isn't enough. Did I miss something?
You are missing a WSGIProcessGroup directive or equivalent option on WSGIScriptAlias, so your application isn't actually being run in that daemon process group where you have set the virtual environment.
See Using mod_wsgi daemon mode
I would also recommend ensuring application group is set to '%{GLOBAL}' if that is the only application you are running in the daemon process group.
Thus use:
WSGIScriptAlias / /path/to/project/project/wsgi.py \
process-group=project application-group=%{GLOBAL}
Also better to use python-home for the virtual environment.
WSGIDaemonProcess project python-path=/path/to/project \
python-home=/path/to/Envs/venv
See:
http://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
My rep is not over 50 so I cannot comment, but I'd like to share my discovery.
In WSGIDaemonProcess, if you are using Python 3.5, you need to set exactly as #graham-dumpleton say, with
python-home=/path/to/Envs/venv
set explicitly.
However, if you are using Python 3.4 (or some older version Python like 2.7 as far as I know), you'll have to configure it as
python-path=/path/to/project:/path/to/Envs/venv/lib/python3.4/site-packages
just like what the asker did.
Really weird.
For me the problem was I had mod wsgi installed for python2. I had to reinstall it for python3:
sudo apt-get install libapache2-mod-wsgi-py3
The issue for me was that I was running libapache2-mod-wsgi-py3 on python version 3.9. When I rolled back the python version to 3.7, there was no issue.

Django deployment with mod_wsgi on WAMP

Context
Python 2.7 64bit
Django 1.3
WAMP 2.2 (Apache 2.2.22) 64bit
mod_wsgi 3.4 64bit
Windows 7 64bit
Detail | Apache httpd.conf
...
Listen 192.168.20.11:8080
...
LoadModule wsgi_module modules/mod_wsgi.so
...
ServerName 192.168.20.11:8080
...
DocumentRoot "c:/wamp/www/"
...
<VirtualHost *:8080>
ServerName 192.168.20.11
ServerAdmin me#mine.com
DocumentRoot "C:/wamp/www/myapp"
<Directory "C:/wamp/www/mapp">
Order allow,deny
Allow from all
</Directory>
Alias /myapp/static "C:/wamp/www/myapp/static"
WSGIScriptAlias /test "C:/wamp/www/myapp/wsgi.py"
</VirtualHost>
Detail | wsgi.py
Generated by Django's startproject. Located at default /myapp/myapp/wsgi.py
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Problem
Cannot deploy Django app on WAMP given the context described above.
A "Hello World" test wsgi application works fine, so I have confirmed that mod_wsgi is active.
I get the error:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, me#mine.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
when pointing to:
http://192.168.20.11:8080/myapp
The static folder works fine, I can access all static files within the directory by pointing to:
http://192.168.20.11:8080/myapp/static
Detail | Server error log
NB: I've removed the timestamps for legibility.
mod_wsgi (pid=5728, process='', application='192.168.20.11:8080|/myapp'): Loading WSGI script 'C:/wamp/www/myapp/myapp/wsgi.py'.
mod_wsgi (pid=5728): Exception occurred processing WSGI script
'C:/wamp/www/myapp/myapp/wsgi.py'.
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\django\core\handlers\wsgi.py", line 236, in call
self.load_middleware()
for middleware_path in settings.MIDDLEWARE_CLASSES:
File "C:\Python27\lib\site-packages\django\conf\_init_.py", line 52, in getattr
self._setup(name)
File "C:\Python27\lib\site-packages\django\conf\_init_.py", line 47, in _setup
self._wrapped = Settings(settings_module)
File "C:\Python27\lib\site-packages\django\conf\_init_.py", line 132, in init
raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" %(self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'myapp.settings' (Is it on sys.path?): No module named myapp.settings
File does not exist: C:/wamp/www/myapp/favicon.ico
I don't understand the function of middleware in this case and was under the impression it wasn't necessary to use middleware.
Regarding the system path, when I add:
WSGIPythonPath "c:/wamp/www/myapp"
to my VirtualHost in the httpd.conf file, the server refuses to start up.
Objective
To deploy a working Django app (that has been developed and tested locally using the Django development server) to a Microsoft SBS network without using IIS. I tried deploying on IIS and ran into difficulties early on so switched to WAMP.
I'm new to Python and Django and have never deployed a web app on any production server (I am an R programmer that has generally used programming for math and statistics).
Any advice that would help in achieving this objective, regardless of method, will be much appreciated!
This has nothing to do with middleware, that's just where the error was encountered. The error itself is the last line: "Could not import settings 'myapp.settings'". This is almost certainly because you haven't modified the PYTHONPATH - either in your wsgi or your Apache conf - to put "myapp" on the path.
See for instance the example Apache conf in the Django docs - there's a WSGIPythonPath directive there to add the app to the Python path, which you don't have.
Placing a WSGIPythonPath directive in the httpd.conf prevented the server from starting, but the problem was indeed related to the path not being declared.
Adding:
sys.path.append("c:/wamp/www/myapp")
to the wsgi.py file did the trick.
Thanks to Daniel Roseman for putting me on the right track.

Django Apache wsgi virtualenv import error

I'm trying to deploy Django (located in a virtualenv) on Apache using WSGI deploying. I'm following the default tutorial from https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/modwsgi/
wsgi.py (the default one which Django generated, with the comments dropped):
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
apache2.conf (its the same httpd.conf just in Debian ). Appended this to the end:
WSGIScriptAlias / /home/user/Desktop/expofit/expofit_hg/py/server/server/wsgi.py
WSGIDaemonProcess example.com python-path=/home/user/Desktop/expofit/expofit_hg/py/server:/home/user/Desktop/expofit/expofit_env/lib/python2.7/site-packages
WSGIProcessGroup example.com
<Directory /home/user/Desktop/expofit/expofit_hg/py/server/server>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
Alias /static/ /home/user/Desktop/expofit/expofit_hg/py/server/server/static
<Directory /home/user/Desktop/expofit/expofit_hg/py/server/server/static>
Order deny,allow
Allow from all
</Directory>
However, this ends with an error:
[Thu Dec 06 17:08:40 2012] [error] [client 192.168.56.1] ImportError: No module named django.core.wsgi
It seems that the standard python is accessible, since
import os
yields no errors. So it seems that modules imported from the virtualenv aren't importable.
The tutorial said:
A further change required to the above configuration if you use
daemon mode is that you can't use WSGIPythonPath; instead you should
use the python-path option to WSGIDaemonProcess, for example:
WSGIDaemonProcess example.com python-path=/path/to/mysite.com:/path/to/venv/lib/python2.7/site-packages
WSGIProcessGroup example.com
What am I missing?
The problem was in the permissions. I didn't check who was the user, and what the permissions were at the beginning, however, when I changed the permission 777 to all the directories containing Django code files, it started working.
I'm aware that a person has to be as careful as possible with permissions, and that giving 777 to everything isn't the best way to do it but should check how to make it work with minimum permission change. It however solves the problem in the question.
the pythonpath your envinronment is different than the apache one i think.
install django "globaly" with easy_install or pip
or add .virtualenv pythonpath to the mod_wsgi config
WSGIPythonPath directory|directory-1:directory-2:
MOD_wsgi config
For a single app this is the easiest to get out of the box, see http://code.google.com/p/modwsgi/wiki/VirtualEnvironments#Baseline_Environment Neither this or using WSGIPythonPath can be done for just a vhost but must be global.
WSGIPythonHome [path to virtualenv folder]
If you have multiple apps - using sys.path to append your virtualenv's site-packages folder at the top of wsgi.py seems the easiest thing to do, see http://code.google.com/p/modwsgi/wiki/VirtualEnvironments#Application_Environments.

Django ImportError: Could not import settings 'settings' - No module named csrf

I am just starting to fiddle around with django. First I made a small app on my windows machine and verified it worked fine
Then, I zipped the entire project, and opened the zip on a linux machine.
The linux machine was installed with mod_wsgi and django 1.1.1, of course.
I created the following dirs:
/usr/local/bin/ROOT - contains only one file, django.wsgi
/usr/local/bin/ROOT/myapp - root dir of django app
Per the instructions here, I added to httpd.conf:
<VirtualHost *:80>
ServerName server
ServerAlias server
ServerAdmin webmaster#example.com
WSGIScriptAlias /myapp /usr/local/bin/ROOT/django.wsgi
<Directory /usr/local/bin/ROOT/>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Now per the instructions here I put in /usr/local/bin/ROOT/django.wsgi:
import os
import sys
path = '/usr/local/bin/ROOT'
if path not in sys.path:
sys.path.append(path)
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
If it is of any importance: there is nothing set on PYTHOHPATH before the application starts.
After that I did a graceful restart to apache, and went to server/myapp. I got a 500 error.
Lookin in the log I see:
[Sun Dec 05 12:24:17 2010] [error] [client XXXX] ImproperlyConfigured: Error importing middleware django.middleware.csrf: "No module named csrf"
What am I doing wrong? all other threads I found about this always either end up with a conclusion that it's an old version of django (but mine's 1.1.1) or that there are several apps running, but I have only one...
Help?
"django.middleware.csrf" is the package in Django 1.2.x
For Django 1.1.x CSRF settings read the appropriate docs Here
The package in 1.1.x was "django.contrib.csrf.middleware.CsrfMiddleware"
1.1.1 is an old version of Django (the current version is 1.2.3), and that's almost certainly the cause of your problem. There is no django.middleware.csrf in 1.1.1.