Skip to content
Snippets Groups Projects
dataset.py 9.88 KiB
Newer Older
  • Learn to ignore specific revisions
  • import os
    from urllib.parse import unquote
    from notebook.base.handlers import IPythonHandler
    from .connection import openbis_connections
    
    class DataSetDownloadHandler(IPythonHandler):
        """Handle the requests for /openbis/dataset/connection/permId"""
    
    
        def download_data(self, conn, permId, downloadPath=None):
            if not conn.is_session_active():
                try:
                    conn.login()
                except Exception as exc:
                    self.set_status(500)
                    self.write({
                        "reason" : 'connection to {} could not be established: {}'.format(conn.name, exc)
                    })
                    return
    
            try:
                dataset = conn.openbis.get_dataset(permId)
            except Exception as exc:
                self.set_status(404)
                self.write({
                    "reason" : 'No such dataSet found: {}'.format(permId)
                })
                return
    
            # dataset was found, download the data to the disk
            try:
                destination = dataset.download(destination=downloadPath)
            except Exception as exc:
                self.set_status(500)
                self.write({
                    "reason": 'Data for DataSet {} could not be downloaded: {}'.format(permId, exc)
                })
                return
    
            # return success message
            path = os.path.join(downloadPath, dataset.permId)
            self.write({
                'url'       : conn.url,
                'permId'    : dataset.permId,
                'path'      : path,
                'dataStore' : dataset.dataStore,
                'location'  : dataset.physicalData.location,
                'size'      : dataset.physicalData.size,
                'statusText': 'Data for DataSet {} was successfully downloaded to: {}.'.format(dataset.permId, path)
            })
    
        def get(self, **params):
            """Handle a request to /openbis/dataset/connection_name/permId
            download the data and return a message
            """
    
            try:
                conn = openbis_connections[params['connection_name']]
            except KeyError:
                self.set_status(404)
                self.write({
                    "reason":'connection {} was not found'.format(params['connection_name'])
                })
                return
    
            results = self.download_data(conn=conn, permId=params['permId'], downloadPath=params['downloadPath'])
    
    
    class DataSetTypesHandler(IPythonHandler):
        def get(self, **params):
            """Handle a request to /openbis/datasetTypes/connection_name
            """
    
            try:
                conn = openbis_connections[params['connection_name']]
            except KeyError:
                self.set_status(404)
                self.write({
                    "reason":'connection {} was not found'.format(params['connection_name'])
                })
                return
    
            try:
                dataset_types = conn.openbis.get_dataset_types()
                dts = dataset_types.df.to_dict(orient='records')
    
                # get property assignments for every dataset-type
                # and add it to the dataset collection
                for dt in dts:
                    dataset_type = conn.openbis.get_dataset_type(dt['code'])
                    pa = dataset_type.get_propertyAssignments(including_vocabulary=True)
                    pa_dicts = pa.to_dict(orient='records')
                    for pa_dict in pa_dicts:
                        if pa_dict['dataType'] == 'CONTROLLEDVOCABULARY':
                            terms = conn.openbis.get_terms(pa_dict['vocabulary']['code'])
                            pa_dict['terms'] = terms.df[['code','label','description','official','ordinal']].to_dict(orient='records')
    
                    dt['propertyAssignments'] = pa_dicts
    
                self.write({
                    "dataSetTypes": dts
                })
                return
    
            except Exception as e:
                print(e)
                self.set_status(500)
                self.write({
                    "reason":'Could not fetch dataset-types: {}'.format(e)
                })
                return
    
    
    class DataSetUploadHandler(IPythonHandler):
        """Handle the POST requests for /openbis/dataset/connection_name"""
    
        def upload_data(self, conn, data):
            if not conn.is_session_active():
                try:
                    conn.login()
                except Exception as e:
                    print(e)
                    self.set_status(500)
                    self.write({
                        "reason": 'connection to {} could not be established: {}'.format(conn.name, e)
                    })
                    return
    
            errors = []
    
            print("--------------_HERE_-----------1")
    
    
            sample = None
            experiment = None
    
    
            if (data.get('entityIdentifier')):
    
                    sample = conn.openbis.get_sample(data.get('entityIdentifier'))
    
                except Exception as e:
    
                    pass
                if sample is None:
                    try:
                        experiment = conn.openbis.get_experiment(data.get('entityIdentifier'))
                    except Exception as e:
                        pass
    
                if sample is None and experiment is None:
    
                    errors.append(
    
                        {"entityIdentifier" : 'No such sample or experiment: {}'.format(data.get('entityIdentifier')) }
    
                    )
            else:
                errors.append(
    
                    {"entityIdentifier": "please provide a sample or experiment identifier"}
    
                )
    
            print("--------------_HERE_-----------2")
    
    
            parents = []
            if data.get('parents'):
                parents = data.get('parents')
                for parent in parents:
                    try:
                        conn.openbis.get_dataset(parent)
                    except Exception as e:
                        errors.append({
                            "parent": "Parent DataSet not found: {}".format(parent)
                        })
    
            print("--------------_HERE_-----------2a")
    
    
            filenames = []
            for filename in data.get('files'):
                filename = unquote(filename)
                if os.path.isfile(filename):
                    filenames.append(filename)
                else:
                    errors.append({
                        "file": "File not found: {}".format(filename)
                    })
            print("--------------_HERE_-----------3")
    
            try:
                dataset = conn.openbis.new_dataset(
                    type   = data.get('type'),
                    sample = sample,
    
                    experiment = experiment,
                    files  = filenames,
                )
            except Exception as e:
                print(e)
                errors.append({
                    "create": 'Error while creating the dataset: {}'.format(e)
                })
            print("--------------_HERE_-----------4")
    
            # try to set the properties
            if data.get('props'):
                props = data.get('props')
                for prop, value in props.items():
                    try:
                        setattr(dataset.props, prop.lower(), value)
                    except Exception as e:
                        errors.append({
                            "prop."+prop : str(e)
                        })
    
            # check if any mandatory property is missing
            for prop_name, prop in dataset.props._property_names.items():
                if prop['mandatory']:
                    if getattr(dataset.props, prop_name) is None or getattr(dataset.props, prop_name) == "":
                        errors.append({
                            "prop."+prop_name : "is mandatory"
                        })
            print("--------------_HERE_-----------5")
    
            # write errors back if already occured
            if errors:
                self.set_status(500)
                self.write({ "errors": errors })
                return
            print("--------------_HERE_-----------6")
    
            try:
                dataset.save()
            except Exception as e:
                errors.append({
                    "save": 'Error while saving the dataset: {}'.format(e)
                })
            print("--------------_HERE_-----------7")
    
            # write errors back if they occured
            if errors:
                self.set_status(500)
                self.write({ "errors": errors })
            else:
                # ...or return a success message
                self.write({
                    'status': 200,
                    'statusText': 'Jupyter Notebook was successfully uploaded to: {} with permId: {}'.format(conn.name, dataset.permId)
                })
    
    
            print('Jupyter Notebook was successfully uploaded to: {} with permId: {}'.format(conn.name, dataset.permId))
    
            print("--------------_HERE_-----------8")
    
        def post(self, **params):
            """Handle a request to /openbis/dataset/connection_name/permId
            download the data and return a message
            """
    
            try:
                conn = openbis_connections[params['connection_name']]
            except KeyError:
                self.write({
                    "reason": 'connection {} was not found'.format(params['connection_name'])
                })
                return
    
            data = self.get_json_body()
            print("Received DATA")
            print(data)
            self.upload_data(conn=conn,data=data)
    
    
    class FileListHandler(IPythonHandler):
    
        def get(self, **params):
            """
            Returns the file list of the current working directory
    
            :param params:
            :return: dictionary of files, key is the fully qualified name,
                     value is the relative name (for display)
            """
    
            cwd = os.getcwd()
            files = {}
            for (dirpath, dirnames, filenames) in os.walk(cwd):
                if filenames:
                    for filename in filenames:
                        # ignore hidden files
                        if filename.startswith('.'):
                            continue
                        # ignore hidden folders
                        if os.path.relpath(dirpath) != '.' \
                                and os.path.relpath(dirpath).startswith('.'):
                            continue
                        fqn = os.path.join(dirpath, filename)
                        files[fqn] = os.path.relpath(fqn, cwd)
    
            self.set_status(200)
            self.write({
                "files": files
            })