lirmm / waves-core

WAVES is a reusable web application dedicated to bioinformatic tool integration

Home Page:https://waves-core.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Trying to access job files on results page gives "Assertion error: Model object must be export-able"

bockp opened this issue · comments

After updating our local installation to the new version, we had a few bugs.
Most of them resolved themselves as problems with our server, the wrong user launching crontab add, and other such small but annoying adjustments, and we fixed those after some work.

There are, however, two bugs that I cannot figure out, and that don't seem to come from anything on our end, as far as I've been able to tell.

This issue details one of them.


Expected :

When launching a job, the results page will normally list several files, depending on how one has configured the service.

The Inputs and output files have See Online and Download Files options, that should allow the user to consult the smaller files directly in the browser, or download them if they are too big.

Bug:

Instead of getting access or downloading the file, if I click on one of the above options I get an AssertionError saying the "Model object must be Export-able"

Example:

image

18856940

Traceback:

Environment:


Request Method: GET
Request URL: http://xx.xx.xx.xxx/waves/jobs/outputs/0ffa5f9b-8646-4995-948f-bf0ed4572bc5/

Django Version: 1.11.17
Python Version: 2.7.5
Installed Applications:
[u'polymorphic',
 u'django.contrib.admin',
 u'django.contrib.auth',
 u'django.contrib.contenttypes',
 u'django.contrib.sessions',
 u'django.contrib.messages',
 u'django.contrib.staticfiles',
 u'waves.wcore',
 u'waves.authentication',
 u'crispy_forms',
 u'rest_framework',
 u'corsheaders',
 u'adminsortable2',
 u'django_crontab']
Installed Middleware:
[u'django.middleware.security.SecurityMiddleware',
 u'django.contrib.sessions.middleware.SessionMiddleware',
 u'corsheaders.middleware.CorsMiddleware',
 u'django.middleware.common.CommonMiddleware',
 u'django.middleware.csrf.CsrfViewMiddleware',
 u'django.contrib.auth.middleware.AuthenticationMiddleware',
 u'django.contrib.messages.middleware.MessageMiddleware',
 u'django.middleware.clickjacking.XFrameOptionsMiddleware']

Traceback:

File "/usr/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/lib/python2.7/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "/usr/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
  88.         return handler(request, *args, **kwargs)

File "/srv/waves-core-1.6.5.1/waves/wcore/views/files.py" in get
  33.         assert isinstance(self.object, ExportAbleMixin), ' Model object must be Export-able'

Exception Type: AssertionError at /waves/jobs/outputs/0ffa5f9b-8646-4995-948f-bf0ed4572bc5/
Exception Value: Model object must be Export-able

I've checked, and the files are perfectly fine on the server itself, where I can see their contents.

After some digging, I find that commenting these lines in /waves/wcore/views/files.py returns the expected functionality, letting me access all the results files and logs through the web interface again:

        assert isinstance(self.object, ExportAbleMixin),' Model object must be Export-able'
        self.object.serialize()

These lines seem linked to the ExportAbleMixin class that is imported from /waves/wcore/base.py

class ExportAbleMixin(object):
    """ Some models object may be 'exportable' in order to be imported elsewhere in another WAVES app.
    Based on Django serializer, because we don't want to select fields to export
    """

    def serializer(self, context=None):
        """ Each sub class must implement this method to initialize its Serializer"""
        raise NotImplementedError('Sub classes must implements this method')

    def serialize(self):
        """ Import model object serializer, serialize and write data to disk """
        from os.path import join
        from waves.wcore.settings import waves_settings
        import json
        file_path = join(waves_settings.DATA_ROOT, self.export_file_name)
        with open(file_path, 'w') as fp:
            try:
                serializer = self.serializer()
                data = serializer.to_representation(self)
                fp.write(json.dumps(data, indent=2))
                return file_path
            except Exception as e:
                raise ExportError('Error dumping model {} [{}]'.format(self, e))

    @property
    def export_file_name(self):
        """ Create export file name, based on concrete class name"""
        return '{}_{}.json'.format(self.__class__.__name__.lower(), str(self.pk))

I have yet to figure out exactly why this is posing a problem, but it would seem the objects (be they text files, csv, tsv, png or .zip. All cases in my pipeline that were broken but now work without these commented lines) can't be serialized, and that was what caused the errors.

In any case, commenting the above lines serves as a fix to this problem.
(probably a temporary fix, as there must be a reason why the objects need to be serialized, and just removing the check might break something else).

Fixed from 1.6.6