El almacenamiento django-pipeline y s3boto no parecen funcionar juntos

Estoy tratando de usar django-pipeline-1.1.27 con s3boto para comprimir y filtrar archivos estáticos, y luego subirlos a un cubo de s3. Si solo uso:

PIPELINE_STORAGE = 'pipeline.storage.PipelineFinderStorage' 

Entonces funciona y obtengo una carpeta estática con el buen archivo versionado que configuré. Tan pronto como me cambie a

 PIPELINE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' 

yo obtengo

 Traceback (most recent call last): File "manage.py", line 15, in  execute_manager(settings) File "/my/virtual/env/lib/python2.7/site-packages/django/core/management/__init__.py", line 438, in execute_manager utility.execute() File "/my/virtual/env/lib/python2.7/site-packages/django/core/management/__init__.py", line 379, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/my/virtual/env/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv self.execute(*args, **options.__dict__) File "/my/virtual/env/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute output = self.handle(*args, **options) File "/my/virtual/env/lib/python2.7/site-packages/pipeline/management/commands/synccompress.py", line 39, in handle packager.pack_stylesheets(package, sync=sync, force=force) File "/my/virtual/env/lib/python2.7/site-packages/pipeline/packager.py", line 52, in pack_stylesheets **kwargs) File "/my/virtual/env/lib/python2.7/site-packages/pipeline/packager.py", line 60, in pack package['output'], package['paths']) File "/my/virtual/env/lib/python2.7/site-packages/pipeline/versioning/__init__.py", line 45, in need_update version = self.version(paths) File "/my/virtual/env/lib/python2.7/site-packages/pipeline/versioning/__init__.py", line 20, in version return getattr(self.versioner, 'version')(paths) File "/my/virtual/env/lib/python2.7/site-packages/pipeline/versioning/hash/__init__.py", line 37, in version buf = self.concatenate(paths) File "/my/virtual/env/lib/python2.7/site-packages/pipeline/versioning/hash/__init__.py", line 27, in concatenate return '\n'.join([self.read_file(path) for path in paths]) File "/my/virtual/env/lib/python2.7/site-packages/pipeline/versioning/hash/__init__.py", line 31, in read_file file = storage.open(path, 'rb') File "/my/virtual/env/lib/python2.7/site-packages/django/core/files/storage.py", line 33, in open file = self._open(name, mode) File "/my/virtual/env/lib/python2.7/site-packages/storages/backends/s3boto.py", line 177, in _open raise IOError('File does not exist: %s' % name) IOError: File does not exist: css/style.css 

que es uno de mis archivos de origen . Entonces, ¿por qué la tubería ya no quiere hacer los pasos de filtro / concatenar / comprimir cuando cambio al almacenamiento de s3boto?

Puede ser que esté haciendo algo. Aquí hay otra configuración en caso de que ayude:

 INSTALLED_APPS = ( ... 'pipeline', 'storages', ) STATICFILES_FINDERS = ( 'pipeline.finders.PipelineFinder', 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) STATIC_ROOT = "/some/path/outside/django_project/deploy_static" STATICFILES_DIRS = () # All statics in this site are in apps STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage' PIPELINE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' PIPELINE = True PIPELINE_AUTO = True PIPELINE_VERSION = True PIPELINE_VERSION_PLACEHOLDER = 'VERSION' PIPELINE_VERSIONING = 'pipeline.versioning.hash.SHA1Versioning' PIPELINE_CSS = { 'standard': { 'source_filenames': ( 'css/style.css', ... ), 'output_filename': 'css/all-VERSION.css', 'extra_context': { 'media': 'screen,projection', }, } } 

Mi sitio está en Django 1.3.1.

El comando que estoy ejecutando es:

 python manage.py synccompress --force 

Las credenciales de AWS también están en la configuración, pero eso es discutible porque ni siquiera está llegando a ese punto.

ACTUALIZACIÓN Pila completa agregada y configuración solicitada en comentarios

ACTUALIZACIÓN A petición del autor de la biblioteca, intenté actualizar a la última versión beta. Observaciones de que hasta ahora:

  1. No sé cómo obtener archivos comprimidos versionados ahora
  2. collectstatic me deja con los archivos comprimidos y los originales.
  3. Sigo recibiendo el mismo error de django-pipeline cuando el almacenamiento de Boto está configurado: quiere enviar mis archivos de origen a s3, pero ni siquiera puedo ver dónde está almacenando mis activos. Nada se coloca en STATIC_ROOT.

ACTUALIZACIÓN He creado el proyecto más simple que funciona para el almacenamiento del buscador y luego se rompe con S3Boto. Lo empujé a github, e incluí una captura del stacktrace.

https://github.com/estebistec/simple_pipeline https://raw.github.com/estebistec/simple_pipeline/master/STACKTRACE

Estaría extasiado si me dijeran que estoy haciendo algo realmente tonto y todo esto debería funcionar.

django-pipeline 1.1.x es un poco tonto acerca de cómo usar los archivos estáticos, prefiere tener todo en un solo lugar. Le sugiero que pruebe django-pipeline 1.2 con los últimos django-staticfiles o django 1.4 .

Usa una costumbre como esta:

 STATICFILES_STORAGE = 'your.app.S3PipelineStorage' 

El código se ve así:

 from staticfiles.storage import CachedFilesMixin from pipeline.storage import PipelineMixin from storages.backends.s3boto import S3BotoStorage class S3PipelineStorage(PipelineMixin, CachedFilesMixin, S3BotoStorage): pass 

Puede encontrar la forma de arreglar su aplicación, pero todavía hay un error con los archivos comstackdos a menos que use la versión 1.2c1: https://gist.github.com/1999564

Acabo de experimentar este mismo error en un proyecto Django 1.6 con django-pipeline==1.3.23 , y la solución fue simplemente eliminando la configuración PIPELINE_STORAGE .

Hay otro problema con un mensaje de error similar que afecta a la versión anterior y actual (1.5.4) de django-pipeline .

El mensaje de error es IOError: File does not exist y ocurre en s3boto.py.open() y packager.pack_stylesheets() . Puede solucionar el problema si utiliza cualquiera de los comstackdores (Compass, Sass, Less, etc.). Sospecho que también afectaría al comstackdor JS, pero no lo he confirmado.

En pocas palabras, el comstackdor genera un archivo de salida en el almacenamiento estático local y, en los próximos pasos, compress está tratando de encontrar la salida en el almacenamiento s3.

Si le afecta, puede echar un vistazo a https://github.com/cyberdelia/django-pipeline/issues/473 . Hay dos solicitudes de extracción (parches), una hecha por skirsdeda y otra hecha por thomasyip (yo). Ambos podrían resolver su problema. Si desea que el archivo comstackdo (pero, previamente comprimido) se copie a s3 y esté disponible para la aplicación, tomará el parche de thomasyip (me).

Aquí está completo Traceback para el problema:

 Traceback (most recent call last): File "apps/manage.py", line 16, in  execute_from_command_line(sys.argv) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line utility.execute() File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv self.execute(*args, **options.__dict__) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute output = self.handle(*args, **options) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/django/core/management/base.py", line 533, in handle return self.handle_noargs(**options) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 171, in handle_noargs collected = self.collect() File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 117, in collect for original_path, processed_path, processed in processor: File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/pipeline/storage.py", line 26, in post_process packager.pack_stylesheets(package) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/pipeline/packager.py", line 96, in pack_stylesheets variant=package.variant, **kwargs) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/pipeline/packager.py", line 106, in pack content = compress(paths, **kwargs) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/pipeline/compressors/__init__.py", line 73, in compress_css css = self.concatenate_and_rewrite(paths, output_filename, variant) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/pipeline/compressors/__init__.py", line 137, in concatenate_and_rewrite content = self.read_text(path) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/pipeline/compressors/__init__.py", line 220, in read_text content = self.read_bytes(path) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/pipeline/compressors/__init__.py", line 214, in read_bytes file = staticfiles_storage.open(path) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/django/core/files/storage.py", line 35, in open return self._open(name, mode) File "/Users/thomas/Dev/Project/main-server/venv/lib/python2.7/site-packages/storages/backends/s3boto.py", line 366, in _open raise IOError('File does not exist: %s' % name) IOError: File does not exist: sheets/sass/sheets.css 

Complementando las respuestas, puede usar GZIP al comprimir:

 from django.contrib.staticfiles.storage import CachedFilesMixin from pipeline.storage import PipelineMixin from storages.backends.s3boto import S3BotoStorage class S3PipelineStorage(PipelineMixin, CachedFilesMixin, S3BotoStorage): def __init__(self, *args, **kwargs): self.gzip = True super(S3PipelineStorage, self).__init__(*args, **kwargs) 

Usando la configuración de la siguiente manera:

 COMPRESS_STORAGE = STATICFILES_STORAGE = 'my.apps.main.S3PipelineStorage' 

No estoy seguro de cómo esto parece funcionar para todos los demás. Seguí la solución anterior y seguí recibiendo el siguiente error:

 Traceback (most recent call last): File "manage.py", line 24, in  execute_from_command_line(sys.argv) File "python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line utility.execute() File "python3.4/site-packages/django/core/management/__init__.py", line 330, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "python3.4/site-packages/django/core/management/base.py", line 390, in run_from_argv self.execute(*args, **cmd_options) File "python3.4/site-packages/django/core/management/base.py", line 441, in execute output = self.handle(*args, **options) File "python3.4/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 168, in handle collected = self.collect() File "python3.4/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 114, in collect for original_path, processed_path, processed in processor: File "python3.4/site-packages/pipeline/storage.py", line 26, in post_process packager.pack_stylesheets(package) File "python3.4/site-packages/pipeline/packager.py", line 96, in pack_stylesheets variant=package.variant, **kwargs) File "python3.4/site-packages/pipeline/packager.py", line 105, in pack paths = self.compile(package.paths, force=True) File "python3.4/site-packages/pipeline/packager.py", line 99, in compile return self.compiler.compile(paths, force=force) File "python3.4/site-packages/pipeline/compilers/__init__.py", line 56, in compile return list(executor.map(_compile, paths)) File "/usr/local/lib/python3.4/concurrent/futures/_base.py", line 549, in result_iterator yield future.result() File "/usr/local/lib/python3.4/concurrent/futures/_base.py", line 402, in result return self.__get_result() File "/usr/local/lib/python3.4/concurrent/futures/_base.py", line 354, in __get_result raise self._exception File "/usr/local/lib/python3.4/concurrent/futures/thread.py", line 54, in run result = self.fn(*self.args, **self.kwargs) File "python3.4/site-packages/pipeline/compilers/__init__.py", line 42, in _compile outdated = compiler.is_outdated(input_path, output_path) File "python3.4/site-packages/pipeline/compilers/__init__.py", line 85, in is_outdated return self.storage.modified_time(infile) > self.storage.modified_time(outfile) File "python3.4/site-packages/storages/backends/s3boto.py", line 480, in modified_time return parse_ts(entry.last_modified) AttributeError: 'NoneType' object has no attribute 'last_modified' 

No fue hasta que encontré esta solución que empecé a encontrar lo que funcionaba para mí. Aquí está el almacenamiento que terminé usando que guardó el archivo localmente, así como en S3, que me hizo pasar todos los errores:

 from django.contrib.staticfiles.storage import ManifestFilesMixin from django.core.files.storage import get_storage_class from pipeline.storage import PipelineMixin from storages.backends.s3boto import S3BotoStorage class StaticStorage(PipelineMixin, ManifestFilesMixin, S3BotoStorage): """Custom storage for static content.""" def __init__(self, *args, **kwargs): super(StaticStorage, self).__init__(*args, **kwargs) self.local_storage = get_storage_class( 'django.contrib.staticfiles.storage.StaticFilesStorage')() def save(self, name, content): name = super(StaticStorage, self).save(name, content) self.local_storage._save(name, content) return name