예제 #1
0
 def __init__(self, host, oauth_client=None, headers=None):
     '''
     Args:
        host: host to connnect to, ie: http://localhost:8888
        oauth_client: instance of the bbp_client.oidc.client
        headers: HTTP headers passed to server
     '''
     self._cwd = '/'  # means that we're at the top level
     self._access = DocAccess(host, oauth_client, headers)
예제 #2
0
 def __init__(self, host, oauth_client=None, headers=None):
     '''
     Args:
        host: host to connnect to, ie: http://localhost:8888
        oauth_client: instance of the bbp_client.oidc.client
        headers: HTTP headers passed to server
     '''
     self._cwd = '/'  # means that we're at the top level
     self._access = DocAccess(host, oauth_client, headers)
예제 #3
0
class Client(object):
    '''Interface to the document service via python

        Example:
            >>> #you'll likely need a user for authentication
            >>> user = '******'
            >>> server = 'http://localhost:8888'
            >>> from bbp_client.oidc.client import BBPOIDCClient
            >>> client = BBPOIDCClient.implicit_auth(user)
            >>> from bbp_client.document_service.client import Client
            >>> handler = Client(server, client)
            >>> handler.walk()
    '''

    def __init__(self, host, oauth_client=None, headers=None):
        '''
        Args:
           host: host to connnect to, ie: http://localhost:8888
           oauth_client: instance of the bbp_client.oidc.client
           headers: HTTP headers passed to server
        '''
        self._cwd = '/'  # means that we're at the top level
        self._access = DocAccess(host, oauth_client, headers)

    @classmethod
    def new(cls, environment='prod', user=None, password=None, token=None):
        '''create new documentservice client'''
        services = get_services()
        oauth_url = services['oidc_service'][environment]['url']
        ds_url = services['document_service'][environment]['url']
        if token:
            oauth_client = BBPOIDCClient.bearer_auth(oauth_url, token)
        else:
            oauth_client = BBPOIDCClient.implicit_auth(user, password, oauth_url)
        return cls(ds_url, oauth_client)

    @sh.swagger_error
    def exists(self, path):
        '''check if path exists, can be a project/directory or file
        '''
        return self._access.exists(path)

    def _norm_path(self, path=None):
        '''returns a normalized path'''
        path = str(path)  # convert from unicode, potentially
        if path:
            ret = os.path.normpath(joinp(self._cwd, path))
        else:
            ret = self._cwd
        return ret

    ######### os.* like functions ##########
    @sh.swagger_error
    def getcwd(self):
        '''Return a string representing the current working directory'''
        return self._cwd

    @sh.swagger_error
    def chdir(self, path):
        '''Change the current working directory to path

           raises DocException if the path doesn't exist
        '''
        path = self._norm_path(path)
        while path.startswith('..'):
            self._cwd = self._cwd.rsplit('/', 1)[0]
            if not self._cwd:  # trying to traverse past root
                self._cwd = '/'
            head, path = os.path.split(path)
            #print 'head "%s" path "%s' % (head, path)
            if not head:
                break

        #print 'path after: "%s", cwd: "%s"' % (path, self._cwd)

        if not path or '..' == path:
            return

        norm_path = self._norm_path(path)
        L.debug("chdir: %s, normalized: %s", path, norm_path)
        try:
            if self._access.exists(norm_path):
                self._cwd = norm_path
            else:
                raise DocException('directory does not exist')
        except KeyError:
            raise DocException('directory does not exist')

    @sh.swagger_error
    def listdir(self, path=None):
        '''Return a list containing the names of the entries in the
           directory given by path. The list is in arbitrary order.

           if no path is given, starts at root (ie: all projects)
        '''
        path = path or '/'
        norm_path = self._norm_path(path)
        return self._access.listdir(norm_path)

    @sh.swagger_error
    def mkdir(self, path=None, ignore_error=False):
        '''Create a directory named path'''
        norm_path = self._norm_path(path)
        return self._access.mkdir(norm_path, ignore_error)

    @sh.swagger_error
    def makedirs(self, path):
        '''Recursive directory creation function'''
        norm_path = self._norm_path(path)
        L.debug('makedirs %s', path)
        split_path = norm_path.split('/')
        assert(not split_path[0])
        prev = joinp('/', split_path[1])
        self.mkdir(prev, ignore_error=True)
        for p in split_path[2:]:
            prev = joinp(prev, p)
            self.mkdir(prev, ignore_error=True)

    @sh.swagger_error
    def remove(self, path):
        '''Remove (delete) the file path'''
        norm_path = self._norm_path(path)
        self._access.remove(norm_path)

    @sh.swagger_error
    def rename(self, src, dst):
        '''Rename the file or directory src to dst'''
        norm_src = self._norm_path(src)
        norm_dst = self._norm_path(dst)
        return self._access.rename(norm_src, norm_dst)

    @sh.swagger_error
    def rmdir(self, path, force=False):
        '''Remove (delete) the directory path'''
        norm_path = self._norm_path(path)
        self._access.rmdir(norm_path, force)

    @sh.swagger_error
    def walk(self, path=None):
        '''For each directory in the tree rooted at cwd (including top itself),
           it yields a 3-tuple (dirpath, dirnames, filenames).
        '''
        norm_path = self._norm_path(path or self._cwd)
        return self._access.walk(norm_path)

    ######### specialized functions ##########
    @sh.swagger_error
    def upload_file(self, src_path, dst_path, mimetype=None, st_attr=None):
        '''upload a file from the local file system to a directory

            Returns: uuid of created entity
        '''
        if not os.path.isfile(src_path):
            raise OSError('Source path does not exist: %s' % src_path)
        dst_path = self._norm_path(dst_path)
        return self._access.upload_file(src_path, dst_path, mimetype, st_attr)

    @sh.swagger_error
    def upload_string(self, _str, dst, mimetype=None, st_attr=None):
        '''upload a string supplied string to document service

            Returns: uuid of created entity
        '''
        return self._access.upload_string(_str, str(dst), mimetype, st_attr)

    @sh.swagger_error
    def download_file(self, path, dst_path=None):
        '''download file

            Args:
                path: the path to the file entity
                dst_path: the path to store the downloaded contents

            Returns:
                path to the file if dst_path was provided
                contents of the file as a string otherwise
        '''
        norm_path = self._norm_path(path)
        return self._access.download_file(norm_path, dst_path)

    @sh.swagger_error
    def download_file_by_id(self, _id, dst_path=None):
        '''download file

            Args:
                id(string): the id of the file entity
                dst_path: the path to store the downloaded contents

            Returns:
                path to the file if dst_path was provided
                contents of the file as a string otherwise
        '''
        return self._access.download_file_by_id(_id, dst_path)

    @sh.swagger_error
    def create_external_link(self, external_path, dst_path, st_attr=None):
        '''create external link to the file

            Args:
                external_path: path like /gpfs/bbp.epfl.ch/...
                dst_path: the path in document server
                st_attr: optional standard attributes

            Returns: uuid of created entity
        '''
        dst = self._norm_path(dst_path)
        return self._access.create_external_link(external_path, dst, st_attr)

    @sh.swagger_error
    def bulk_create_external_links(self, files, dst_folder):
        '''creates external link to file

            Args:
                files(dict): a dictionary of dst_name -> properties
                    where properties must be a dictionary containing content_type and external_path
                    example:
                    {'txt1': {'content_type': 'text/plain', 'external_path': '/gpfs/txt1'},
                     'txt2': ...
                    }
                dst_folder(string): on the server

            Returns: dictionary of dst_name -> uuid
        '''
        dst = self._norm_path(dst_folder)
        return self._access.bulk_create_external_links(files, dst)

    @sh.swagger_error
    def get_external_link_path_by_id(self, uuid):
        '''get the path to an external link.

        Args:
            uuid: The UUID of the ducument service entity.
        Returns:

            A path to the external link.
        '''
        doc_attrs = self.get_standard_attr_by_id(uuid)
        return doc_attrs._contentUri

    @sh.swagger_error
    def get_standard_attr(self, path):
        '''get the standard attributes of the path
           https://bbpteam.epfl.ch/project/spaces/display/BBPWFA/Document+Service+REST+API+Draft+3#DocumentServiceRESTAPIDraft3-StandardAttributesandMetadata # pylint: disable=C0301 # nopep8

            Args:
                path: the path to the entity

            Returns:
                Dictionary with all standard attributes
        '''
        norm_path = self._norm_path(path)
        return self._access.get_standard_attr(norm_path)

    @sh.swagger_error
    def set_standard_attr(self, path, attr_dict):
        '''set the standard attributes of the path'''
        norm_path = self._norm_path(path)
        return self._access.set_standard_attr(norm_path, attr_dict)

    @sh.swagger_error
    def get_standard_attr_by_id(self, _id):
        '''get the standard attributes of the entity'''
        return self._access.get_standard_attr_by_id(_id)

    @sh.swagger_error
    def set_standard_attr_by_id(self, _id, attr_dict):
        '''set the standard attributes of the entity'''
        return self._access.set_standard_attr_by_id(_id, attr_dict)

    @sh.swagger_error
    def get_metadata(self, path):
        '''get the metadata of the path

            Args:
                path: the path to the entity

            Returns:
                Dictionary with all meta attributes
        '''
        norm_path = self._norm_path(path)
        return self._access.get_metadata(norm_path)

    @sh.swagger_error
    def get_metadata_by_id(self, _id):
        '''get the metadata of the id

            Args:
                id: the id of the entity

            Returns:
                Dictionary with all meta attributes
        '''
        return self._access.get_metadata_by_id(_id)

    @sh.swagger_error
    def set_metadata(self, path, metadata_dict):
        '''set the metadata of the path

            Args:
                path: the path to the entity
                metadata_dict: dictionary of key/values to set
        '''
        norm_path = self._norm_path(path)
        return self._access.set_metadata(norm_path, metadata_dict)

    @sh.swagger_error
    def set_metadata_by_id(self, _id, metadata_dict):
        '''set the metadata of an id

            Args:
                id: the uuid of the entity
                metadata_dict: dictionary of key/values to set
        '''
        return self._access.set_metadata_by_id(_id, metadata_dict)

    @sh.swagger_error
    def reset_cache(self):
        '''reset the directory cache'''
        self._access.reset_cache()

    @sh.swagger_error
    def __repr__(self):
        return repr(self._access)

    def get_path_by_id(self, _id):
        '''returns a path on the DS from the uuid of an existing object'''
        attr = self.get_standard_attr_by_id(_id)
        if attr._parent == 'None':
            return '/' + attr._name
        else:
            return joinp(self.get_path_by_id(attr._parent), attr._name)

    @sh.swagger_error
    def get_project_by_collab_id(self, collab_id):
        '''return project managed by collab'''
        projects = self._access.filter_projects('managed_by_collab=%s' % collab_id)
        if len(projects) > 1:
            raise DocException('More than one project exists for collab %s' % collab_id)
        if projects:
            return dict((n, getattr(projects[0], n)) for n in
                        projects[0].swaggerTypes.keys())
        return None
예제 #4
0
class Client(object):
    '''Interface to the document service via python

        Example:
            >>> #you'll likely need a user for authentication
            >>> user = '******'
            >>> server = 'http://localhost:8888'
            >>> from bbp_client.oidc.client import BBPOIDCClient
            >>> client = BBPOIDCClient.implicit_auth(user)
            >>> from bbp_client.document_service.client import Client
            >>> handler = Client(server, client)
            >>> handler.walk()
    '''
    def __init__(self, host, oauth_client=None, headers=None):
        '''
        Args:
           host: host to connnect to, ie: http://localhost:8888
           oauth_client: instance of the bbp_client.oidc.client
           headers: HTTP headers passed to server
        '''
        self._cwd = '/'  # means that we're at the top level
        self._access = DocAccess(host, oauth_client, headers)

    @classmethod
    def new(cls, environment='prod', user=None, password=None, token=None):
        '''create new documentservice client'''
        services = get_services()
        oauth_url = services['oidc_service'][environment]['url']
        ds_url = services['document_service'][environment]['url']
        if token:
            oauth_client = BBPOIDCClient.bearer_auth(oauth_url, token)
        else:
            oauth_client = BBPOIDCClient.implicit_auth(user, password,
                                                       oauth_url)
        return cls(ds_url, oauth_client)

    @sh.swagger_error
    def exists(self, path):
        '''check if path exists, can be a project/directory or file
        '''
        return self._access.exists(path)

    def _norm_path(self, path=None):
        '''returns a normalized path'''
        path = str(path)  # convert from unicode, potentially
        if path:
            ret = os.path.normpath(joinp(self._cwd, path))
        else:
            ret = self._cwd
        return ret

    ######### os.* like functions ##########
    @sh.swagger_error
    def getcwd(self):
        '''Return a string representing the current working directory'''
        return self._cwd

    @sh.swagger_error
    def chdir(self, path):
        '''Change the current working directory to path

           raises DocException if the path doesn't exist
        '''
        path = self._norm_path(path)
        while path.startswith('..'):
            self._cwd = self._cwd.rsplit('/', 1)[0]
            if not self._cwd:  # trying to traverse past root
                self._cwd = '/'
            head, path = os.path.split(path)
            #print 'head "%s" path "%s' % (head, path)
            if not head:
                break

        #print 'path after: "%s", cwd: "%s"' % (path, self._cwd)

        if not path or '..' == path:
            return

        norm_path = self._norm_path(path)
        L.debug("chdir: %s, normalized: %s", path, norm_path)
        try:
            if self._access.exists(norm_path):
                self._cwd = norm_path
            else:
                raise DocException('directory does not exist')
        except KeyError:
            raise DocException('directory does not exist')

    @sh.swagger_error
    def listdir(self, path=None):
        '''Return a list containing the names of the entries in the
           directory given by path. The list is in arbitrary order.

           if no path is given, starts at root (ie: all projects)
        '''
        path = path or '/'
        norm_path = self._norm_path(path)
        return self._access.listdir(norm_path)

    @sh.swagger_error
    def mkdir(self, path=None, ignore_error=False):
        '''Create a directory named path'''
        norm_path = self._norm_path(path)
        return self._access.mkdir(norm_path, ignore_error)

    @sh.swagger_error
    def makedirs(self, path):
        '''Recursive directory creation function'''
        norm_path = self._norm_path(path)
        L.debug('makedirs %s', path)
        split_path = norm_path.split('/')
        assert (not split_path[0])
        prev = joinp('/', split_path[1])
        self.mkdir(prev, ignore_error=True)
        for p in split_path[2:]:
            prev = joinp(prev, p)
            self.mkdir(prev, ignore_error=True)

    @sh.swagger_error
    def remove(self, path):
        '''Remove (delete) the file path'''
        norm_path = self._norm_path(path)
        self._access.remove(norm_path)

    @sh.swagger_error
    def rename(self, src, dst):
        '''Rename the file or directory src to dst'''
        norm_src = self._norm_path(src)
        norm_dst = self._norm_path(dst)
        return self._access.rename(norm_src, norm_dst)

    @sh.swagger_error
    def rmdir(self, path, force=False):
        '''Remove (delete) the directory path'''
        norm_path = self._norm_path(path)
        self._access.rmdir(norm_path, force)

    @sh.swagger_error
    def walk(self, path=None):
        '''For each directory in the tree rooted at cwd (including top itself),
           it yields a 3-tuple (dirpath, dirnames, filenames).
        '''
        norm_path = self._norm_path(path or self._cwd)
        return self._access.walk(norm_path)

    ######### specialized functions ##########
    @sh.swagger_error
    def upload_file(self, src_path, dst_path, mimetype=None, st_attr=None):
        '''upload a file from the local file system to a directory

            Returns: uuid of created entity
        '''
        if not os.path.isfile(src_path):
            raise OSError('Source path does not exist: %s' % src_path)
        dst_path = self._norm_path(dst_path)
        return self._access.upload_file(src_path, dst_path, mimetype, st_attr)

    @sh.swagger_error
    def upload_string(self, _str, dst, mimetype=None, st_attr=None):
        '''upload a string supplied string to document service

            Returns: uuid of created entity
        '''
        return self._access.upload_string(_str, str(dst), mimetype, st_attr)

    @sh.swagger_error
    def download_file(self, path, dst_path=None):
        '''download file

            Args:
                path: the path to the file entity
                dst_path: the path to store the downloaded contents

            Returns:
                path to the file if dst_path was provided
                contents of the file as a string otherwise
        '''
        norm_path = self._norm_path(path)
        return self._access.download_file(norm_path, dst_path)

    @sh.swagger_error
    def download_file_by_id(self, _id, dst_path=None):
        '''download file

            Args:
                id(string): the id of the file entity
                dst_path: the path to store the downloaded contents

            Returns:
                path to the file if dst_path was provided
                contents of the file as a string otherwise
        '''
        return self._access.download_file_by_id(_id, dst_path)

    @sh.swagger_error
    def create_external_link(self, external_path, dst_path, st_attr=None):
        '''create external link to the file

            Args:
                external_path: path like /gpfs/bbp.epfl.ch/...
                dst_path: the path in document server
                st_attr: optional standard attributes

            Returns: uuid of created entity
        '''
        dst = self._norm_path(dst_path)
        return self._access.create_external_link(external_path, dst, st_attr)

    @sh.swagger_error
    def bulk_create_external_links(self, files, dst_folder):
        '''creates external link to file

            Args:
                files(dict): a dictionary of dst_name -> properties
                    where properties must be a dictionary containing content_type and external_path
                    example:
                    {'txt1': {'content_type': 'text/plain', 'external_path': '/gpfs/txt1'},
                     'txt2': ...
                    }
                dst_folder(string): on the server

            Returns: dictionary of dst_name -> uuid
        '''
        dst = self._norm_path(dst_folder)
        return self._access.bulk_create_external_links(files, dst)

    @sh.swagger_error
    def get_external_link_path_by_id(self, uuid):
        '''get the path to an external link.

        Args:
            uuid: The UUID of the ducument service entity.
        Returns:

            A path to the external link.
        '''
        doc_attrs = self.get_standard_attr_by_id(uuid)
        return doc_attrs._contentUri

    @sh.swagger_error
    def get_standard_attr(self, path):
        '''get the standard attributes of the path
           https://bbpteam.epfl.ch/project/spaces/display/BBPWFA/Document+Service+REST+API+Draft+3#DocumentServiceRESTAPIDraft3-StandardAttributesandMetadata # pylint: disable=C0301 # nopep8

            Args:
                path: the path to the entity

            Returns:
                Dictionary with all standard attributes
        '''
        norm_path = self._norm_path(path)
        return self._access.get_standard_attr(norm_path)

    @sh.swagger_error
    def set_standard_attr(self, path, attr_dict):
        '''set the standard attributes of the path'''
        norm_path = self._norm_path(path)
        return self._access.set_standard_attr(norm_path, attr_dict)

    @sh.swagger_error
    def get_standard_attr_by_id(self, _id):
        '''get the standard attributes of the entity'''
        return self._access.get_standard_attr_by_id(_id)

    @sh.swagger_error
    def set_standard_attr_by_id(self, _id, attr_dict):
        '''set the standard attributes of the entity'''
        return self._access.set_standard_attr_by_id(_id, attr_dict)

    @sh.swagger_error
    def get_metadata(self, path):
        '''get the metadata of the path

            Args:
                path: the path to the entity

            Returns:
                Dictionary with all meta attributes
        '''
        norm_path = self._norm_path(path)
        return self._access.get_metadata(norm_path)

    @sh.swagger_error
    def get_metadata_by_id(self, _id):
        '''get the metadata of the id

            Args:
                id: the id of the entity

            Returns:
                Dictionary with all meta attributes
        '''
        return self._access.get_metadata_by_id(_id)

    @sh.swagger_error
    def set_metadata(self, path, metadata_dict):
        '''set the metadata of the path

            Args:
                path: the path to the entity
                metadata_dict: dictionary of key/values to set
        '''
        norm_path = self._norm_path(path)
        return self._access.set_metadata(norm_path, metadata_dict)

    @sh.swagger_error
    def set_metadata_by_id(self, _id, metadata_dict):
        '''set the metadata of an id

            Args:
                id: the uuid of the entity
                metadata_dict: dictionary of key/values to set
        '''
        return self._access.set_metadata_by_id(_id, metadata_dict)

    @sh.swagger_error
    def reset_cache(self):
        '''reset the directory cache'''
        self._access.reset_cache()

    @sh.swagger_error
    def __repr__(self):
        return repr(self._access)

    def get_path_by_id(self, _id):
        '''returns a path on the DS from the uuid of an existing object'''
        attr = self.get_standard_attr_by_id(_id)
        if attr._parent == 'None':
            return '/' + attr._name
        else:
            return joinp(self.get_path_by_id(attr._parent), attr._name)

    @sh.swagger_error
    def get_project_by_collab_id(self, collab_id):
        '''return project managed by collab'''
        projects = self._access.filter_projects('managed_by_collab=%s' %
                                                collab_id)
        if len(projects) > 1:
            raise DocException('More than one project exists for collab %s' %
                               collab_id)
        if projects:
            return dict((n, getattr(projects[0], n))
                        for n in projects[0].swaggerTypes.keys())
        return None