def register(experiment_id, acquisition_id): """ .. http:post:: /api/experiments/(string:experiment_id)/acquisitions/(string:acquisition_id)/register Register a single directory (passed as parameter `path` in the JSON request) as the directory containing all the files for the given acquisition. Calling this method twice with different `path` parameters will result in an error (so you cannot combine the contents of two directories by 'registering' them). On the other hand, the *same* directory can be registered over and over again without adverse side-effects; the method is idempotent in this sense. **Example request**: .. sourcecode:: http Content-Type: application/json { "path": "/fullpath/to/serversidedata" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "data": "/fullpath/to/serversidedata" } :reqheader Authorization: JWT token issued by the server :statuscode 200: no error :statuscode 500: server error """ data = request.get_json() path = data['path'] logger.info('Registering microscope files from path `%s` ...', path) try: filenames = [ f for f in os.listdir(path) if (not f.startswith('.') and not os.path.isdir(os.path.join(path, f))) ] except OSError as err: logger.error("Cannot list directory `%s`: %s", path, err) raise with tm.utils.ExperimentSession(experiment_id) as session: experiment = session.query(tm.Experiment).one() microscope_type = experiment.microscope_type img_regex, metadata_regex = get_microscope_type_regex(microscope_type) acquisition = session.query(tm.Acquisition).get(acquisition_id) plate = session.query(tm.Plate).get(acquisition.plate_id) # check for image files already registered img_filenames = [f.name for f in acquisition.microscope_image_files] img_files = [ tm.MicroscopeImageFile( name=f, acquisition_id=acquisition.id ) for f in filenames if img_regex.search(f) and f not in img_filenames ] # check for metadata already registered meta_filenames = [f.name for f in acquisition.microscope_metadata_files] meta_files = [ tm.MicroscopeMetadataFile( name=secure_filename(f), acquisition_id=acquisition.id ) for f in filenames if metadata_regex.search(f) and f not in meta_filenames ] session.bulk_save_objects(img_files + meta_files) # trigger creation of directories acquisition.location acquisition.microscope_metadata_location # link root directory path_to_link = os.path.join( LibraryConfig().storage_home, ('experiment_{}' '/plates/plate_{}' '/acquisitions/acquisition_{}' '/microscope_images' .format(experiment.id, plate.id, acquisition.id))) if not os.path.exists(path_to_link): try: os.symlink(path, path_to_link) except Exception as err: logger.debug( "Error linking source directory `%s` to TM directory `%s`: %s", path, path_to_link, err) raise else: # path exists, check if it is correct p1 = os.path.realpath(path) p2 = os.path.realpath(path_to_link) if p1 != p2: raise ValueError( "Acquisition {a} of plate {p} of experiment {e}" " is already linked to directory `{d}`" .format( a=acquisition.id, p=plate.id, e=epxeriment.id, d=p1)) microscope_files = session.query(tm.MicroscopeImageFile).filter_by(acquisition_id=acquisition.id).all() for microscope_file in microscope_files: microscope_file.location microscope_file.status = 'COMPLETE' return jsonify(message='ok')
def register_upload(experiment_id, acquisition_id): """ .. http:post:: /api/experiments/(string:experiment_id)/acquisitions/(string:acquisition_id)/upload/register Notify the server that an upload for this acquisition is imminent. The client has to wait for this response before uploading files. **Example request**: .. sourcecode:: http Content-Type: application/json { "files": ["file1.png", "file2.png", ...] } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "data": ["file1.png", "file2.png", ...] } :reqheader Authorization: JWT token issued by the server :statuscode 200: no error :statuscode 500: server error """ logger.info('register microscope files for upload') data = request.get_json() files = data['files'] if len(files) == 0: raise MalformedRequestError( 'No files supplied. Cannot register upload.' ) with tm.utils.ExperimentSession(experiment_id) as session: experiment = session.query(tm.Experiment).one() microscope_type = experiment.microscope_type img_regex, metadata_regex = get_microscope_type_regex(microscope_type) acquisition = session.query(tm.Acquisition).get(acquisition_id) img_filenames = [f.name for f in acquisition.microscope_image_files] img_files = [ tm.MicroscopeImageFile( name=secure_filename(f), acquisition_id=acquisition.id ) for f in files if img_regex.search(f) and secure_filename(f) not in img_filenames ] meta_filenames = [f.name for f in acquisition.microscope_metadata_files] meta_files = [ tm.MicroscopeMetadataFile( name=secure_filename(f), acquisition_id=acquisition.id ) for f in files if metadata_regex.search(f) and secure_filename(f) not in meta_filenames ] session.bulk_save_objects(img_files + meta_files) # Trigger creation of directories acquisition.location acquisition.microscope_images_location acquisition.microscope_metadata_location with tm.utils.ExperimentSession(experiment_id) as session: image_filenames = session.query(tm.MicroscopeImageFile.name).\ filter(tm.MicroscopeImageFile.status != FileUploadStatus.COMPLETE).\ all() metadata_filenames = session.query(tm.MicroscopeMetadataFile.name).\ filter(tm.MicroscopeMetadataFile.status != FileUploadStatus.COMPLETE).\ all() all_filenames = image_filenames + metadata_filenames logger.info('registered %d files', len(all_filenames)) return jsonify(data=[f.name for f in all_filenames])
def register(experiment_id, acquisition_id): """ .. http:post:: /api/experiments/(string:experiment_id)/acquisitions/(string:acquisition_id)/register Pass the NFS path to the data to the server. The client has to wait for this response before uploading files. **Example request**: .. sourcecode:: http Content-Type: application/json { "path": "/fullpath/to/serversidedata" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "data": "/fullpath/to/serversidedata" } :reqheader Authorization: JWT token issued by the server :statuscode 200: no error :statuscode 500: server error """ logger.info('register microscope files') data = request.get_json() path = data['path'] logger.info('path given by the client: %s', path) # Parse storage_home variable from tissuemaps.cfg file parser = SafeConfigParser() parser.read('/home/tissuemaps/.tmaps/tissuemaps.cfg') storage_home_path = parser.get('tmlib', 'storage_home') path_to_link = os.path.join( storage_home_path, 'experiment_{}/plates/plate_{}/acquisitions/acquisition_{}/microscope_images' ) filenames = [ f for f in os.listdir(path) if (not f.startswith('.') and not os.path.isdir(os.path.join(path, f))) ] with tm.utils.ExperimentSession(experiment_id) as session: experiment = session.query(tm.Experiment).one() microscope_type = experiment.microscope_type img_regex, metadata_regex = get_microscope_type_regex(microscope_type) acquisition = session.query(tm.Acquisition).get(acquisition_id) # single plate only plate = session.query(tm.Plate).one() logger.info( 'path to link: %s', path_to_link.format(experiment.id, plate.id, acquisition.id)) logger.info('experiment %s', experiment.id) logger.info('acquisition %s', acquisition) logger.info('plate %s', plate) # check for image files already registered img_filenames = [f.name for f in acquisition.microscope_image_files] logger.debug('img_filenames %s', img_filenames) img_files = [ tm.MicroscopeImageFile(name=f, acquisition_id=acquisition.id) for f in filenames if img_regex.search(f) and f not in img_filenames ] # check for metadata already registered meta_filenames = [ f.name for f in acquisition.microscope_metadata_files ] meta_files = [ tm.MicroscopeMetadataFile(name=secure_filename(f), acquisition_id=acquisition.id) for f in filenames if metadata_regex.search(f) and f not in meta_filenames ] session.bulk_save_objects(img_files + meta_files) # Trigger creation of directories acquisition.location #acquisition.microscope_images_location acquisition.microscope_metadata_location os.symlink( path, path_to_link.format(experiment.id, plate.id, acquisition.id)) microscope_files = session.query(tm.MicroscopeImageFile).filter_by( acquisition_id=acquisition.id).all() for microscope_file in microscope_files: microscope_file.location microscope_file.status = 'COMPLETE' return jsonify(message='ok')