Django Sass Compressor django_libsass.SassCompiler: command not found

moshushi picture moshushi · Mar 19, 2014 · Viewed 7.1k times · Source

I'm using a Django-Compressor Filter as part of Wagtail (Django variant CMS with super cool UI). Environment is Wagtail 0.2 + Python 2.7 + Django 1.6 + Virtualenv + FastCGI + Apache shared hosting.

Issue occurs when trying to access admin/login page of the CMS. Django shows an Error rendering template

    Error during template rendering

In template /home/username/env/lib/python2.7/site-packages/wagtail/wagtailadmin/templates/wagtailadmin/skeleton.html, error at line 20
/bin/sh: django_libsass.SassCompiler: command not found

Line 20 of the skeleton.html is:

    <!doctype html>
    {% load compress %}
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"  lang="{{ LANGUAGE_CODE|default:"en-gb" }}"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"  lang="{{ LANGUAGE_CODE|default:"en-gb" }}"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"  lang="{{ LANGUAGE_CODE|default:"en-gb" }}"> <![endif]-->
    <!--[if gt IE 8]><!--> <html class="no-js"  lang="{{ LANGUAGE_CODE|default:"en-gb" }}"> <!--<![endif]-->
        <title>Wagtail - {% block titletag %}{% endblock %}</title>
        <meta name="description" content="" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />

        <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>

        {% block css %}{# Block defined for timing breakdowns in django debug toolbar - not expected to be overridden #}
            <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" />
            <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Bitter:400,700" /> 
19          
20          {% compress css %}
21              <link rel="stylesheet" href="{{ STATIC_URL }}wagtailadmin/scss/normalize.css" />
                <link rel="stylesheet" href="{{ STATIC_URL }}wagtailadmin/scss/vendor/jquery-ui/jquery-ui-1.10.3.verdant.css" />
                <link rel="stylesheet" href="{{ STATIC_URL }}wagtailadmin/scss/vendor/jquery.timepicker.css" />
                <link rel="stylesheet" href="{{ STATIC_URL }}wagtailadmin/scss/core.scss" type="text/x-scss" />
            {% endcompress %}

            {% block extra_css %}{% endblock %}
        {% endblock %}
    </head>
    <body class="{% block bodyclass %}{% endblock %} {% if messages %}has-messages{% endif %}">

the precompiler in my settings.py, DEBUG is set to True:

COMPRESS_ENABLED = True

COMPRESS_PRECOMPILERS = ( 
     ('text/x-scss', 'django_libsass.SassCompiler'), 
)

TRIAL AND ERROR #1

I've tried changing to:

('text/x-scss', '/home/username/env/lib/python2.7/site-packages/django_libsass {infile} {outfile}')

but that leads me to a dictionary update sequence element #0 error.

I have django_libsass & compressor installed, also tried pip install libsass, ngm install lessc, pip install sass, turning DEBUG = False, adding COMPRESSOR_OFFLINE, adding COMPRESSOR_ENABLED as suggested in other similar questions. Running manage.py compress returns the same error.

Have rechecked and site-packages and django_libsass are indeed on my sys.path

SassCompiler can be found in ~/env/lib/python2.7/site-packages/django_libsass.py

TRIAL AND ERROR #2

Re-checked that sass is installed and on my path.

Change code to:

COMPRESS_PRECOMPILERS = ( 
     ('text/x-scss', 'sass --scss {infile} {outfile}'), 
 )

Returns error:

Exception Type: FilterError
Exception Value:    
/bin/sh: sass: command not found

TRIAL AND ERROR #3

After reading this feedly issue, tried pip install compass to no effect

TRIAL AND ERROR #4

Following gasman's comment, I ran python manage.py shell and tried to import SassCompiler It works with no errors.

 Python 2.7.6 (default, Nov 11 2013, 18:34:29) 
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>> from django_libsass import SassCompiler
    >>> 

Full Traceback

I do apologize if this question is getting too long.

Traceback:
File "/home/username/env/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  139.                 response = response.render()
File "/home/username/env/lib/python2.7/site-packages/django/template/response.py" in render
  105.             self.content = self.rendered_content
File "/home/username/env/lib/python2.7/site-packages/django/template/response.py" in rendered_content
  82.         content = template.render(context)
File "/home/username/env/lib/python2.7/site-packages/django/template/base.py" in render
  140.             return self._render(context)
File "/home/username/env/lib/python2.7/site-packages/django/template/base.py" in _render
  134.         return self.nodelist.render(context)
File "/home/username/env/lib/python2.7/site-packages/django/template/base.py" in render
  840.                 bit = self.render_node(node, context)
File "/home/username/env/lib/python2.7/site-packages/django/template/debug.py" in render_node
  78.             return node.render(context)
File "/home/username/env/lib/python2.7/site-packages/django/template/loader_tags.py" in render
  123.         return compiled_parent._render(context)
File "/home/username/env/lib/python2.7/site-packages/django/template/base.py" in _render
  134.         return self.nodelist.render(context)
File "/home/username/env/lib/python2.7/site-packages/django/template/base.py" in render
  840.                 bit = self.render_node(node, context)
File "/home/username/env/lib/python2.7/site-packages/django/template/debug.py" in render_node
  78.             return node.render(context)
File "/home/username/env/lib/python2.7/site-packages/django/template/loader_tags.py" in render
  62.             result = block.nodelist.render(context)
File "/home/username/env/lib/python2.7/site-packages/django/template/base.py" in render
  840.                 bit = self.render_node(node, context)
File "/home/username/env/lib/python2.7/site-packages/django/template/debug.py" in render_node
  78.             return node.render(context)
File "/home/username/env/lib/python2.7/site-packages/compressor/templatetags/compress.py" in render
  147.         return self.render_compressed(context, self.kind, self.mode, forced=forced)
File "/home/username/env/lib/python2.7/site-packages/compressor/templatetags/compress.py" in render_compressed
  107.             rendered_output = self.render_output(compressor, mode, forced=forced)
File "/home/username/env/lib/python2.7/site-packages/compressor/templatetags/compress.py" in render_output
  119.         return compressor.output(mode, forced=forced)
File "/home/username/env/lib/python2.7/site-packages/compressor/css.py" in output
  51.                     ret.append(subnode.output(*args, **kwargs))
File "/home/username/env/lib/python2.7/site-packages/compressor/css.py" in output
  53.         return super(CssCompressor, self).output(*args, **kwargs)
File "/home/username/env/lib/python2.7/site-packages/compressor/base.py" in output
  246.         content = self.filter_input(forced)
File "/home/username/env/lib/python2.7/site-packages/compressor/base.py" in filter_input
  194.         for hunk in self.hunks(forced):
File "/home/username/env/lib/python2.7/site-packages/compressor/base.py" in hunks
  169.                 precompiled, value = self.precompile(value, **options)
File "/home/username/env/lib/python2.7/site-packages/compressor/base.py" in precompile
  226.                                 **kwargs)
File "/home/username/env/lib/python2.7/site-packages/django_libsass.py" in input
  51.             return compile(filename=self.filename)
File "/home/username/env/lib/python2.7/site-packages/django_libsass.py" in compile
  41.     return sass.compile(**kwargs)

Exception Type: AttributeError at /admin/login/
Exception Value: 'module' object has no attribute 'compile'

Answer

gasman picture gasman · Mar 24, 2014

(Reposting my comments as an answer, as requested...)

The original error: django_libsass.SassCompiler: command not found

meant that it was failing to import the django-libsass library. (django-compressor responded to that failure by trying to treat it as a shell command instead - django_libsass is not a runnable command, so this failed too, giving the actual error seen here.) The solution is to ensure that django-libsass is installed - it should show up in the output of pip freeze.

The second error: 'module' object has no attribute 'compile'

meant that there was another package installed which defined a module called sass, and this was being loaded in place of the one we wanted, from the libsass package. The solution is to uninstall all sass-related packages apart from django-libsass and libsass.