Given some data from the queue, deserializes it into a ``Task``
        instance.

        The data must be similar in format to what comes from
        ``Task.serialize`` (a JSON-serialized dictionary). Required keys are
        ``task_id``, ``retries`` & ``async``.

        :param data: A JSON-serialized string of the task data
        :type data: string

        :returns: A populated task
        :rtype: A ``Task`` instance

def deserialize(cls, data):
        """
        Given some data from the queue, deserializes it into a ``Task``
        instance.

        The data must be similar in format to what comes from
        ``Task.serialize`` (a JSON-serialized dictionary). Required keys are
        ``task_id``, ``retries`` & ``async``.

        :param data: A JSON-serialized string of the task data
        :type data: string

        :returns: A populated task
        :rtype: A ``Task`` instance
        """
        data = json.loads(data)
        options = data.get('options', {})

        task = cls(
            task_id=data['task_id'],
            retries=data['retries'],
            async=data['async']
        )

        func = import_attr(data['module'], data['callable'])
        task.to_call(func, *data.get('args', []), **data.get('kwargs', {}))

        if options.get('on_start'):
            task.on_start = import_attr(
                options['on_start']['module'],
                options['on_start']['callable']
            )

        if options.get('on_success'):
            task.on_success = import_attr(
                options['on_success']['module'],
                options['on_success']['callable']
            )

        if options.get('on_error'):
            task.on_error = import_attr(
                options['on_error']['module'],
                options['on_error']['callable']
            )

        return task