コード例 #1
0
ファイル: delete.py プロジェクト: harlekeyn/grest
def delete_all(self, request):
    try:
        # patch __log
        self.__log = self._GRest__log

        (primary, _) = validate_models(self)

        if all([ENABLE_DELETE_ALL == "True", primary.model]):
            # user wants to delete all items (including relations)
            results = db.cypher_query("MATCH (n:{0}) DETACH DELETE n".format(
                primary.model.__name__))
            if results[0] == []:
                return serialize(dict(result="OK"))
            else:
                raise HTTPException(msg.DELETE_FAILED, 500)
        else:
            raise HTTPException(msg.FEATURE_IS_DISABLED, 403)
    except (DoesNotExist, AttributeError) as e:
        self.__log.exception(e)
        raise HTTPException(msg.ITEM_DOES_NOT_EXIST, 404)
    except UniqueProperty as e:
        self.__log.exception(e)
        raise HTTPException(msg.NON_UNIQUE_PROPERTY, 409)
    except RequiredProperty as e:
        self.__log.exception(e)
        raise HTTPException(msg.REQUIRE_PROPERTY_MISSING, 500)
コード例 #2
0
def patch(self, request, primary_id):
    try:
        # patch __log
        self.__log = self._GRest__log

        (primary, _) = validate_models(self, primary_id)

        primary_selected_item = None
        if primary.id is not None:
            primary_selected_item = primary.model.nodes.get_or_none(
                **{primary.selection_field: primary.id})

        if primary_selected_item:
            new_item = primary.model()

            # parse input data (validate or not!)
            json_data = validate_input(new_item.validation_rules, request)

            updated_item = None
            with db.transaction:
                primary_selected_item.__dict__.update(json_data)
                updated_item = primary_selected_item.save()
                updated_item.refresh()

            if updated_item:
                return serialize(dict(result="OK"))
            else:
                raise HTTPException(msg.UPDATE_FAILED, 500)
        else:
            raise HTTPException(msg.ITEM_DOES_NOT_EXIST, 404)
    except DoesNotExist as e:
        self.__log.exception(e)
        raise HTTPException("The requested item or relation does not exist.",
                            404)
コード例 #3
0
ファイル: index.py プロジェクト: mostafa/grest
def index(self: FlaskView, request: Request) -> "grest.GRestResponse":
    try:
        # patch __log
        self.__log = self._GRest__log

        __validation_rules__ = {
            "skip": fields.Int(required=False,
                               validate=lambda skip: skip >= 0,
                               missing=0),

            "limit": fields.Int(required=False,
                                validate=lambda lim: lim >= 1 and lim <= 100,
                                missing=QUERY_LIMIT),

            "order_by": fields.Str(required=False,
                                   missing="?")
        }

        (primary, _) = validate_models(self)

        query_data = validate_input(
            __validation_rules__, request, location="query")
        skip = query_data.get("skip")
        limit = query_data.get("skip") + query_data.get("limit")
        order_by = escape(query_data.get("order_by"))

        if order_by:
            if order_by.startswith("-"):
                # select property for descending ordering
                order_by_prop = order_by[1:]
            else:
                # select property for ascending ordering
                order_by_prop = order_by

            primary_model_props = primary.model.defined_properties().keys()
            if all([order_by_prop not in primary_model_props,
                    order_by_prop != "?"]):
                raise HTTPException(msg.INVALID_ORDER_PROPERTY, 404)

        total_items = len(primary.model.nodes)

        if total_items <= 0:
            raise HTTPException(msg.NO_ITEM_EXISTS.format(
                model=primary.model_name), 404)

        if skip > total_items:
            raise HTTPException(msg.VALIDATION_FAILED, 422)

        items = primary.model.nodes.order_by(order_by)[skip:limit]

        if items:
            return serialize({pluralize(primary.model_name):
                              [item.to_dict() for item in items]})
        else:
            raise HTTPException(msg.NO_ITEM_EXISTS.format(
                model=primary.model_name), 404)
    except DoesNotExist as e:
        self.__log.exception(str(e))
        raise HTTPException(msg.ITEM_DOES_NOT_EXIST, 404)
コード例 #4
0
ファイル: get.py プロジェクト: mostafa/grest
def get(self: FlaskView,
        primary_id: str,
        secondary_model_name: Optional[str] = None,
        secondary_id: Optional[str] = None) -> "grest.GRestResponse":
    try:
        # patch __log
        self.__log = self._GRest__log

        (primary, secondary) = validate_models(self, primary_id,
                                               secondary_model_name,
                                               secondary_id)

        primary_selected_item = primary.model.nodes.get_or_none(
            **{primary.selection_field: primary.id})

        if all([primary_selected_item, secondary.model, secondary.id]):
            # user selected a nested model with 2 keys
            # (from the primary and secondary models)
            # /users/user_id/roles/role_id -> selected role of this user
            # /categories/cat_id/tags/tag_id -> selected tag of this category

            # In this example, the p variable of type Post
            # is the secondary_item
            # (u:User)-[:POSTED]-(p:Post)
            secondary_item = primary_selected_item.get_all(
                secondary.model_name,
                secondary.selection_field,
                secondary.id,
                retrieve_relations=True)

            return serialize(
                {singularize(secondary.model_name): secondary_item})
        elif all([primary_selected_item, secondary.model]):
            # user selected a nested model with primary key
            # (from the primary and the secondary models)
            # /users/user_1/roles -> all roles for this user
            relationships = primary_selected_item.get_all(
                secondary.model_name, retrieve_relations=True)
            return serialize({pluralize(secondary.model_name): relationships})
        else:
            # user selected a single item (from the primary model)
            if primary_selected_item:
                return serialize(
                    {primary.model_name: primary_selected_item.to_dict()})
            else:
                raise HTTPException(
                    msg.MODEL_DOES_NOT_EXIST.format(model=primary.model_name),
                    404)
    except (DoesNotExist, AttributeError) as e:
        self.__log.exception(str(e))
        raise HTTPException(msg.ITEM_DOES_NOT_EXIST, 404)
コード例 #5
0
def validate_input(validation_rules, request):
    # parse input data (validate or not!)
    # noinspection PyBroadException
    try:
        query_data = parser.parse(validation_rules, request)
    except:
        raise HTTPException(msg.VALIDATION_FAILED, 422)

    if not query_data:
        # if a non-existent property is present or misspelled,
        # the json_data property is empty!
        raise HTTPException(msg.INVALID_PROPERTIES, 409)

    return query_data
コード例 #6
0
def validate_models(self,
                    primary_id=None,
                    secondary_model_name=None,
                    secondary_id=None):

    class Primary:
        id = None
        model = None
        model_name = None
        selection_field = None

    class Secondary:
        id = None
        model = None
        model_name = None
        selection_field = None

    if primary_id:
        Primary.id = escape(unquote(primary_id))

    Primary.model = self.__model__.get("primary")
    Primary.model_name = Primary.model.__name__.lower()
    Primary.selection_field = self.__selection_field__.get("primary")

    if secondary_model_name:
        Secondary.model_name = escape(unquote(secondary_model_name))

        if secondary_id:
            Secondary.id = escape(unquote(secondary_id))

        Secondary.model = Secondary.selection_field = None

        if "secondary" in self.__model__:
            Secondary.model = self.__model__.get(
                "secondary").get(Secondary.model_name)

        if "secondary" in self.__selection_field__:
            Secondary.selection_fields = self.__selection_field__.get(
                "secondary")
            Secondary.selection_field = Secondary.selection_fields.get(
                Secondary.model_name)

        if all([Secondary.model_name is not None,
                Secondary.model is None]):
            raise HTTPException(msg.RELATION_DOES_NOT_EXIST, 404)

    return (Primary, Secondary)
コード例 #7
0
def put(self,
        request,
        primary_id,
        secondary_model_name=None,
        secondary_id=None):
    try:
        # patch __log
        self.__log = self._GRest__log

        (primary, secondary) = validate_models(self, primary_id,
                                               secondary_model_name,
                                               secondary_id)

        primary_selected_item = None
        if primary.id is not None:
            primary_selected_item = primary.model.nodes.get_or_none(
                **{primary.selection_field: primary.id})

        secondary_selected_item = None
        if secondary.id is not None:
            secondary_selected_item = secondary.model.nodes.get_or_none(
                **{secondary.selection_field: secondary.id})

        if all([
                primary_selected_item, secondary_selected_item,
                secondary.model, secondary.id
        ]):
            # user either wants to update a relation or
            # has provided invalid information
            if hasattr(primary_selected_item, secondary.model_name):
                # Get relation between primary and secondary objects
                relation = getattr(primary_selected_item, secondary.model_name)

                # If there is a relation model between the two,
                # validate requests based on that
                relation_model = relation.definition["model"]
                json_data = {}
                if relation_model is not None:
                    # TODO: find a way to validate relationships
                    json_data = request.get_json(silent=True)

                with db.transaction:
                    # remove all relationships
                    for each_relation in relation.all():
                        relation.disconnect(each_relation)

                    if not json_data:
                        related_item = relation.connect(
                            secondary_selected_item)
                    else:
                        related_item = relation.connect(
                            secondary_selected_item, json_data)

                    if related_item:
                        return serialize(dict(result="OK"))
                    else:
                        raise HTTPException(msg.RELATION_DOES_NOT_EXIST, 404)
        elif all([
                primary_selected_item is not None, secondary.model is None,
                secondary.id is None
        ]):
            # a single item is going to be updated(/replaced) with the
            # provided JSON data

            # parse input data (validate or not!)
            json_data = validate_input(primary.model().validation_rules,
                                       request)

            # delete old node and its relations
            primary_selected_item.delete()

            with db.transaction:
                new_item = primary.model(**json_data).save()
                new_item.refresh()

            return serialize({
                primary.selection_field:
                getattr(new_item, primary.selection_field)
            })
        else:
            raise HTTPException(msg.BAD_REQUEST, 400)
    except (DoesNotExist, AttributeError) as e:
        self.__log.exception(e.message)
        raise HTTPException(msg.ITEM_DOES_NOT_EXIST, 404)
    except UniqueProperty as e:
        self.__log.exception(e.message)
        raise HTTPException(msg.NON_UNIQUE_PROPERTIY, 409)
    except RequiredProperty as e:
        self.__log.exception(e.message)
        raise HTTPException(msg.REQUIRE_PROPERTY_MISSING, 500)
コード例 #8
0
ファイル: delete.py プロジェクト: harlekeyn/grest
def delete(self,
           request,
           primary_id,
           secondary_model_name=None,
           secondary_id=None):
    try:
        # patch __log
        self.__log = self._GRest__log

        (primary, secondary) = validate_models(self,
                                               primary_id,
                                               secondary_model_name,
                                               secondary_id)

        primary_selected_item = None
        if primary.id is not None:
            primary_selected_item = primary.model.nodes.get_or_none(
                **{primary.selection_field: primary.id})

        secondary_selected_item = None
        if secondary.id is not None:
            secondary_selected_item = secondary.model.nodes.get_or_none(
                **{secondary.selection_field: secondary.id})

        if all([primary_selected_item,
                secondary_selected_item,
                secondary.model,
                secondary.id]):
            # user either wants to delete a relation or
            # has provided invalid information
            if hasattr(primary_selected_item, secondary.model_name):
                relation_exists = primary_selected_item.relation_exists(
                    secondary.model_name,
                    secondary_selected_item)
                if not relation_exists:
                    # There is an no relation
                    raise HTTPException(msg.RELATION_DOES_NOT_EXIST, 404)
                else:
                    # Get relation between primary and secondary objects
                    relation = getattr(
                        primary_selected_item,
                        secondary.model_name)

                    with db.transaction:
                        # remove all relationships
                        for each_relation in relation.all():
                            relation.disconnect(each_relation)

                        if secondary_selected_item not in relation.all():
                            return serialize(dict(result="OK"))
                        else:
                            raise HTTPException(msg.DELETE_FAILED,
                                                500)
        elif all([primary_selected_item is not None,
                  secondary.model is None,
                  secondary.id is None]):
            with db.transaction:
                if primary_selected_item.delete():
                    return serialize(dict(result="OK"))
                else:
                    raise HTTPException(msg.DELETE_FAILED, 500)
        else:
            raise HTTPException(msg.RELATION_DOES_NOT_EXIST, 404)
    except (DoesNotExist, AttributeError) as e:
        self.__log.exception(e)
        raise HTTPException(msg.ITEM_DOES_NOT_EXIST, 404)
    except UniqueProperty as e:
        self.__log.exception(e)
        raise HTTPException(msg.NON_UNIQUE_PROPERTY, 409)
    except RequiredProperty as e:
        self.__log.exception(e)
        raise HTTPException(msg.REQUIRE_PROPERTY_MISSING, 500)
コード例 #9
0
def post(self: FlaskView,
         primary_id: Optional[str] = None,
         secondary_model_name: Optional[str] = None,
         secondary_id: Optional[str] = None) -> "grest.GRestResponse":
    try:
        # patch __log
        self.__log = self._GRest__log

        (primary, secondary) = validate_models(self, primary_id,
                                               secondary_model_name,
                                               secondary_id)

        primary_selected_item = None
        if primary.id is not None:
            primary_selected_item = primary.model.nodes.get_or_none(
                **{primary.selection_field: primary.id})

        secondary_selected_item = None
        if secondary.id is not None:
            secondary_selected_item = secondary.model.nodes.get_or_none(
                **{secondary.selection_field: secondary.id})

        if all([
                primary_selected_item, secondary_selected_item,
                secondary.model, secondary.id
        ]):
            # user either wants to update a relation or
            # has provided invalid information
            if hasattr(primary_selected_item, secondary.model_name):
                relation_exists = primary_selected_item.relation_exists(  # type: ignore
                    secondary.model_name, secondary_selected_item)
                if relation_exists:
                    # There is an existing relation
                    raise HTTPException(msg.RELATION_EXISTS, 409)
                else:
                    # Get relation between primary and secondary objects
                    relation = getattr(primary_selected_item,
                                       secondary.model_name)

                    # If there is a relation model between the two,
                    # validate requests based on that
                    relation_model = relation.definition["model"]
                    json_data: Optional[Any] = None
                    if relation_model is not None:
                        # TODO: find a way to validate relationships
                        json_data = request.get_json(silent=True)

                    with db.transaction:
                        if not json_data:
                            related_item = relation.connect(
                                secondary_selected_item)
                        else:
                            related_item = relation.connect(
                                secondary_selected_item, json_data)

                        if related_item:
                            return serialize(dict(result="OK"))
                        else:
                            raise HTTPException(msg.RELATION_DOES_NOT_EXIST,
                                                404)
        elif all([
                primary_selected_item is None, secondary.model is None,
                secondary.id is None
        ]):
            new_item = primary.model()

            # parse input data (validate or not!)
            json_data = validate_input(new_item.validation_rules, request)

            # user wants to add a new item (from the primary model)
            new_item = primary.model.nodes.get_or_none(**json_data)

            if not new_item:
                with db.transaction:
                    new_item = primary.model(**json_data).save()
                    new_item.refresh()

                return serialize({
                    primary.selection_field:
                    getattr(new_item, primary.selection_field)
                })
            else:
                raise HTTPException(
                    msg.ITEM_EXISTS.format(item=primary.model_name), 409)
        else:
            raise HTTPException(msg.BAD_REQUEST, 400)
    except (DoesNotExist, AttributeError) as e:
        self.__log.exception(str(e))
        raise HTTPException(msg.ITEM_DOES_NOT_EXIST, 404)
    except UniqueProperty as e:
        self.__log.exception(str(e))
        raise HTTPException(msg.NON_UNIQUE_PROPERTY, 409)
    except RequiredProperty as e:
        self.__log.exception(str(e))
        raise HTTPException(msg.REQUIRE_PROPERTY_MISSING, 500)

    return None