def get(self, location, etag=None): """ Get a single object from the G-Node REST API. If an etag is provided it will be included in the request with 'If-none-match'. If the response is 304 the return value of this method will be None. :param location: The location of the object or the whole URL. :type location: str :param etag: The etag of the cached object. :type etag: str :returns: The found object or None if it was not updated. :rtype: Model :raises: HTTPError if the entity was not found on the server (404). """ if location.startswith("http://"): url = location else: url = urlparse.urljoin(self.location, location) headers = {} if etag is not None: headers['If-none-match'] = etag future = self.__session.get(url, headers=headers) response = future.result() if response.status_code in (304, 404): result = None else: self.raise_for_status(response) result = convert.collections_to_model(convert.json_to_collections(response.content)) return result
def get_list(self, locations): """ Get a list of objects that are referenced by their locations or complete URLs from the G-Node REST API. In order to get a better performance this method uses the features of the requests_futures package. :param locations: List with locations or URLs. :type locations: list :returns: A list of objects matching the list of locations. :rtype: list """ futures = [] results = [] for location in locations: if location.startswith("http://"): url = location else: url = urlparse.urljoin(self.location, location) future = self.__session.get(url) futures.append(future) for future in futures: response = future.result() self.raise_for_status(response) result = convert.collections_to_model(convert.json_to_collections(response.content)) results.append(result) return results
def select(self, model_name, raw_filters=None): """ Select data from a certain type e.g. blocks or spiketrains from the G-Node REST API and convert the results to a list of model objects. :param model_name: The name of the model as string. :type model_name: str :param raw_filters: Filters as defined by the G-Node REST API. :type raw_filters: dict :returns: A list of (filtered) results. :rtype: list """ results = [] raw_filters = {} if raw_filters is None else raw_filters location = Model.get_location(model_name) url = urlparse.urljoin(self.location, location) headers = {} future = self.__session.get(url, headers=headers, params=raw_filters) response = future.result() self.raise_for_status(response) raw_results = convert.json_to_collections(response.content, as_list=True) for obj in raw_results: results.append(convert.collections_to_model(obj)) return results
def set_delta(self, path): """ Submits a given Delta file with changes to the Remote. :param path: a path to the Delta file with changes to be submitted """ url = urlparse.urljoin(self.location, "/api/v1/in_bulk/") with open(path, 'rb') as f: files = {'raw_file': f.read()} future = self.__session.post(url, files=files) response = future.result() self.raise_for_status(response) return convert.collections_to_model(convert.json_to_collections(response.content))
def set(self, entity, avoid_collisions=False): """ Update or create an entity on the G-Node REST API. If an etag/guid is provided by the entity it will be included in the header with 'If-match' if avoid_collisions is True. :param entity: The entity to persist. :type entity: Model :param avoid_collisions: Try to avoid collisions (lost update problem) :type avoid_collisions: bool :returns: The updated entity. :rtype: Model :raises: RuntimeError If the changes collide with remote changes of the entity. """ if hasattr(entity, "location") and entity.location is not None: method = 'put' url = urlparse.urljoin(self.location, entity.location) else: method = 'post' url = urlparse.urljoin(self.location, Model.get_location(entity.model)) data = convert.model_to_json_response(entity) headers = {'Content-Type': 'application/json'} if avoid_collisions and entity.guid is not None: headers['If-match'] = entity.guid future = getattr(self.__session, method)(url, data=data, headers=headers) response = future.result() if response.status_code == 304: result = entity else: self.raise_for_status(response) result = convert.collections_to_model(convert.json_to_collections(response.content)) return result