def _configure_job(simulator_gid, available_space, is_group_launch, operation_id): # type: (str, int, bool, int) -> (dict, list) bash_entrypoint = os.path.join( os.environ[HPCSchedulerClient.TVB_BIN_ENV_KEY], HPCSettings.HPC_LAUNCHER_SH_SCRIPT) base_url = TvbProfile.current.web.BASE_URL inputs_in_container = os.path.join( HPCSchedulerClient.CONTAINER_INPUT_FOLDER, StorageInterface(simulator_gid).get_current_enc_dirname()) # Build job configuration JSON my_job = { HPCSettings.UNICORE_EXE_KEY: os.path.basename(bash_entrypoint), HPCSettings.UNICORE_ARGS_KEY: [ simulator_gid, available_space, is_group_launch, base_url, inputs_in_container, HPCSchedulerClient.HOME_FOLDER_MOUNT, operation_id ], HPCSettings.UNICORE_RESOURCER_KEY: { "CPUs": "1" } } if HPCSchedulerClient.CSCS_PROJECT in os.environ: my_job[HPCSettings.UNICORE_PROJECT_KEY] = os.environ[ HPCSchedulerClient.CSCS_PROJECT] return my_job, bash_entrypoint
def _import_image(self, src_folder, metadata_file, project_id, target_images_path): """ Create and store a image entity. """ figure_dict = StorageInterface().read_metadata_from_xml( os.path.join(src_folder, metadata_file)) actual_figure = os.path.join( src_folder, os.path.split(figure_dict['file_path'])[1]) if not os.path.exists(actual_figure): self.logger.warning("Expected to find image path %s .Skipping" % actual_figure) return figure_dict['fk_user_id'] = self.user_id figure_dict['fk_project_id'] = project_id figure_entity = manager_of_class(ResultFigure).new_instance() figure_entity = figure_entity.from_dict(figure_dict) stored_entity = dao.store_entity(figure_entity) # Update image meta-data with the new details after import figure = dao.load_figure(stored_entity.id) shutil.move(actual_figure, target_images_path) self.logger.debug("Store imported figure") _, meta_data = figure.to_dict() self.storage_interface.write_image_metadata(figure, meta_data)
def build(user=None, project=None, op=None, nr_regions=76, monitor=TemporalAverageViewModel(), with_surface=False, conn_gid=None): model = SimulatorAdapterModel() model.monitors = [monitor] if not op: op = operation_factory(test_user=user, test_project=project) if conn_gid: model.connectivity = conn_gid if not with_surface and not conn_gid: model.connectivity = connectivity_index_factory(nr_regions, op).gid model.simulation_length = 100 if with_surface: rm_idx = region_mapping_index_factory() model.connectivity = rm_idx.fk_connectivity_gid model.surface = CortexViewModel() model.surface.surface_gid = rm_idx.fk_surface_gid model.surface.region_mapping_data = rm_idx.gid model.simulation_length = 10 storage_path = StorageInterface().get_project_folder( op.project.name, str(op.id)) h5.store_view_model(model, storage_path) return storage_path, model.gid
def test_tvb_export_of_simple_datatype_with_encryption( self, dummy_datatype_index_factory): """ Test export of an encrypted data type which has no data stored on file system """ datatype = dummy_datatype_index_factory() storage_interface = StorageInterface() import_export_encryption_handler = StorageInterface.get_import_export_encryption_handler( ) import_export_encryption_handler.generate_public_private_key_pair( TvbProfile.current.TVB_TEMP_FOLDER) _, file_path, _ = self.export_manager.export_data( datatype, self.TVB_EXPORTER, self.test_project, os.path.join(TvbProfile.current.TVB_TEMP_FOLDER, import_export_encryption_handler.PUBLIC_KEY_NAME)) assert file_path is not None, "Export process should return path to export file" assert os.path.exists( file_path), "Could not find export file: %s on disk." % file_path result = storage_interface.unpack_zip( file_path, TvbProfile.current.TVB_TEMP_FOLDER) encrypted_password_path = import_export_encryption_handler.extract_encrypted_password_from_list( result) decrypted_file_path = import_export_encryption_handler.decrypt_content( encrypted_password_path, result, os.path.join(TvbProfile.current.TVB_TEMP_FOLDER, import_export_encryption_handler.PRIVATE_KEY_NAME))[0] original_path = h5.path_for_stored_index(datatype) self.compare_files(original_path, decrypted_file_path)
def stage_out_to_operation_folder(working_dir, operation, simulator_gid): # type: (Storage, Operation, typing.Union[uuid.UUID, str]) -> (list, Operation, str) encrypted_files = HPCSchedulerClient._stage_out_results( working_dir, simulator_gid) simulation_results = list() metric_encrypted_file = None metric_vm_encrypted_file = None for encrypted_file in encrypted_files: if os.path.basename(encrypted_file).startswith( DatatypeMeasureH5.file_name_base()): metric_encrypted_file = encrypted_file elif os.path.basename(encrypted_file).startswith( MEASURE_METRICS_MODEL_CLASS): metric_vm_encrypted_file = encrypted_file else: simulation_results.append(encrypted_file) storage_interface = StorageInterface() metric_op, metric_file = HPCSchedulerClient._handle_metric_results( metric_encrypted_file, metric_vm_encrypted_file, operation, storage_interface, simulator_gid) project = dao.get_project_by_id(operation.fk_launched_in) operation_dir = HPCSchedulerClient.storage_interface.get_project_folder( project.name, str(operation.id)) h5_filenames = storage_interface.decrypt_files_to_dir( simulator_gid, simulation_results, operation_dir) storage_interface.cleanup_encryption_handler(simulator_gid) LOGGER.info("Decrypted h5: {}".format(h5_filenames)) LOGGER.info("Metric op: {}".format(metric_op)) LOGGER.info("Metric file: {}".format(metric_file)) return h5_filenames, metric_op, metric_file
def _operation_finished(operation, simulator_gid): op_ident = dao.get_operation_process_for_operation(operation.id) # TODO: Handle login job = Job( Transport(os.environ[HPCSchedulerClient.CSCS_LOGIN_TOKEN_ENV_KEY]), op_ident.job_id) operation = dao.get_operation_by_id(operation.id) folder = HPCSchedulerClient.storage_interface.get_project_folder( operation.project.name) storage_interface = StorageInterface() if storage_interface.encryption_enabled(): storage_interface.inc_project_usage_count(folder) storage_interface.sync_folders(folder) try: sim_h5_filenames, metric_op, metric_h5_filename = \ HPCSchedulerClient.stage_out_to_operation_folder(job.working_dir, operation, simulator_gid) operation.mark_complete(STATUS_FINISHED) dao.store_entity(operation) HPCSchedulerClient().update_db_with_results( operation, sim_h5_filenames, metric_op, metric_h5_filename) except OperationException as exception: HPCOperationService.LOGGER.error(exception) HPCOperationService._operation_error(operation) finally: if storage_interface.encryption_enabled(): storage_interface.sync_folders(folder) storage_interface.set_project_inactive(operation.project)
def __init__(self): # Here we register all available data type exporters # If new exporters supported, they should be added here self._register_exporter(TVBExporter()) self._register_exporter(TVBLinkedExporter()) self.export_folder = os.path.join(TvbProfile.current.TVB_STORAGE, self.EXPORT_FOLDER_NAME) self.storage_interface = StorageInterface()
def clean_up(self): """Clean up expired sessions.""" now = self.now() for _id, (data, expiration_time) in self.cache.copy().items(): if expiration_time <= now: if KEY_PROJECT in data: selected_project = data[KEY_PROJECT] StorageInterface().set_project_inactive(selected_project) try: del self.cache[_id] except KeyError: pass try: if self.locks[_id].acquire(blocking=False): lock = self.locks.pop(_id) lock.release() except KeyError: pass # added to remove obsolete lock objects for _id in list(self.locks): locked = (_id not in self.cache and self.locks[_id].acquire(blocking=False)) if locked: lock = self.locks.pop(_id) lock.release()
def prepare_importer_data(self, user_factory, project_factory, operation_factory, connectivity_index_factory, datatype_group_factory): """ Sets up the environment for running the tests; creates a test user, a test project, a datatype and a datatype_group; """ self.test_user = user_factory() self.test_project = project_factory(self.test_user) operation = operation_factory(test_project=self.test_project) # Generate simple data type and export it to H5 file self.datatype = connectivity_index_factory(op=operation) export_manager = ExportManager() _, exported_h5_file, _ = export_manager.export_data(self.datatype, self.TVB_EXPORTER, self.test_project) # Copy H5 file to another location since the original one / exported will be deleted with the project _, h5_file_name = os.path.split(exported_h5_file) shutil.copy(exported_h5_file, TvbProfile.current.TVB_TEMP_FOLDER) self.h5_file_path = os.path.join(TvbProfile.current.TVB_TEMP_FOLDER, h5_file_name) assert os.path.exists(self.h5_file_path), "Simple data type was not exported correct" # Generate data type group and export it to ZIP file datatype_group = datatype_group_factory(project=self.test_project) _, self.zip_file_path, _ = export_manager.export_data(datatype_group, self.TVB_EXPORTER, self.test_project) assert os.path.exists(self.zip_file_path), "Data type group was not exported correct" StorageInterface().remove_project_structure(self.test_project.name) self.clean_database(delete_folders=False) # Recreate project, but a clean one where to import data self.test_user = user_factory() self.test_project = project_factory(self.test_user)
def build_operation_from_file(self, project, operation_file): """ Create Operation entity from metadata file. """ operation_dict = StorageInterface().read_metadata_from_xml(operation_file) operation_entity = manager_of_class(Operation).new_instance() return operation_entity.from_dict(operation_dict, dao, self.user_id, project.gid)
def test_adapter_huge_memory_requirement(self, test_adapter_factory): """ Test that an MemoryException is raised in case adapter cant launch due to lack of memory. """ # Prepare adapter test_adapter_factory(adapter_class=DummyAdapterHugeMemoryRequired) adapter = TestFactory.create_adapter("tvb.tests.framework.adapters.dummy_adapter3", "DummyAdapterHugeMemoryRequired") # Simulate receiving POST data form = DummyAdapterHugeMemoryRequiredForm() view_model = form.get_view_model()() view_model.test = 5 # Prepare operation for launch operation = Operation(view_model.gid.hex, self.test_user.id, self.test_project.id, adapter.stored_adapter.id, status=STATUS_STARTED) operation = dao.store_entity(operation) # Store ViewModel in H5 parent_folder = StorageInterface().get_project_folder(self.test_project.name, str(operation.id)) h5.store_view_model(view_model, parent_folder) # Launch operation with pytest.raises(NoMemoryAvailableException): OperationService().initiate_prelaunch(operation, adapter)
def do_operation_launch(simulator_gid, available_disk_space, is_group_launch, base_url, operation_id, plain_dir='/root/plain'): try: log.info("Preparing HPC launch for simulation with id={}".format( simulator_gid)) populate_datatypes_registry() log.info("Current TVB profile has HPC run=: {}".format( TvbProfile.current.hpc.IS_HPC_RUN)) storage_interface = StorageInterface() _request_passfile(simulator_gid, operation_id, base_url, storage_interface.get_password_file(simulator_gid)) storage_interface.decrypt_results_to_dir(simulator_gid, plain_dir) log.info("Current wdir is: {}".format(plain_dir)) view_model = h5.load_view_model(simulator_gid, plain_dir) adapter_instance = HPCSimulatorAdapter(plain_dir, is_group_launch) _update_operation_status(STATUS_STARTED, simulator_gid, operation_id, base_url) adapter_instance._prelaunch(None, view_model, available_disk_space) _encrypt_results(adapter_instance, storage_interface, simulator_gid) _update_operation_status(STATUS_FINISHED, simulator_gid, operation_id, base_url) except Exception as excep: log.error("Could not execute operation {}".format(str(sys.argv[1]))) log.exception(excep) _update_operation_status(STATUS_ERROR, simulator_gid, operation_id, base_url) raise excep
def transactional_setup_method(self): """ Reset the database before each test. """ self.project_service = ProjectService() self.storage_interface = StorageInterface() self.test_user = TestFactory.create_user()
def _mark_selected(self, project): """ Set the project passed as parameter as the selected project. """ previous_project = common.get_current_project() # Update project stored in selection, with latest Project entity from DB. members = self.user_service.get_users_for_project("", project.id)[1] project.members = members if previous_project is None or previous_project.id != project.id: # Clean Burst selection from session in case of a different project. SimulatorContext().clean_project_data_from_session() # Store in DB new project selection user = common.get_from_session(common.KEY_USER) if user is not None: self.user_service.save_project_to_user(user.id, project.id) # Display info message about project change self.logger.debug("Selected project is now " + project.name) common.set_info_message("Your current working project is: " + str(project.name)) linked_dt = self.project_service.get_linked_datatypes_storage_path( project) storage_interface = StorageInterface() storage_interface.set_project_active(project, linked_dt) if previous_project is not None: storage_interface.set_project_inactive(previous_project) # Add the project entity to session every time, as it might be changed (e.g. after edit) common.add2session(common.KEY_PROJECT, project)
def load_burst_read_only(self, burst_config_id): try: burst_config = self.burst_service.load_burst_configuration( burst_config_id) storage_path = StorageInterface().get_project_folder( self.context.project.name, str(burst_config.fk_simulation)) simulator = h5.load_view_model(burst_config.simulator_gid, storage_path) last_loaded_form_url = self.get_url_for_final_fragment( burst_config) self.context.init_session_at_burst_loading(burst_config, simulator, last_loaded_form_url) form = self.prepare_first_fragment() self.monitors_handler.build_list_of_monitors_from_view_models( self.context.simulator) rendering_rules = SimulatorFragmentRenderingRules( form, SimulatorWizzardURLs.SET_CONNECTIVITY_URL, is_simulation_readonly_load=True, is_first_fragment=True) return rendering_rules.to_dict() except Exception: # Most probably Burst was removed. Delete it from session, so that client # has a good chance to get a good response on refresh self.logger.exception("Error loading burst") self.context.remove_burst_config_from_session() raise
def path_for_has_traits(self, has_traits_class, gid): if isinstance(gid, str): gid = uuid.UUID(gid) fname = StorageInterface().get_filename( self._get_has_traits_classname(has_traits_class), gid) return os.path.join(self.base_dir, fname)
def update(): """ Move images previously stored in TVB operation folders, in a single folder/project. """ projects_count = dao.get_all_projects(is_count=True) for page_start in range(0, projects_count, PAGE_SIZE): projects_page = dao.get_all_projects(page_start=page_start, page_size=PAGE_SIZE) for project in projects_page: figures = _figures_in_project(project.id) for figure in figures: figure.file_path = "%s-%s" % (figure.operation.id, figure.file_path) dao.store_entities(figures) project_path = StorageInterface().get_project_folder(project.name) update_manager = ProjectUpdateManager(project_path) update_manager.run_all_updates() project.version = TvbProfile.current.version.PROJECT_VERSION dao.store_entity(project)
def test_prepare_inputs_with_eeg_monitor(self, operation_factory, simulator_factory, surface_index_factory, sensors_index_factory, region_mapping_index_factory, connectivity_index_factory): surface_idx, surface = surface_index_factory(cortical=True) sensors_idx, sensors = sensors_index_factory() proj = ProjectionSurfaceEEG(sensors=sensors, sources=surface, projection_data=numpy.ones(3)) op = operation_factory() storage_path = StorageInterface().get_project_folder( op.project.name, str(op.id)) prj_db_db = h5.store_complete(proj, storage_path) prj_db_db.fk_from_operation = op.id dao.store_entity(prj_db_db) connectivity = connectivity_index_factory(76, op) rm_index = region_mapping_index_factory(conn_gid=connectivity.gid, surface_gid=surface_idx.gid) eeg_monitor = EEGViewModel(projection=proj.gid, sensors=sensors.gid) eeg_monitor.region_mapping = rm_index.gid sim_folder, sim_gid = simulator_factory(op=op, monitor=eeg_monitor, conn_gid=connectivity.gid) hpc_client = HPCSchedulerClient() input_files = hpc_client._prepare_input(op, sim_gid) assert len(input_files) == 11
def _do_operation_launch(self, op, sim_gid, mocker, is_pse=False): # Prepare encrypted dir self.storage_interface = StorageInterface() self.dir_gid = sim_gid job_encrypted_inputs = HPCSchedulerClient()._prepare_input(op, sim_gid) self.storage_interface.encrypt_inputs(sim_gid, job_encrypted_inputs) encrypted_dir = self.storage_interface.get_encrypted_dir(self.dir_gid) mocker.patch('tvb.core.operation_hpc_launcher._request_passfile', _request_passfile_dummy) mocker.patch( 'tvb.core.operation_hpc_launcher._update_operation_status', _update_operation_status) # Call do_operation_launch similarly to CSCS env plain_dir = self.storage_interface.get_project_folder( self.test_project.name, 'plain') do_operation_launch(sim_gid.hex, 1000, is_pse, '', op.id, plain_dir) assert len(os.listdir(encrypted_dir)) == 7 output_path = os.path.join(encrypted_dir, HPCSchedulerClient.OUTPUT_FOLDER) assert os.path.exists(output_path) expected_files = 2 if is_pse: expected_files = 3 assert len(os.listdir(output_path)) == expected_files return output_path
def test_export_simulator_configuration(self, operation_factory, connectivity_index_factory): """ Test export of a simulator configuration """ conn_gid = uuid.UUID(connectivity_index_factory().gid) operation = operation_factory(is_simulation=True, store_vm=True, test_project=self.test_project, conn_gid=conn_gid) burst_configuration = BurstConfiguration(self.test_project.id) burst_configuration.fk_simulation = operation.id burst_configuration.simulator_gid = operation.view_model_gid burst_configuration.name = "Test_burst" burst_configuration = dao.store_entity(burst_configuration) op_folder = StorageInterface().get_project_folder( self.test_project.name, str(operation.id)) BurstService().store_burst_configuration(burst_configuration, op_folder) export_file = self.export_manager.export_simulator_configuration( burst_configuration.id) assert export_file is not None, "Export process should return path to export file" assert os.path.exists( export_file ), "Could not find export file: %s on disk." % export_file assert zipfile.is_zipfile( export_file), "Generated file is not a valid ZIP file"
def create_operation(test_user=None, test_project=None, operation_status=STATUS_FINISHED): """ Create persisted operation. :return: Operation entity after persistence. """ if test_user is None: test_user = TestFactory.create_user() if test_project is None: test_project = TestFactory.create_project(test_user) algorithm = dao.get_algorithm_by_module(TVB_IMPORTER_MODULE, TVB_IMPORTER_CLASS) adapter = ABCAdapter.build_adapter(algorithm) view_model = adapter.get_view_model_class()() view_model.data_file = "." operation = Operation(view_model.gid.hex, test_user.id, test_project.id, algorithm.id, status=operation_status) dao.store_entity(operation) op_dir = StorageInterface().get_project_folder(test_project.name, str(operation.id)) h5.store_view_model(view_model, op_dir) return dao.get_operation_by_id(operation.id)
def _prepare_input(operation, simulator_gid): # type: (Operation, str) -> list storage_path = StorageInterface().get_project_folder( operation.project.name, str(operation.id)) vm_files, dt_files = h5.gather_references_of_view_model( simulator_gid, storage_path) vm_files.extend(dt_files) return vm_files
def __init__(self, path): self.bi_hemispheric = False self.vertices, self.normals, self.triangles = [], [], [] self.hemisphere_mask = [] self._read_vertices = 0 self.storage_interface = StorageInterface() self._read(path)
def transactional_setup_method(self): self.test_user = TestFactory.create_user('Rest_User') self.test_project = TestFactory.create_project(self.test_user, 'Rest_Project', users=[self.test_user.id]) self.operations_resource = GetOperationsInProjectResource() self.status_resource = GetOperationStatusResource() self.results_resource = GetOperationResultsResource() self.launch_resource = LaunchOperationResource() self.storage_interface = StorageInterface()
def store_view_model(operation, project, view_model): storage_path = StorageInterface().get_project_folder( project.name, str(operation.id)) h5.store_view_model(view_model, storage_path) view_model_size_on_disk = StorageInterface.compute_recursive_h5_disk_usage( storage_path) operation.view_model_disk_size = view_model_size_on_disk dao.store_entity(operation)
def setup_method(self): self.storage_interface = StorageInterface() self.dir_gid = '123' self.encryption_handler = self.storage_interface.get_encryption_handler( self.dir_gid) self.clean_database() self.test_user = TestFactory.create_user() self.test_project = TestFactory.create_project(self.test_user)
def _update_vm_generic_operation_tag(view_model, operation): project = dao.get_project_by_id(operation.fk_launched_in) storage_path = StorageInterface().get_project_folder( project.name, str(operation.id)) h5_path = h5.path_for(storage_path, ViewModelH5, view_model.gid, type(view_model).__name__) with ViewModelH5(h5_path, view_model) as vm_h5: vm_h5.operation_tag.store(operation.user_group)
def run(self): """ Get the required data from the operation queue and launch the operation. """ operation_id = self.operation_id run_params = [TvbProfile.current.PYTHON_INTERPRETER_PATH, '-m', 'tvb.core.operation_async_launcher', str(operation_id), TvbProfile.CURRENT_PROFILE_NAME] current_operation = dao.get_operation_by_id(operation_id) storage_interface = StorageInterface() project_folder = storage_interface.get_project_folder(current_operation.project.name) in_usage = storage_interface.is_in_usage(project_folder) storage_interface.inc_running_op_count(project_folder) if not in_usage: storage_interface.sync_folders(project_folder) # In the exceptional case where the user pressed stop while the Thread startup is done, # We should no longer launch the operation. if self.stopped() is False: env = os.environ.copy() env['PYTHONPATH'] = os.pathsep.join(sys.path) # anything that was already in $PYTHONPATH should have been reproduced in sys.path launched_process = Popen(run_params, stdout=PIPE, stderr=PIPE, env=env) LOGGER.debug("Storing pid=%s for operation id=%s launched on local machine." % (operation_id, launched_process.pid)) op_ident = OperationProcessIdentifier(operation_id, pid=launched_process.pid) dao.store_entity(op_ident) if self.stopped(): # In the exceptional case where the user pressed stop while the Thread startup is done. # and stop_operation is concurrently asking about OperationProcessIdentity. self.stop_pid(launched_process.pid) subprocess_result = launched_process.communicate() LOGGER.info("Finished with launch of operation %s" % operation_id) returned = launched_process.wait() LOGGER.info("Return code: {}. Stopped: {}".format(returned, self.stopped())) LOGGER.info("Thread: {}".format(self)) if returned != 0 and not self.stopped(): # Process did not end as expected. (e.g. Segmentation fault) burst_service = BurstService() operation = dao.get_operation_by_id(self.operation_id) LOGGER.error("Operation suffered fatal failure! Exit code: %s Exit message: %s" % (returned, subprocess_result)) burst_service.persist_operation_state(operation, STATUS_ERROR, "Operation failed unexpectedly! Please check the log files.") del launched_process storage_interface.check_and_delete(project_folder) # Give back empty spot now that you finished your operation CURRENT_ACTIVE_THREADS.remove(self) LOCKS_QUEUE.put(1)
def _adapt_epileptor_simulations(): """ Previous Simulations on EpileptorWithPermitivity model, should be converted to use the Epileptor model. As the parameters from the two models are having different ranges and defaults, we do not translate parameters, we only set the Epileptor as model instead of EpileptorPermittivityCoupling, and leave the model params to defaults. """ session = SA_SESSIONMAKER() epileptor_old = "EpileptorPermittivityCoupling" epileptor_new = "Epileptor" param_model = "model" try: all_ep_ops = session.query(model.Operation).filter( model.Operation.parameters.ilike('%"' + epileptor_old + '"%')).all() storage_interface = StorageInterface() all_bursts = dict() for ep_op in all_ep_ops: try: op_params = parse_json_parameters(ep_op.parameters) if op_params[param_model] != epileptor_old: LOGGER.debug("Skipping op " + str(op_params[param_model]) + " -- " + str(ep_op)) continue LOGGER.debug("Updating " + str(op_params)) op_params[param_model] = epileptor_new ep_op.parameters = json.dumps(op_params, cls=MapAsJson.MapAsJsonEncoder) LOGGER.debug("New params:" + ep_op.parameters) storage_interface.write_operation_metadata(ep_op) burst = dao.get_burst_for_operation_id(ep_op.id) if burst is not None: LOGGER.debug("Updating burst:" + str(burst)) burst.prepare_after_load() burst.simulator_configuration[param_model] = { 'value': epileptor_new } burst._simulator_configuration = json.dumps( burst.simulator_configuration, cls=MapAsJson.MapAsJsonEncoder) if burst.id not in all_bursts: all_bursts[burst.id] = burst except Exception: LOGGER.exception("Could not process " + str(ep_op)) session.add_all(all_ep_ops) session.add_all(list(all_bursts.values())) session.commit() except Exception: LOGGER.exception("Could not update Simulation Epileptor Params") finally: session.close()
def __init__(self): self.generic_attributes = GenericAttributes() self.generic_attributes.subject = DataTypeMetaData.DEFAULT_SUBJECT self.storage_interface = StorageInterface() # Will be populate with current running operation's identifier self.operation_id = None self.user_id = None self.submitted_form = None self.log = get_logger(self.__class__.__module__)