6

Tengo un problema extraño con MemoryError en mi proyecto Django.Django mod_wsgi MemoryError

  • Ubuntu 11
  • Apache 2
  • Nginx
  • mod_wsgi
  • python2.7

tengo una etiqueta de plantilla que se redimensionar imágenes utilizando PIL y funciona muy bien en mi dev- máquina, pero en producción causa un error 500 con imágenes grandes (~ 800 px). La etiqueta de plantilla parece funcionar sin problemas, pero solo si la imagen original ya es muy pequeña. La etiqueta de plantilla es una versión modificada de http://djangosnippets.org/snippets/1944/

Acabo de intentar recompilar mod_wsgi para python2.7 - el mismo error.

¿Hay alguna forma de asignar más memoria o quizás algo más que simplemente no entiendo?

¡Cualquier ayuda sería muy apreciada!

Rastreo por correo electrónico a mí es:

Traceback (most recent call last): 

    File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 111, in get_response 
     response = callback(request, *callback_args, **callback_kwargs) 

    File "/var/www/rizzyhome.com/www/django/rizzyhome/products/views.py", line 31, in designs 
     context_instance=RequestContext(request) 

    File "/usr/local/lib/python2.7/dist-packages/django/shortcuts/__init__.py", line 20, in render_to_response 
     return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/loader.py", line 188, in render_to_string 
     return t.render(context_instance) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 123, in render 
     return self._render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 117, in _render 
     return self.nodelist.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 744, in render 
     bits.append(self.render_node(node, context)) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 757, in render_node 
     return node.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py", line 127, in render 
     return compiled_parent._render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 117, in _render 
     return self.nodelist.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 744, in render 
     bits.append(self.render_node(node, context)) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 757, in render_node 
     return node.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py", line 127, in render 
     return compiled_parent._render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 117, in _render 
     return self.nodelist.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 744, in render 
     bits.append(self.render_node(node, context)) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 757, in render_node 
     return node.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py", line 64, in render 
     result = block.nodelist.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 744, in render 
     bits.append(self.render_node(node, context)) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 757, in render_node 
     return node.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py", line 64, in render 
     result = block.nodelist.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 744, in render 
     bits.append(self.render_node(node, context)) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 757, in render_node 
     return node.render(context) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py", line 227, in render 
     nodelist.append(node.render(context)) 

    File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 885, in render 
     return func(*func_args) 

    File "/var/www/rizzyhome.com/www/django/rizzyhome/products/templatetags/yair.py", line 108, in thumbnail 
     import Image, ImageOps 

    File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 45, in <module> 
     __import__("FixTk") 

    File "/usr/lib/python2.7/lib-tk/FixTk.py", line 15, in <module> 
     import ctypes 

    File "/usr/lib/python2.7/ctypes/__init__.py", line 549, in <module> 
     CFUNCTYPE(c_int)(lambda: None) 

    MemoryError 

Editar: Adición de código

import os, errno 

from django import template 
from django.conf import settings 

register = template.Library() 

def _mkdir_p(path): 
    try: 
     os.makedirs(path) 
    except OSError as exc: # Python >2.5 
     if exc.errno == errno.EEXIST: 
      pass 
     else: raise 

@register.simple_tag 
def thumbnail(image_url, width, height, THIS_ROOT=settings.MEDIA_ROOT, THIS_URL=settings.MEDIA_URL, img_w=None, img_h=None, method="crop"): 
    """ 
    Given the url to an image, resizes the image using the given width and 
    height on the first time it is requested, and returns the url to the new 
    resized image. If width or height are zero then the original ratio is 
    maintained. 
    """ 

    if not img_w: 
     img_w = width 

    if not img_h: 
     img_w = height 

    image_url = unicode(image_url) 

    # determine new paths 
    resized_image_reduced = os.path.join('_resized_', image_url.replace(THIS_ROOT, '')) 

    file_name, file_ext = os.path.basename(resized_image_reduced).split(os.extsep) 
    resized_image_absolute_path = os.path.join(
     THIS_ROOT, 
     os.path.dirname(resized_image_reduced), 
     u'%s__%05d-%05d_%s%s%s' % (file_name, width, height, method, os.extsep, file_ext) 
    ) 
    resized_image_relative_url = os.path.join(
     THIS_URL, 
     os.path.dirname(resized_image_reduced), 
     u'%s__%05d-%05d_%s%s%s' % (file_name, width, height, method, os.extsep, file_ext) 
    ) 

    # make sure target directory exists 
    _mkdir_p(os.path.realpath(os.path.dirname(resized_image_absolute_path))) 

    # abort if thumbnail exists, original image doesn't exist, invalid width or 
    # height are given, or PIL not installed, or thumbnail is newer than source image 
    if os.path.exists(resized_image_absolute_path): 
     if os.path.exists(image_url): 
      if os.path.getmtime(resized_image_absolute_path) > os.path.getmtime(image_url): 
       return resized_image_relative_url 
     else: 
      return resized_image_relative_url 
    if not image_url: 
     return "" 

    try: 
     width = int(width) 
     height = int(height) 
    except ValueError: 
     return resized_image_relative_url 

    if not os.path.exists(image_url) or (width == 0 and height == 0): 
     return image_url 

    try: 
     from PIL import Image, ImageOps 
    except ImportError: 
     return resized_image_relative_url 

    # open image, determine ratio if required and resize/crop/save 
    image = Image.open(image_url) 
    if width == 0: 
     width = image.size[0] * height/image.size[1] 
    elif height == 0: 
     height = image.size[1] * width/image.size[0] 
    if image.mode not in ("L", "RGB"): 
     image = image.convert("RGB") 

    try: 
     if method == 'scale': 

      image.thumbnail((width, height), Image.ANTIALIAS) 


      new_w, new_h = image.size 

      x1 = (img_w-new_w) /2 
      y1 = (img_h-new_h) 

      new_image = Image.new(image.mode, (img_w, img_h), (255,255,255)) 
      new_image.paste(image, (x1,y1)) 

      new_image.save(
       resized_image_absolute_path, 
       "JPEG", 
       quality=100 
      ) 

     elif method == 'crop': 
      image = ImageOps.fit(image, (width, height), Image.ANTIALIAS) 
      image.save(
       resized_image_absolute_path, 
       "JPEG", 
       quality=100 
      ) 

    except Exception, e: 
     raise 
     return resized_image_relative_url 

    return resized_image_relative_url 
+0

Publique el código real. – agf

+0

Agregué mi guión (modificado) a mi publicación original, ¡gracias! – sframe

+0

¿Está ejecutando SELinux en producción? Hay algunos problemas conocidos con ctypes en algunas plataformas con selinux habilitado: http://stackoverflow.com/questions/3762566/occasional-ctypes-error-importing-numpy-from-mod-wsgi-django-app – GDorn

Respuesta

2

Muchas gracias por sus comentarios y ofrecer ayuda.

Aparentemente hay un error extraño en el __init__.py para el módulo CTYPE. - o lo que sea, acabo de leerlo :)

La solución, al menos para mí, era comentar la última línea en el archivo __init__.py. Parece que la última línea es específicamente para Windows 64bit y está estropeando mi Ubuntu.

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=598727#38

+0

Acabo de encontrar esto en Python 2.7.3 al intentar implementar un sitio Mezzanine en bluehost. Esto fue una gran sorpresa porque nunca es un error en el código que uno está usando, es un error en el código de uno. Gracias por publicar esta pregunta. – Feanor

Cuestiones relacionadas