def individual_relationship_response(self, related_collection_type, related_resource, included=[]): response = dict() response['links'] = { 'self': '{base_url}/{type}/{id}/relationships/{related_collection_type}/{related_resource}'.format( base_url=base_url, type=self.type, id=self.id, related_collection_type=related_collection_type, related_resource=related_resource), 'related': '{base_url}/{type}/{id}/{related_collection_type}/{related_resource}'.format( base_url=base_url, type=self.type, id=self.id, related_collection_type=related_collection_type, related_resource=related_resource) } # data related_node_or_nodes = eval('self.{related_collection_type}.search(id=related_resource)'.format(related_collection_type=related_collection_type), ) if len(related_node_or_nodes) == 1: the_node = related_node_or_nodes[0] response['data'] = {'type': the_node.type, 'id': the_node.id} response['included'] = [the_node.get_resource_object()] + the_node.get_included_from_list(included) r = make_response(jsonify(response)) r.status_code = http_error_codes.OK r.headers['Content-Type'] = CONTENT_TYPE else: response['data'] = None r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) return r
def delete_relationship(cls, id, related_collection_name, related_resource=None): try: this_resource = cls.nodes.get(id=id, active=True) if not related_resource: r = this_resource.delete_relationship_collection(related_collection_name) else: r = this_resource.delete_individual_relationship(related_collection_name, related_resource) except DoesNotExist: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) return r
def get_relationship(cls, request_args, id, related_collection_name, related_resource=None): try: included = request_args.get('included').split(',') except: included = [] try: offset = request_args.get('page[offset]', 0) limit = request_args.get('page[limit]', 20) this_resource = cls.nodes.get(id=id, active=True) if not related_resource: if request_args.get('included'): r = application_codes.error_response([application_codes.PARAMETER_NOT_SUPPORTED_VIOLATION]) else: r = this_resource.relationship_collection_response(related_collection_name, offset, limit) else: r = this_resource.individual_relationship_response(related_collection_name, related_resource, included) except DoesNotExist: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) return r
def set_resource_inactive(cls, id): try: this_resource = cls.nodes.get(id=id, active=True) this_resource.deactivate() #this_resource.active = False #this_resource.save() r = make_response('') r.headers['Content-Type'] = "application/vnd.api+json; charset=utf-8" r.status_code = http_error_codes.NO_CONTENT except DoesNotExist: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) return r
def get_resource_or_collection(cls, request_args, id=None): if id: try: this_resource = cls.nodes.get(id=id, active=True) try: included = request_args.get('included').split(',') except: included = [] r = this_resource.individual_resource_response(included) except DoesNotExist: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) else: if request_args.get('included'): r = application_codes.error_response([application_codes.PARAMETER_NOT_SUPPORTED_VIOLATION]) else: r = cls.resource_collection_response( request_args.get('page[offset]', 0), request_args.get('page[limit]', 20) ) return r
def set_individual_related_resource_inactive(self, related_collection_type, related_resource): # data related_node_or_nodes = eval('self.{related_collection_type}.search(id=related_resource)'.format(related_collection_type=related_collection_type), ) if len(related_node_or_nodes) == 1: the_node = related_node_or_nodes[0] the_node.deactivate() r = make_response('') r.status_code = http_error_codes.NO_CONTENT r.headers['Content-Type'] = CONTENT_TYPE else: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) return r
def set_related_resources_collection_inactive(self, related_collection_type): try: # data relation_type = eval('self.{related_collection_type}.definition'.format( related_collection_type=related_collection_type)).get('relation_type') results, columns = self.cypher( "START a=node({self}) MATCH a-[:{relation_type}]-(b) RETURN b".format( self=self._id, relation_type=relation_type ) ) related_node_or_nodes = [self.inflate(row[0]) for row in results] for n in related_node_or_nodes: n.deactivate() r = make_response('') r.status_code = http_error_codes.NO_CONTENT r.headers['Content-Type'] = CONTENT_TYPE except AttributeError: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) return r
def method_not_allowed(error): """Return an error response when requests supply an unsupported HTTP method""" return application_codes.error_response([application_codes.METHOD_NOT_ALLOWED])
def not_found(error): """Return an error response for resources that don't exist""" return application_codes.error_response([application_codes.RESOURCE_NOT_FOUND])
def method_not_allowed(error): return application_codes.error_response([application_codes.METHOD_NOT_ALLOWED])
def not_found(error): return application_codes.error_response([application_codes.RESOURCE_NOT_FOUND])
def update_resource(cls, request_json, id): response = dict() try: this_resource = cls.nodes.get(id=id, active=True) data = request_json['data'] if data['type'] != cls.type: raise WrongTypeError('type must match the type of the resource being updated.') attributes = data.get('attributes') if attributes: for key in attributes.keys(): eval('setattr(this_resource,{key}, attributes[{key}])'.format(key=repr(key))) this_resource.save() relationships = data.get('relationships') if relationships: for relation_name in relationships.keys(): relations = relationships.get(relation_name) for related_resource in eval('this_resource.{relation_name}.all()'.format(relation_name=relation_name)): eval('this_resource.{relation_name}.disconnect(related_resource)'. format(relation_name=relation_name)) if relations: relations = relations['data'] if isinstance(relations, list): for relation in relations: the_type = relation['type'] the_id = relation['id'] new_resources_relation = cls.nodes.get(id=the_id, active=True) eval('this_resource.{relation_name}.connect(new_resources_relation)'.format( relation_name=relation_name) ) else: relation = relations the_type = relation['type'] the_id = relation['id'] new_resources_relation = cls.nodes.get(id=the_id, active=True) eval('this_resource.{relation_name}.connect(new_resources_relation)'.format( relation_name=relation_name) ) this_resource.updated = datetime.now() this_resource.save() response['data'] = this_resource.get_resource_object() response['links'] = {'self': this_resource.get_self_link()} status_code = http_error_codes.OK location = this_resource.get_self_link() r = make_response(jsonify(response)) r.headers['Content-Type'] = "application/vnd.api+json; charset=utf-8" if location and this_resource: r.headers['Location'] = location r.status_code = status_code except UniqueProperty as e: print str(e) r = application_codes.error_response([application_codes.UNIQUE_KEY_VIOLATION]) except DoesNotExist: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) except WrongTypeError as e: r = application_codes.error_response([application_codes.WRONG_TYPE_VIOLATION]) except KeyError as e: r = application_codes.error_response([application_codes.BAD_FORMAT_VIOLATION]) return r
def create_resource(cls, request_json): response = dict() new_resource, location = None, None try: data = request_json['data'] if data['type'] != cls.type: raise WrongTypeError('type must match the type of the resource being created.') attributes = data.get('attributes') if attributes: new_resource = cls(**attributes) new_resource.save() relationships = data.get('relationships') if relationships: for relation_name in relationships.keys(): relations = relationships.get(relation_name) if relations: relations = relations['data'] if isinstance(relations, list): for relation in relations: the_type = relation['type'] the_id = relation['id'] new_resources_relation = cls.nodes.get(id=the_id, active=True) eval('new_resource.{relation_name}.connect(new_resources_relation)'.format( relation_name=relation_name) ) new_resource.save() else: relation = relations the_type = relation['type'] the_id = relation['id'] new_resources_relation = cls.nodes.get(id=the_id, active=True) eval('new_resource.{relation_name}.connect(new_resources_relation)'.format( relation_name=relation_name) ) new_resource.save() response['data'] = new_resource.get_resource_object() response['links'] = {'self': new_resource.get_self_link()} status_code = http_error_codes.CREATED location = new_resource.get_self_link() r = make_response(jsonify(response)) r.headers['Content-Type'] = "application/vnd.api+json; charset=utf-8" if location and new_resource: r.headers['Location'] = location r.status_code = status_code except UniqueProperty: r = application_codes.error_response([application_codes.UNIQUE_KEY_VIOLATION]) try: new_resource.delete() except: pass except DoesNotExist: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) try: new_resource.delete() except: pass except WrongTypeError as e: r = application_codes.error_response([application_codes.WRONG_TYPE_VIOLATION]) try: new_resource.delete() except: pass except KeyError as e: r = application_codes.error_response([application_codes.BAD_FORMAT_VIOLATION]) try: new_resource.delete() except: pass return r
def related_resources_collection_response(self, related_collection_type, included, offset=0, limit=20): try: response = dict() response['included'] = list() total_length = eval('len(self.{related_collection_type})'.format( related_collection_type=related_collection_type) ) response['links'] = { 'self': '{base_url}/{type}/{id}/{related_collection_type}?page[offset]={offset}&page[limit]={limit}'.format( base_url=base_url, type=self.type, id=self.id, related_collection_type=related_collection_type, offset=offset, limit=limit ), 'first': '{base_url}/{type}/{id}/{related_collection_type}?page[offset]={offset}&page[limit]={limit}'.format( base_url=base_url, type=self.type, id=self.id, related_collection_type=related_collection_type, offset=0, limit=limit ), 'last': "{base_url}/{type}/{id}/{related_collection_type}?page[offset]={offset}&page[limit]={limit}".format( base_url=base_url, type=self.type, id=self.id, related_collection_type=related_collection_type, offset=total_length - (total_length % int(limit)), limit=limit ) } if int(offset) - int(limit) > 0: response['links']['prev'] = "{base_url}/{type}/{id}/{related_collection_type}?page[offset]={offset}&page[limit]={limit}".format( base_url=base_url, type=self.type, id=self.id, related_collection_type=related_collection_type, offset=int(offset) - int(limit), limit=limit ) if total_length > int(offset) + int(limit): response['links']['next'] = "{base_url}/{type}/{id}/{related_collection_type}?page[offset]={offset}&page[limit]={limit}".format( base_url=base_url, type=self.type, id=self.id, related_collection_type=related_collection_type, offset=int(offset) + int(limit), limit=limit ) # data relation_type = eval('self.{related_collection_type}.definition'.format( related_collection_type=related_collection_type)).get('relation_type') results, columns = self.cypher( "START a=node({self}) MATCH a-[:{relation_type}]-(b) RETURN b SKIP {offset} LIMIT {limit}".format( self=self._id, relation_type=relation_type, offset=offset, limit=limit ) ) related_node_or_nodes = [self.inflate(row[0]) for row in results] if not eval("type(self.{related_collection_type})".format(related_collection_type=related_collection_type)) == ZeroOrOne: response['data'] = list() for the_node in related_node_or_nodes: if the_node.active: response['data'].append(the_node.get_resource_object()) for n in the_node.get_included_from_list(included): if n not in response['included']: response['included'].append(n) elif related_node_or_nodes: the_node = related_node_or_nodes[0] response['data'].append(the_node.get_resource_object()) else: response['data'] = None r = make_response(jsonify(response)) r.status_code = http_error_codes.OK r.headers['Content-Type'] = CONTENT_TYPE except AttributeError: r = application_codes.error_response([application_codes.RESOURCE_NOT_FOUND]) return r
def method_not_allowed(error): """Return an error response when requests supply an unsupported HTTP method""" return application_codes.error_response( [application_codes.METHOD_NOT_ALLOWED])
def not_found(error): """Return an error response for resources that don't exist""" return application_codes.error_response( [application_codes.RESOURCE_NOT_FOUND])