Commit 774d77a8 authored by robert.vincze's avatar robert.vincze

TVB-2587: Solved task. Added support for Uploaders to launch_operation.

TVB-2587: Separated the file saving and obtaining the temp folder to facilitate multi-file requests

TVB-2587: Added generic get_file_type method for uploaders

TVB-2587: Added generic get_upload_files_name method for UploaderViewModel

TVB-2587: Adapter importers to facilitate launch upload operation in TVB Rest

TVB-2587: Add TODO for Gifti parser

TVB-2587: Added new function to test if a file exists in the request because it is intented to be used in operation_resource as well now

TVB-2587: Extracted some duplicated code for handling the 2 data files of uploaders in handle_data_file

TVB-2587: Added extra code to support uploaders in launch_operation

TVB-2587: Corrected a few minor errors. Everything is fine now.

TVB-2587: Moved obtaining file types to view models, generalized obtaining file name with os.path.basename and added getattr instead of eval

TVB-2587: Extended launch_operation to client-side.

TVB-2587: Corrected this

TVB-2587: Removed unnecessary imports
parent ccbd5093
......@@ -56,13 +56,21 @@ class BRCOImporterModel(UploaderViewModel):
doc='The Connectivity for which these annotations were made'
)
@staticmethod
def get_files_types():
return ['.xml']
@staticmethod
def get_upload_files_names():
return ['data_file']
class BRCOImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(BRCOImporterForm, self).__init__(prefix, project_id)
self.data_file = TraitUploadField(BRCOImporterModel.data_file, '.xml', self, name='data_file')
self.data_file = TraitUploadField(BRCOImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
self.connectivity = TraitDataTypeSelectField(BRCOImporterModel.connectivity, self, name='connectivity')
@staticmethod
......
......@@ -66,13 +66,21 @@ class ConnectivityMeasureImporterModel(UploaderViewModel):
doc='The Connectivity for which these measurements were made'
)
@staticmethod
def get_files_types():
return ['.mat']
@staticmethod
def get_upload_files_names():
return ['data_file']
class ConnectivityMeasureImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(ConnectivityMeasureImporterForm, self).__init__(prefix, project_id)
self.data_file = TraitUploadField(ConnectivityMeasureImporterModel.data_file, '.mat', self, name='data_file')
self.data_file = TraitUploadField(ConnectivityMeasureImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
self.dataset_name = StrField(ConnectivityMeasureImporterModel.dataset_name, self, name='dataset_name')
self.connectivity = TraitDataTypeSelectField(ConnectivityMeasureImporterModel.connectivity, self,
name='connectivity')
......
......@@ -139,16 +139,24 @@ class CSVConnectivityImporterModel(UploaderViewModel):
label='Reference Connectivity Matrix (for node labels, 3d positions etc.)'
)
@staticmethod
def get_files_types():
return ['.csv', '.csv']
@staticmethod
def get_upload_files_names():
return ['weights', 'tracts']
class CSVConnectivityImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(CSVConnectivityImporterForm, self).__init__(prefix, project_id)
self.weights = TraitUploadField(CSVConnectivityImporterModel.weights, '.csv', self, name='weights')
self.weights = TraitUploadField(CSVConnectivityImporterModel.weights, self.get_view_model().get_files_types()[0], self, name='weights')
self.weights_delimiter = SelectField(CSVConnectivityImporterModel.weights_delimiter, self,
name='weights_delimiter', choices=DELIMITER_OPTIONS)
self.tracts = TraitUploadField(CSVConnectivityImporterModel.tracts, '.csv', self, name='tracts')
self.tracts = TraitUploadField(CSVConnectivityImporterModel.tracts, [self.get_view_model().get_files_types()[1]], self, name='tracts')
self.tracts_delimiter = SelectField(CSVConnectivityImporterModel.tracts_delimiter, self,
name='tracts_delimiter', choices=DELIMITER_OPTIONS)
self.input_data = TraitDataTypeSelectField(CSVConnectivityImporterModel.input_data, self, name='input_data')
......
......@@ -161,7 +161,7 @@ class GIFTIParser(object):
return time_series, data_arrays
# TODO: data_file_part2 should be optional and if it's not given, then it should be None, but it is actually taken as '' from h5 file, so it acts as if it is required
def parse(self, data_file, data_file_part2=None, surface_type=OPTION_READ_METADATA, should_center=False):
"""
Parse NIFTI file(s) and returns A Surface or a TimeSeries for it.
......
......@@ -72,6 +72,14 @@ class GIFTISurfaceImporterModel(UploaderViewModel):
label='Center surface using vertex means along axes'
)
@staticmethod
def get_files_types():
return ['.gii', '.gii']
@staticmethod
def get_upload_files_names():
return ['data_file', 'data_file_part2']
class GIFTISurfaceImporterForm(ABCUploaderForm):
......@@ -80,8 +88,8 @@ class GIFTISurfaceImporterForm(ABCUploaderForm):
self.file_type = SelectField(GIFTISurfaceImporterModel.file_type, self, name='file_type',
choices=GIFTISurfaceImporterModel.surface_types)
self.data_file = TraitUploadField(GIFTISurfaceImporterModel.data_file, '.gii', self, name='data_file')
self.data_file_part2 = TraitUploadField(GIFTISurfaceImporterModel.data_file_part2, '.gii', self,
self.data_file = TraitUploadField(GIFTISurfaceImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
self.data_file_part2 = TraitUploadField(GIFTISurfaceImporterModel.data_file_part2, self.get_view_model().get_files_types()[1], self,
name='data_file_part2')
self.should_center = BoolField(GIFTISurfaceImporterModel.should_center, self, name='should_center')
......
......@@ -59,13 +59,21 @@ class GIFTITimeSeriesImporterModel(UploaderViewModel):
doc='The Brain Surface used to generate imported TimeSeries.'
)
@staticmethod
def get_files_types():
return ['.gii']
@staticmethod
def get_upload_files_names():
return ['data_file']
class GIFTITimeSeriesImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(GIFTITimeSeriesImporterForm, self).__init__(prefix, project_id)
self.data_file = TraitUploadField(GIFTITimeSeriesImporterModel.data_file, '.gii', self, name='data_file')
self.data_file = TraitUploadField(GIFTITimeSeriesImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
surface_conditions = FilterChain(fields=[FilterChain.datatype + '.surface_type'], operations=["=="],
values=['Cortical Surface'])
self.surface = TraitDataTypeSelectField(GIFTITimeSeriesImporterModel.surface, self, name='surface',
......
......@@ -104,12 +104,20 @@ class RegionMatTimeSeriesImporterModel(UploaderViewModel):
label='Connectivity'
)
@staticmethod
def get_files_types():
return ['.mat']
@staticmethod
def get_upload_files_names():
return ['data_file']
class RegionMatTimeSeriesImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(RegionMatTimeSeriesImporterForm, self).__init__(prefix, project_id)
self.data_file = TraitUploadField(RegionMatTimeSeriesImporterModel.data_file, '.mat', self, name='data_file')
self.data_file = TraitUploadField(RegionMatTimeSeriesImporterModel.data_file, RegionMatTimeSeriesImporterModel.get_files_types()[0], self, name='data_file')
self.dataset_name = StrField(RegionMatTimeSeriesImporterModel.dataset_name, self, name='dataset_name')
self.structure_path = StrField(RegionMatTimeSeriesImporterModel.structure_path, self, name='structure_path')
self.transpose = BoolField(RegionMatTimeSeriesImporterModel.transpose, self, name='transpose')
......
......@@ -91,12 +91,20 @@ class NetworkxImporterModel(UploaderViewModel):
label='Key Node Hemisphere'
)
@staticmethod
def get_files_types():
return ['.gpickle']
@staticmethod
def get_upload_files_names():
return ['data_file']
class NetworkxConnectivityImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(NetworkxConnectivityImporterForm, self).__init__(prefix, project_id)
self.data_file = TraitUploadField(NetworkxImporterModel.data_file, '.gpickle', self, name='data_file')
self.data_file = TraitUploadField(NetworkxImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
self.key_edge_weight = StrField(NetworkxImporterModel.key_edge_weight, self, name='key_edge_weight')
self.key_edge_tract = StrField(NetworkxImporterModel.key_edge_tract, self, name='key_edge_tract')
self.key_node_coordinates = StrField(NetworkxImporterModel.key_node_coordinates, self,
......
......@@ -86,15 +86,23 @@ class NIFTIImporterModel(UploaderViewModel):
doc='Optional Connectivity if the NII file is a volume2regions mapping'
)
@staticmethod
def get_files_types():
return [('.nii', '.gz', '.zip'), '.txt']
@staticmethod
def get_upload_files_names():
return ['data_file', 'mappings_file']
class NIFTIImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(NIFTIImporterForm, self).__init__(prefix, project_id)
self.data_file = TraitUploadField(NIFTIImporterModel.data_file, '.nii, .gz, .zip', self, name='data_file')
self.data_file = TraitUploadField(NIFTIImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
self.apply_corrections = BoolField(NIFTIImporterModel.apply_corrections, self, name='apply_corrections')
self.mappings_file = TraitUploadField(NIFTIImporterModel.mappings_file, '.txt', self, name='mappings_file')
self.mappings_file = TraitUploadField(NIFTIImporterModel.mappings_file, self.get_view_model().get_files_types()[1], self, name='mappings_file')
self.connectivity = TraitDataTypeSelectField(NIFTIImporterModel.connectivity, self, name='connectivity')
@staticmethod
......
......@@ -63,6 +63,14 @@ class ObjSurfaceImporterModel(UploaderViewModel):
label='Center surface using vertex means along axes'
)
@staticmethod
def get_files_types():
return ['.obj']
@staticmethod
def get_upload_files_names():
return ['data_file']
class ObjSurfaceImporterForm(ABCUploaderForm):
......@@ -71,7 +79,7 @@ class ObjSurfaceImporterForm(ABCUploaderForm):
self.surface_type = SelectField(ObjSurfaceImporterModel.surface_type, self, name='surface_type',
choices=ALL_SURFACES_SELECTION)
self.data_file = TraitUploadField(ObjSurfaceImporterModel.data_file, '.obj', self, name='data_file')
self.data_file = TraitUploadField(ObjSurfaceImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
self.should_center = BoolField(ObjSurfaceImporterModel.should_center, self, name='should_center')
@staticmethod
......
......@@ -89,12 +89,20 @@ class ProjectionMatrixImporterModel(UploaderViewModel):
doc='The Sensors used in for current projection.'
)
@staticmethod
def get_files_types():
return [('.mat', '.npy')]
@staticmethod
def get_upload_files_names():
return ['projection_file']
class ProjectionMatrixImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(ProjectionMatrixImporterForm, self).__init__(prefix, project_id)
self.projection_file = TraitUploadField(ProjectionMatrixImporterModel.projection_file, '.mat, .npy', self,
self.projection_file = TraitUploadField(ProjectionMatrixImporterModel.projection_file, self.get_view_model().get_files_types()[0], self,
name='projection_file')
self.dataset_name = StrField(ProjectionMatrixImporterModel.dataset_name, self, name='dataset_name')
surface_conditions = FilterChain(fields=[FilterChain.datatype + '.surface_type'], operations=['=='],
......
......@@ -71,13 +71,21 @@ class RegionMappingImporterModel(UploaderViewModel):
required=True, doc='The Connectivity used by uploaded region mapping.'
)
@staticmethod
def get_files_types():
return [('.txt', '.zip', '.bz2')]
@staticmethod
def get_upload_files_names():
return ['mapping_file']
class RegionMappingImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(RegionMappingImporterForm, self).__init__(prefix, project_id)
self.mapping_file = TraitUploadField(RegionMappingImporterModel.mapping_file, '.txt, .zip, .bz2', self,
self.mapping_file = TraitUploadField(RegionMappingImporterModel.mapping_file, self.get_view_model().get_files_types()[0], self,
name='mapping_file')
surface_conditions = FilterChain(fields=[FilterChain.datatype + '.surface_type'], operations=['=='],
values=[CORTICAL])
......
......@@ -60,13 +60,21 @@ class SensorsImporterModel(UploaderViewModel):
default=tuple(OPTIONS.values())[0]
)
@staticmethod
def get_files_types():
return [('.txt', '.bz2')]
@staticmethod
def get_upload_files_names():
return ['sensors_file']
class SensorsImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(SensorsImporterForm, self).__init__(prefix, project_id)
self.sensors_file = TraitUploadField(SensorsImporterModel.sensors_file, 'text/plain, .bz2', self,
self.sensors_file = TraitUploadField(SensorsImporterModel.sensors_file, self.get_view_model().get_files_types()[0], self,
name='sensors_file')
self.sensors_type = SelectField(SensorsImporterModel.sensors_type, self, name='sensors_type',
choices=SensorsImporterModel.OPTIONS)
......
......@@ -71,13 +71,21 @@ class TrackImporterModel(UploaderViewModel):
label='Reference Volume Map'
)
@staticmethod
def get_files_types():
return ['.trk']
@staticmethod
def get_upload_files_names():
return ['data_file']
class TrackImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(TrackImporterForm, self).__init__(prefix, project_id)
self.data_file = TraitUploadField(TrackImporterModel.data_file, '.trk', self, name='data_file')
self.data_file = TraitUploadField(TrackImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
self.region_volume = TraitDataTypeSelectField(TrackImporterModel.region_volume, self, name='region_volume')
@staticmethod
......
......@@ -52,13 +52,21 @@ class TVBImporterModel(UploaderViewModel):
label='Please select file to import (h5 or zip)'
)
@staticmethod
def get_files_types():
return [('.zip', '.h5')]
@staticmethod
def get_upload_files_names():
return ['data_file']
class TVBImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(TVBImporterForm, self).__init__(prefix, project_id)
self.data_file = TraitUploadField(TVBImporterModel.data_file, '.zip, .h5', self, name='data_file')
self.data_file = TraitUploadField(TVBImporterModel.data_file, self.get_view_model().get_files_types()[0], self, name='data_file')
@staticmethod
def get_view_model():
......
......@@ -32,6 +32,7 @@
.. moduleauthor:: Calin Pavel <calin.pavel@codemart.ro>
.. moduleauthor:: Lia Domide <lia.domide@codemart.ro>
"""
import numpy
from tvb.core.adapters.abcuploader import ABCUploader, ABCUploaderForm
from tvb.core.entities.file.files_helper import FilesHelper
......@@ -58,13 +59,21 @@ class ZIPConnectivityImporterModel(UploaderViewModel):
doc='Normalization mode for weights'
)
@staticmethod
def get_files_types():
return ['.zip']
@staticmethod
def get_upload_files_names():
return ['uploaded']
class ZIPConnectivityImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(ZIPConnectivityImporterForm, self).__init__(prefix, project_id)
self.uploaded = TraitUploadField(ZIPConnectivityImporterModel.uploaded, "application/zip", self,
self.uploaded = TraitUploadField(ZIPConnectivityImporterModel.uploaded, self.get_view_model().get_files_types()[0], self,
name='uploaded')
self.normalization = SelectField(ZIPConnectivityImporterModel.normalization, self, name='normalization',
choices=NORMALIZATION_OPTIONS)
......
......@@ -71,12 +71,20 @@ class ZIPSurfaceImporterModel(UploaderViewModel):
label='Center surface using vertex means along axes'
)
@staticmethod
def get_files_types():
return ['.zip']
@staticmethod
def get_upload_files_names():
return 'uploaded'
class ZIPSurfaceImporterForm(ABCUploaderForm):
def __init__(self, prefix='', project_id=None):
super(ZIPSurfaceImporterForm, self).__init__(prefix, project_id)
self.uploaded = TraitUploadField(ZIPSurfaceImporterModel.uploaded, 'application/zip', self, name='uploaded')
self.uploaded = TraitUploadField(ZIPSurfaceImporterModel.uploaded, self.get_view_model().get_files_types()[0], self, name='uploaded')
self.surface_type = SelectField(ZIPSurfaceImporterModel.surface_type, self, name='surface_type',
choices=ALL_SURFACES_SELECTION)
self.zero_based_triangles = BoolField(ZIPSurfaceImporterModel.zero_based_triangles, self,
......
......@@ -79,7 +79,6 @@ class ABCUploader(ABCSynchronous, metaclass=ABCMeta):
return ABCSynchronous._prelaunch(self, operation, uid, available_disk_space, view_model, **kwargs)
def get_required_memory_size(self, view_model):
"""
Return the required memory to run this algorithm.
......@@ -87,14 +86,12 @@ class ABCUploader(ABCSynchronous, metaclass=ABCMeta):
"""
return -1
def get_required_disk_size(self, view_model):
"""
As it is an upload algorithm and we do not have information about data, we can not approximate this.
"""
return 0
@staticmethod
def read_list_data(full_path, dimensions=None, dtype=numpy.float64, skiprows=0, usecols=None):
"""
......@@ -113,7 +110,6 @@ class ABCUploader(ABCSynchronous, metaclass=ABCMeta):
exc.args = (exc.args[0] + " In file: " + file_ending,)
raise
@staticmethod
def read_matlab_data(path, matlab_data_name=None):
"""
......
......@@ -32,8 +32,24 @@ from tvb.core.neotraits.view_model import ViewModel, Str
class UploaderViewModel(ViewModel):
REQUIRED_TYPE = None
data_subject = Str(
default=DataTypeMetaData.DEFAULT_SUBJECT,
label='Subject'
)
\ No newline at end of file
)
@staticmethod
def get_files_types():
"""
:return: a list of one or two elements which contains the required file types for uploaders.
"""
return NotImplementedError
@staticmethod
def get_upload_files_names():
"""
:return: a list of one or two elements which contains the attribute names for trait field uploaders.
"""
return NotImplementedError
......@@ -54,16 +54,26 @@ class OperationApi(MainApi):
return response, DataTypeDto
@handle_response
def launch_operation(self, project_gid, algorithm_module, algorithm_classname, view_model, temp_folder):
def launch_operation(self, project_gid, algorithm_module, algorithm_classname, view_model, temp_folder, data_file_path_1=None, data_file_path_2=None):
h5_file_path = h5.path_for(temp_folder, ViewModelH5, view_model.gid)
h5_file = ViewModelH5(h5_file_path, view_model)
h5_file.store(view_model)
h5_file.close()
file_obj = open(h5_file_path, 'rb')
model_file_obj = open(h5_file_path, 'rb')
files = {"model_file": (os.path.basename(h5_file_path), model_file_obj)}
if data_file_path_1 is not None:
data_file_obj_1 = open(data_file_path_1, 'rb')
files['data_file_1'] = (os.path.basename(data_file_path_1), data_file_obj_1)
if data_file_path_2 is not None:
data_file_obj_2 = open(data_file_path_2, 'rb')
files['data_file_2'] = (os.path.basename(data_file_path_2), data_file_obj_2)
return requests.post(self.build_request_url(RestLink.LAUNCH_OPERATION.compute_url(True, {
LinkPlaceholder.PROJECT_GID.value: project_gid,
LinkPlaceholder.ALG_MODULE.value: algorithm_module,
LinkPlaceholder.ALG_CLASSNAME.value: algorithm_classname
})), files={"file": (os.path.basename(h5_file_path), file_obj)})
})), files=files)
......@@ -29,7 +29,6 @@
#
import tempfile
from tvb.config.init.datatypes_registry import populate_datatypes_registry
from tvb.interfaces.rest.client.datatype.datatype_api import DataTypeApi
from tvb.interfaces.rest.client.operation.operation_api import OperationApi
......@@ -108,13 +107,15 @@ class TVBClient:
"""
return self.simulation_api.fire_simulation(project_gid, session_stored_simulator, self.temp_folder)
def launch_operation(self, project_gid, algorithm_module, algorithm_classname, view_model):
def launch_operation(self, project_gid, algorithm_module, algorithm_classname, view_model, data_file_path_1=None,
data_file_path_2=None):
"""
This is a more generic method of launching Analyzers. Given a project id, algorithm module, algorithm classname
and a view model instance, this function will serialize the view model and will launch the analyzer.
"""
return self.operation_api.launch_operation(project_gid, algorithm_module, algorithm_classname,
view_model, self.temp_folder)
view_model, self.temp_folder, data_file_path_1,
data_file_path_2)
def get_operation_status(self, operation_gid):
"""
......
......@@ -29,9 +29,12 @@
#
import shutil
from tvb.adapters.uploaders.csv_connectivity_importer import CSVConnectivityImporter
from tvb.adapters.uploaders.gifti_surface_importer import GIFTISurfaceImporter
from tvb.adapters.uploaders.nifti_importer import NIFTIImporter
from tvb.basic.logger.builder import get_logger
from tvb.core.adapters.abcadapter import ABCAdapter
from tvb.core.adapters.abcuploader import ABCUploader
from tvb.core.entities.file.files_helper import FilesHelper
from tvb.core.neotraits.h5 import ViewModelH5
from tvb.core.services.exceptions import ProjectServiceException
......@@ -43,8 +46,8 @@ from tvb.interfaces.rest.commons.dtos import DataTypeDto
from tvb.interfaces.rest.commons.exceptions import InvalidIdentifierException, ServiceException
from tvb.interfaces.rest.commons.status_codes import HTTP_STATUS_CREATED
from tvb.interfaces.rest.server.resources.project.project_resource import INVALID_PROJECT_GID_MESSAGE
from tvb.interfaces.rest.server.resources.rest_resource import RestResource
from tvb.interfaces.rest.server.resources.util import save_temporary_file
from tvb.interfaces.rest.server.resources.rest_resource import RestResource, is_path_in_files
from tvb.interfaces.rest.server.resources.util import save_temporary_file, get_destination_folder, handle_data_file
INVALID_OPERATION_GID_MESSAGE = "No operation found for GID: %s"
......@@ -94,8 +97,9 @@ class LaunchOperationResource(RestResource):
"""
:generic method of launching Analyzers
"""
file = self.extract_file_from_request()
h5_path = save_temporary_file(file)
model_file = self.extract_file_from_request()
destination_folder = get_destination_folder()
h5_path = save_temporary_file(model_file, destination_folder)
try:
project = self.project_service.find_project_lazy_by_gid(project_gid)
......@@ -109,8 +113,9 @@ class LaunchOperationResource(RestResource):
try:
adapter_instance = ABCAdapter.build_adapter(algorithm)
view_model = adapter_instance.get_view_model_class()()
with ViewModelH5(h5_path, view_model) as view_model_h5:
view_model_gid = view_model_h5.gid.load()
view_model_h5 = ViewModelH5(h5_path, view_model)
view_model_gid = view_model_h5.gid.load()
# TODO: use logged user
user_id = project.fk_admin
......@@ -119,7 +124,17 @@ class LaunchOperationResource(RestResource):
{})
storage_path = self.files_helper.get_project_folder(project, str(operation.id))
if isinstance(adapter_instance, ABCUploader):
data_file_1 = self.extract_file_from_request(file_name='data_file_1', file_extension=view_model.get_files_types()[0])
handle_data_file(data_file_1, destination_folder, view_model_h5, storage_path, 0)
if isinstance(adapter_instance, (CSVConnectivityImporter, NIFTIImporter)) or \
(isinstance(adapter_instance, GIFTISurfaceImporter) and is_path_in_files('data_file_2')):
data_file_2 = self.extract_file_from_request(file_name='data_file_2', file_extension=view_model.get_files_types()[1])
handle_data_file(data_file_2, destination_folder, view_model_h5, storage_path, 1)
shutil.move(h5_path, storage_path)
view_model_h5.close()
OperationService().launch_operation(operation.id, True)
except Exception as excep:
self.logger.error(excep, exc_info=True)
......
......@@ -38,11 +38,15 @@ class RestResource(Resource):
method_decorators = [rest_jsonify]
@staticmethod
def extract_file_from_request(file_extension=FilesHelper.TVB_STORAGE_FILE_EXTENSION):
if 'file' not in flask.request.files:
raise BadRequestException('No file part in the request!')
file = flask.request.files['file']
def extract_file_from_request(file_name='model_file', file_extension=FilesHelper.TVB_STORAGE_FILE_EXTENSION):
if is_path_in_files(file_name):
raise BadRequestException("No file '%s' in the request!" % file_name)
file = flask.request.files[file_name]
if not file.filename.endswith(file_extension):
<