Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I/O operation on closed file Error when using imagekit #404

Closed
calmyoga opened this issue Feb 16, 2017 · 2 comments
Closed

I/O operation on closed file Error when using imagekit #404

calmyoga opened this issue Feb 16, 2017 · 2 comments

Comments

@calmyoga
Copy link
Contributor

I am using imagekit with djangorestframework and get below exception:
Traceback (most recent call last):
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/rest_framework/viewsets.py", line 83, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/rest_framework/views.py", line 477, in dispatch
response = self.handle_exception(exc)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/rest_framework/views.py", line 474, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/rest_framework/mixins.py", line 21, in create
self.perform_create(serializer)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/rest_framework/mixins.py", line 26, in perform_create
serializer.save()
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/rest_framework/serializers.py", line 214, in save
self.instance = self.create(validated_data)
File "/Users/rsuri/espressive/src/django/espressive/espuser/serializers.py", line 232, in create
return super(ProfileImageSerializer, self).create(validated_data)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/rest_framework/serializers.py", line 902, in create
instance = ModelClass.objects.create(**validated_data)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/query.py", line 399, in create
obj.save(force_insert=True, using=self.db)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/base.py", line 796, in save
force_update=force_update, update_fields=update_fields)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/base.py", line 824, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/base.py", line 908, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/base.py", line 947, in _do_insert
using=using, raw=raw)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/query.py", line 1045, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1053, in execute_sql
for sql, params in self.as_sql():
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1006, in as_sql
for obj in self.query.objs
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 955, in pre_save_val
return field.pre_save(obj, add=True)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/fields/files.py", line 292, in pre_save
file.save(file.name, file, save=False)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/imagekit/models/fields/files.py", line 12, in save
content = generate(spec)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/imagekit/utils.py", line 134, in generate
content = generator.generate()
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/imagekit/specs/init.py", line 153, in generate
self.source.open()
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/db/models/fields/files.py", line 81, in open
self.file.open(mode)
File "/Users/rsuri/espressive/src/esp/lib/python2.7/site-packages/django/core/files/uploadedfile.py", line 96, in open
self.file.seek(0)
ValueError: I/O operation on closed file.

On debugging this issue I found that in specs/init.py at line number 159, file gets closed even if the it was not opened in this path.

@calmyoga
Copy link
Contributor Author

here is the proposed fix:
diff --git a/imagekit/specs/init.py b/imagekit/specs/init.py
index 829dce1..5ea7856 100644
--- a/imagekit/specs/init.py
+++ b/imagekit/specs/init.py
@@ -145,18 +145,21 @@ class ImageSpec(BaseImageSpec):

     # TODO: Move into a generator base class
     # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.)
  •    file_opened_locally = False
       try:
           img = open_image(self.source)
       except ValueError:
    
           # Re-open the file -- https://code.djangoproject.com/ticket/13750
           self.source.open()
    
  •        file_opened_locally = True
           img = open_image(self.source)
    
       new_image =  process_image(img, processors=self.processors,
                                  format=self.format, autoconvert=self.autoconvert,
                                  options=self.options)
    
  •    self.source.close()
    
  •    if file_opened_locally:
    
  •        self.source.close()
       return new_image
    

@calmyoga
Copy link
Contributor Author

pull request is at 732f704

vstoykov added a commit that referenced this issue Feb 16, 2017
Close the file only if it has been opened locally

Fixed #404
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant