ImportError: cannot import name '_imaging' - django

Apache or Python doesn't import image on the media folder. When I tried to upload something It returns 500 error.
Django is working behind Apache with mod_wsgi on CentOS 7. Django also works in a virtual environment. I disabled all firewalls (selinux, firewalld and iptables) I gave every permission to the Apache for the project folder. (chown apache:apache and chmod 777 I applied public write permission only for the media folder)
Here is my apache conf file for the project:
<VirtualHost *:80>
ServerAdmin webmaster#domain.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/html
Alias /static/ /var/www/example.com/html/static/
Alias /media /var/www/example.com/html/media
<Location "/static/">
Options -Indexes
</Location>
<Directory /var/www/example.com/html/logging>
<Files debug.log>
Require all granted
</Files>
</Directory>
<Directory /var/www/example.com/html>
<Files db.sqlite3>
Require all granted
</Files>
</Directory>
<Directory /var/www/example.com/html/media>
Require all granted
</Directory>
<Directory /var/www/example.com/html/media/uploads>
Require all granted
</Directory>
<Directory /var/www/example.com/html/static>
Require all granted
</Directory>
<Directory /var/www/example.com/html/example>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess example.com python-path=/var/www/example.com/html:/var/www/example.com/html/env/lib/python3.4/site-packages
WSGIProcessGroup example.com
WSGIScriptAlias / /var/www/example.com/html/example/wsgi.py
#Log Settings
ErrorLog "/etc/httpd/logs/example_error"
CustomLog "/etc/httpd/logs/example_acess" combined
</VirtualHost>
model.py
from django.db import models
from services.file_extentions import validate_image_extention
# Create your models here.
class FotografModel(models.Model):
"""Model definition for GaleriModel."""
# TODO: Define fields here
foto = models.ImageField(verbose_name="Fotoğraf", upload_to='uploads/fotograflar/', max_length=100, height_field=None, width_field=None, validators=[validate_image_extention])
foto_baslik = models.CharField(verbose_name="Fotoğraf Açıklaması (Görme Engelliler için)", max_length=100, blank=True, null=True)
olusturulma_tarihi = models.DateTimeField(editable=False, auto_now_add=True, null=True, verbose_name="Oluşturulma tarihi")
guncelleme = models.DateTimeField(auto_now=True, null=True, auto_now_add=False, verbose_name="Son güncelleme", editable=False)
class Meta:
"""Meta definition for FotografModel."""
verbose_name = 'Fotoğraf'
verbose_name_plural = 'Fotoğraflar'
def image_tag(self):
path = "/media/"+str(self.foto)
return u'<img src="%s" style="height:80px!important;height:auto;"/>' % (path)
image_tag.short_description = "Fotoğraf"
image_tag.allow_tags = True
def __str__(self):
return "%s" % (self.foto_baslik)
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver
#receiver(pre_delete, sender=FotografModel)
def fotograf_delete(sender, instance, **kwargs):
# Pass false so FileField doesn't save the model.
instance.foto.delete(False)
debug log
from . import _imaging as core
ImportError: cannot import name '_imaging'
When I open the shell in my virtual environment and tried this code from PIL import _imaging it works well. The project is using 4.3.0 version of Pillow package.

Related

How to secure media files in django in poduction?

I am trying to make a project and have some media files which should only be accessed by their owner.
In production, media and static files are served by apache (or nginx but I am using apache).
I was looking for some solutions and I am not able to apply.
On djangosnippets website, I found this code,
from mod_python import apache
from django.core.handlers.base import BaseHandler
from django.core.handlers.modpython import ModPythonRequest
class AccessHandler(BaseHandler):
def __call__(self, req):
from django.conf import settings
# set up middleware
if self._request_middleware is None:
self.load_middleware()
# populate the request object
request = ModPythonRequest(req)
# and apply the middleware to it
# actually only session and auth middleware would be needed here
for middleware_method in self._request_middleware:
middleware_method(request)
return request
def accesshandler(req):
os.environ.update(req.subprocess_env)
# check for PythonOptions
_str_to_bool = lambda s: s.lower() in ("1", "true", "on", "yes")
options = req.get_options()
permission_name = options.get("DjangoPermissionName", None)
staff_only = _str_to_bool(
options.get("DjangoRequireStaffStatus", "on")
)
superuser_only = _str_to_bool(
options.get("DjangoRequireSuperuserStatus", "off")
)
settings_module = options.get("DJANGO_SETTINGS_MODULE", None)
if settings_module:
os.environ["DJANGO_SETTINGS_MODULE"] = settings_module
request = AccessHandler()(req)
if request.user.is_authenticated():
if superuser_only and request.user.is_superuser:
return apache.OK
elif staff_only and request.user.is_staff:
return apache.OK
elif permission_name and request.user.has_perm(
permission_name
):
return apache.OK
return apache.HTTP_UNAUTHORIZED
But I am not able to install mod_python. Please tell me how to do that first
And I changed my .conf file for apache which is as below.
<VirtualHost *:80>
ServerName podcast.com
ServerAdmin srpatel980#gmail.com
DocumentRoot /home/username/Documents/secret_media
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /static /home/username/Documents/secret_media/static
<Directory /home/username/Documents/secret_media/static>
Require all granted
</Directory>
Alias /media /home/username/Documents/secret_media/media
<Directory /home/username/Documents/secret_media/media>
Require all granted
</Directory>
<Directory /home/username/Documents/secret_media/secret_media>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/username/Documents/secret_media/secret_media/wsgi.py
WSGIDaemonProcess secret_media python-path=/home/username/Documents/secret_media python-home=/home/username/Documents/secret_media/venv
WSGIProcessGroup secret_media
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authz_user_module modules/mod_authz_user.so
<Location "/media/images">
PythonPath /home/username/Documents/secret_media
PythonOption DJANGO_SETTINGS_MODULE secret_media.settings
PythonAccessHandler secret_media.wsgi.py #this should point to accesshandler
SetHandler None
</Location>
</VirtualHost>
There are some settings which are repeated, don't know why, please explain
X-Sendfile
I do not know about the method you use above, but I have been using mod_xsendfile to do the same. Whats the principle: request to a url is handeled by a view that checks access rights ... the view returns a response with a key "X-Sendfile" & file ... this triggers Apache on the way back to serve the media file.
I just show you the code without testing syntax .... please ask if something is not clear
Apache httpd.conf
LoadModule xsendfile_module modules/mod_xsendfile.so
in Apache remove the usual "alias media ..."
Apache httpd-vhosts.conf
<VirtualHost *:80>
# ... all your usual Django Config staff
# remove the usual alias /media/
# Alias /media/ d:/WEBSPACES/dieweltdahinter_project/media/
XSendFile on
XSendFilePath D:/your_path/media/
<Directory "D:/your_path/media">
Order Deny,Allow
Allow from all
</Directory>
</VirtualHost>
urls.py
urlpatterns = [
.....,
re_path(r'^media/(?P<folder>[A-Za-z0-9\-_]+)/(?P<filename>[A-Za-z0-9\-_]+).(?P<extension>[A-Za-z0-9]+)\/?$', app_views.media_xsendfile, name='media-xsendfile'),
.....
]
views.py
# add decorators to manage access
#
def media_xsendfile(request, folder='', filename=None, extension=None):
# add an kind of user check ....
# only server certain type of files
if extension in ('jpg', 'png', 'gif'):
response['Content-Type'] = 'image/'+extension
elif extension == 'mp3':
response['Content-Type'] = 'audio/mpeg'
else:
return
if not folder == '':
folder = '/'+folder+'/'
response = HttpResponse()
# this is the part of the response that Apache reacts upon:
response['X-Sendfile'] = smart_str(settings.MEDIA_ROOT + folder + filename + "." + extension)
# need to handover an absolute path to your file to Apache!!
return response
One way to do it is using a so-called X-Sendfile.
In simple words:
User requests URL to get a protected file (so you need to keep your public and protected files separately, and then either proxy a request to Django for protected files, or serve files directly from the apache/nginx if they are public)
Django view decides which file to return based on URL, and checks user permission, etc.
Django returns an HTTP Response with the 'X-Sendfile' header set to the server's file path
The web server finds the file and returns it to the requester
The setup will be different for nginx and apache, according to my findings you need to install mod_xsendfile for apache, nginx supports it out of the box. Hopefully, that helps, ask any additional questions if needed.

Django APPS.PY ignored by Apache2

I have a function in apps.py set to run at Apache boot/restart, however it doesn't and it only works after I pull up the index page.
However, if I use Django's development environment it works perfectly.
APPS.PY
from django.apps import AppConfig
class GpioAppConfig(AppConfig):
name = 'gpio_app'
verbose_name = "My Application"
def ready(self):
from apscheduler.schedulers.background import BackgroundScheduler
from gpio_app.models import Status, ApsScheduler
import gpio_app.scheduler as sched
import logging
logging.basicConfig()
logging.getLogger('apscheduler').setLevel(logging.DEBUG)
sched.cancel_day_schedule()
sched.get_schedule()
sched.daily_sched_update()
sched.add_status_db()
MOD_WSIG 000-default.conf is as follows:
<VirtualHost *:80>
ServerName 127.0.0.1
ServerAlias localhost
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /robots.txt /path/to/mysite.com/static/robots.txt
Alias /favicon.ico /path/to/mysite.com/static/favicon.ico
Alias /static /home/pi/poolprojectdir/static
<Directory /home/pi/poolprojectdir/static>
Require all granted
</Directory>
<Directory /home/pi/poolprojectdir/poolproject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess poolproject python- home=/home/pi/poolprojectdir/venv python-path=/home/pi/poolprojectdir
WSGIProcessGroup poolproject
WSGIScriptAlias / /home/pi/poolprojectdir/poolproject/wsgi.py
Any ideas as to how I get apps.py recognised by Apache2?
The problem is with apache loading your wsgi.py lazily - only after the first request arrives.
See this answer on how to fix this.

ImportError: No module named site deploying Django with mod-wsgi and httpd

I'm trying to deploy a django project on CentOS 7, but I keep getting ImportError: No module named site on my httpd error log.
This is my config file for httpd located at /etc/httpd/conf.d:
<VirtualHost *:8008>
WSGIProcessGroup programa_registos
WSGIDaemonProcess programa_registos python-home=/var/www/html/programa_registos/.env python-path=/var/www/html/programa_registos
Alias /static /var/www/html/programa_registos/static
<Directory /var/www/html/programa_registos/static>
Require all granted
</Directory>
WSGIScriptAlias / /var/www/html/programa_registos/programa_registos/wsgi.py
<Directory /var/www/html/programa_registos/programa_registos>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
My project is located at /var/www/html/programa_registos and my virtualenv at /var/www/html/programa_registos/.env.
Here is my wsgi.py file, located at /var/www/html/programa_registos/programa_registos:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "programa_registos.settings")
application = get_wsgi_application()

import error while trying to run django on apache

I am trying to run my django project on an apache server. I am not running the django project on a virtualenv. I have the following piece of code in views.py where I get an import error saying No module named startInsight every time. The same if I run with python manage.py runserver 0.0.0.0:80 it works prefectly fine.
Error point in views.py:
sys.path.insert(0,"/Insight/scripts")
import startInsight
The following are the configurations I made:-
/etc/apache2/sites-available/000-default.conf:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /web/mysite
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /web/mysite>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Require all granted
</Directory>
Alias /static /web/mysite/mysite/static
<Directory /web/mysite/mysite/static>
Require all granted
</Directory>
<Directory /web/mysite/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess mysite python-path=/usr/bin/python:/web/mysite
WSGIProcessGroup mysite
WSGIScriptAlias / /web/mysite/mysite/wsgi.py
</VirtualHost>
/web/mysite/mysite/wsgi.py:
import os
'''
I tried adding these two lines below. Did not make a difference.
import sys
sys.path.insert(0,"/Insight/scripts")
'''
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
application = get_wsgi_application()
I am not sure what I am doing wrong and would need some guidance.

Pinax & Apache: deliver Attachments only to authenticated users

I want that Apache and Pinax only deliver Attachments to authenticated users.
I found this post, but i can't make it work.
My Apache-conf-file:
WSGIPythonPath /usr/local/bin/python
<VirtualHost *:80>
ServerName www.domain.com
ServerAlias domain.com
WSGIDaemonProcess k-production python-path=/path/to/app/pinax-env/lib/python2.6/site-packages
WSGIProcessGroup k-production
Alias /site_media /path/to/app/cp/site_media
<Directory /path/to/app/cp/site_media>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias /site_media/media/attachments /path/to/app/cp/deploy/pinax.wsgi
<Directory /path/to/app/cp/site_media/media/attachments>
Deny from all
</Directory>
XSendFile On
XSendFileAllowAbove On
WSGIScriptAlias / /path/to/app/cp/deploy/pinax.wsgi
<Directory /path/to/app/cp/deploy>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
and my (still rough) view, that should get called:
#login_required
def sendfile(request, slug):
app, content_object_id, img = slug.split('/')
project_file = get_object_or_404(Attachment, attachment_file = 'attachments/'+slug)
response = HttpResponse()
response['X-Sendfile'] = os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug)
content_type = 'application/octet-stream'
response['Content-Type'] = content_type
response['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug))
return response
Apache throws a 403 no matter if the user is logged in.
Via the develoment-server i can access the view, but no data will get transmitted.
What is wrong?
I was trying to do pretty much exactly the same thing, and the solution turned out to be not using WSGIScriptAlias, and instead using a regular Alias to a directory that defined a wsgi handler. For the view I basically just wrote a wrapper around django.views.static.serve.
My apache conf ended up looking like this:
# myproject
<VirtualHost *:8080>
#DocumentRoot /var/www/myproject/public
ServerName myproject
ErrorLog /var/www/myproject/logs/apache_error_log
CustomLog /var/www/myproject/logs/apache_access_log common
AliasMatch ^/(media/uploads/protected/.*) /var/www/myproject/src/myproject-trunk/server/django.wsgi/$1
Alias /media/ /var/www/myproject/public/media/
Alias / /var/www/myproject/src/myproject-trunk/server/django.wsgi/
<Directory /var/www/myproject/src/myproject-trunk/server>
Options ExecCGI
AddHandler wsgi-script .wsgi
# WSGIApplicationGroup %{GLOBAL}
Order allow,deny
Allow from all
</Directory>
<Directory /var/www/myproject/public/media>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Try to concentrate on the development server first - since it is a simpler setup and thus less error prone.
Perhaps try this:
#login_required def sendfile(request, slug):
## these are never used
# app, content_object_id, img = slug.split('/')
# project_file = get_object_or_404(Attachment, attachment_file = 'attachments/'+slug)
response = HttpResponse()
response['X-Sendfile'] = os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug)
import pdb; pdb.set_trace()
# your development server will stop here
# you can now inspect the your context, e.g.
# >> p response['X-Sendfile']
# this should print the value of response['X-Sendfile']
# >> c
# this will continue program execution
# for more commands see http://www.python.org/doc/2.4/lib/debugger-commands.html
content_type = 'application/octet-stream'
response['Content-Type'] = content_type
# Content-Disposition filename is only for suggesting a name for the file
# when the user tries to download it, e.g.:
# response['Content-Disposition'] = 'attachment; filename='localfile.txt'
response['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug))
return response
But by using the dev server you won't get any files served, since Apache will do the file serving.
You can just ensure, the data sent to apache is correct.
Or use (not recommended for your production server)
f = open(os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug), 'rb')
response = HttpResponse(f.read())
instead of
response = HttpResponse()
response['X-Sendfile'] = os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug)
Some Links:
Similar topic at stackoverflow