Example #1
0
    def evaluate(self, data):
        """Evaluate the code needed to compute a given Data object."""
        try:
            inputs = copy.deepcopy(data.input)
            hydrate_input_references(inputs, data.process.input_schema)
            hydrate_input_uploads(inputs, data.process.input_schema)

            # Include special 'proc' variable in the context.
            inputs["proc"] = {
                "data_id": data.id,
                "data_dir": self.manager.get_executor().resolve_data_path(),
            }

            # Include special 'requirements' variable in the context.
            inputs["requirements"] = data.process.requirements
            # Inject default values and change resources according to
            # the current Django configuration.
            inputs["requirements"]["resources"] = data.process.get_resource_limits()

            script_template = data.process.run.get("program", "")

            # Get the appropriate expression engine. If none is defined, do not evaluate
            # any expressions.
            expression_engine = data.process.requirements.get("expression-engine", None)
            if not expression_engine:
                return script_template

            return self.get_expression_engine(expression_engine).evaluate_block(
                script_template, inputs, escape=self._escape, safe_wrapper=SafeString,
            )
        except EvaluationError as error:
            raise ExecutionError("{}".format(error))
Example #2
0
    def evaluate(self, data):
        """Evaluate the code needed to compute a given Data object."""
        try:
            inputs = copy.deepcopy(data.input)
            hydrate_input_references(inputs, data.process.input_schema)
            hydrate_input_uploads(inputs, data.process.input_schema)

            # Include special 'proc' variable in the context.
            inputs['proc'] = {
                'data_id': data.id,
                'data_dir': settings.FLOW_EXECUTOR['DATA_DIR'],
            }

            # Include special 'requirements' variable in the context.
            inputs['requirements'] = data.process.requirements

            script_template = data.process.run.get('program', '')

            # Get the appropriate expression engine. If none is defined, do not evaluate
            # any expressions.
            expression_engine = data.process.requirements.get(
                'expression-engine', None)
            if not expression_engine:
                return script_template

            return self.get_expression_engine(
                expression_engine).evaluate_block(
                    script_template,
                    inputs,
                    escape=self._escape,
                    safe_wrapper=SafeString,
                )
        except EvaluationError as error:
            raise ExecutionError('{}'.format(error))
Example #3
0
    def prepare_runtime(self, runtime_dir, data):
        """Prepare runtime directory."""
        # Copy over Python process runtime (resolwe.process).
        import resolwe.process as runtime_package

        src_dir = os.path.dirname(inspect.getsourcefile(runtime_package))
        dest_package_dir = os.path.join(runtime_dir, PYTHON_RUNTIME_DIRNAME,
                                        'resolwe', 'process')
        shutil.copytree(src_dir, dest_package_dir)
        os.chmod(dest_package_dir, 0o755)

        # Write python source file.
        source = data.process.run.get('program', '')
        program_path = os.path.join(runtime_dir, PYTHON_PROGRAM_FILENAME)
        with open(program_path, 'w') as file:
            file.write(source)
        os.chmod(program_path, 0o755)

        # Write serialized inputs.
        inputs = copy.deepcopy(data.input)
        hydrate_input_references(inputs, data.process.input_schema)
        hydrate_input_uploads(inputs, data.process.input_schema)
        inputs_path = os.path.join(runtime_dir, PYTHON_INPUTS_FILENAME)

        # XXX: Skip serialization of LazyStorageJSON. We should support
        # LazyStorageJSON in Python processes on the new communication protocol
        def default(obj):
            """Get default value."""
            class_name = obj.__class__.__name__
            if class_name == 'LazyStorageJSON':
                return ''

            raise TypeError(
                f'Object of type {class_name} is not JSON serializable')

        with open(inputs_path, 'w') as file:
            json.dump(inputs, file, default=default)

        # Write serialized requirements.
        # Include special 'requirements' variable in the context.
        requirements = copy.deepcopy(data.process.requirements)
        # Inject default values and change resources according to
        # the current Django configuration.
        requirements['resources'] = data.process.get_resource_limits()
        requirements_path = os.path.join(runtime_dir,
                                         PYTHON_REQUIREMENTS_FILENAME)

        with open(requirements_path, 'w') as file:
            json.dump(requirements, file)

        # Generate volume maps required to expose needed files.
        volume_maps = {
            PYTHON_RUNTIME_DIRNAME: PYTHON_RUNTIME_VOLUME,
            PYTHON_PROGRAM_FILENAME: PYTHON_PROGRAM_VOLUME,
            PYTHON_INPUTS_FILENAME: PYTHON_INPUTS_VOLUME,
            PYTHON_REQUIREMENTS_FILENAME: PYTHON_REQUIREMENTS_VOLUME,
        }

        return volume_maps
Example #4
0
def input_(data, field_path):
    """Return a hydrated value of the ``input`` field."""
    data_obj = Data.objects.get(id=data["__id"])

    inputs = copy.deepcopy(data_obj.input)
    # XXX: Optimize by hydrating only the required field (major refactoring).
    hydrate_input_references(inputs, data_obj.process.input_schema)
    hydrate_input_uploads(inputs, data_obj.process.input_schema)

    return dict_dot(inputs, field_path)