def test_unit__get_output_validation_error__ok__exception_transmitted(
            self, serpyco_processor: SerpycoProcessor) -> None:
        serpyco_processor.set_schema(UserSchema)
        validation_error = serpyco_processor.get_output_validation_error(
            {"name": 42})

        assert validation_error.original_exception
    def test_unit__load_files_input__ok__one_file(
            self, serpyco_processor: SerpycoProcessor) -> None:
        serpyco_processor.set_schema(OneFileSchema)
        input_data = serpyco_processor.load_files_input({"file1": b"42"})

        assert isinstance(input_data, OneFileSchema)
        assert b"42" == input_data.file1
    def test_unit__get_input_files_validation_error__ok__missing_one_file(
            self, serpyco_processor: SerpycoProcessor) -> None:
        serpyco_processor.set_schema(OneFileSchema)
        error = serpyco_processor.get_input_files_validation_error({})

        assert {"file1": "data is missing"} == error.details
        assert "Validation error of input data" == error.message
Beispiel #4
0
class BottleController(object):
    @hapic.with_api_doc()
    @hapic.output_body(AboutSchema)
    def about(self):
        """
        This endpoint allow to check that the API is running. This description
        is generated from the docstring of the method.
        """
        return DictLikeObject({"version": "1.2.3", "datetime": datetime.now()})

    @hapic.with_api_doc()
    @hapic.output_body(UserDigestSchema, processor=SerpycoProcessor(many=True))
    def get_users(self):
        """
        Obtain users list.
        """
        return UserLib().get_users()

    @hapic.with_api_doc()
    @hapic.handle_exception(UserNotFound, HTTPStatus.NOT_FOUND)
    @hapic.input_path(UserIdPathSchema)
    @hapic.output_body(UserSchema)
    def get_user(self, id, hapic_data: HapicData):
        """
        Return a user taken from the list or return a 404
        """
        return UserLib().get_user(int(hapic_data.path.id))

    @hapic.with_api_doc()
    # TODO - G.M - 2017-12-5 - Support input_forms ?
    # TODO - G.M - 2017-12-5 - Support exclude, only ?
    @hapic.input_body(UserSchema, processor=SerpycoProcessor(exclude=["id"]))
    @hapic.output_body(UserSchema)
    def add_user(self, hapic_data: HapicData):
        """
        Add a user to the list
        """
        new_user = User(**hapic_data.body)
        return UserLib().add_user(new_user)

    @hapic.with_api_doc()
    @hapic.handle_exception(UserNotFound, HTTPStatus.NOT_FOUND)
    @hapic.output_body(NoContentSchema, default_http_code=204)
    @hapic.input_path(UserIdPathSchema)
    def del_user(self, id, hapic_data: HapicData):
        UserLib().del_user(int(hapic_data.path.id))
        return NoContentSchema()

    @hapic.with_api_doc()
    @hapic.handle_exception(UserNotFound, HTTPStatus.NOT_FOUND)
    @hapic.handle_exception(UserAvatarNotFound, HTTPStatus.NOT_FOUND)
    @hapic.input_path(UserIdPathSchema)
    @hapic.output_file(["image/png"])
    def get_user_avatar(self, id, hapic_data: HapicData):
        return HapicFile(
            file_path=UserLib().get_user_avatar_path(user_id=(int(hapic_data.path.id)))
        )

    @hapic.with_api_doc()
    @hapic.handle_exception(UserNotFound, HTTPStatus.NOT_FOUND)
    @hapic.handle_exception(UserAvatarNotFound, HTTPStatus.BAD_REQUEST)
    @hapic.input_path(UserIdPathSchema)
    @hapic.input_files(UserAvatarSchema)
    @hapic.output_body(NoContentSchema, default_http_code=204)
    def update_user_avatar(self, id, hapic_data: HapicData):
        UserLib().update_user_avatar(
            user_id=int(hapic_data.path.id), avatar=hapic_data.files.avatar
        )

    def bind(self, app: bottle.Bottle):
        app.route("/about", callback=self.about)
        app.route("/users/", callback=self.get_users)
        app.route("/users/<id>", callback=self.get_user)
        app.route("/users/", callback=self.add_user, method="POST")
        app.route("/users/<id>", callback=self.del_user, method="DELETE")
        app.route("/users/<id>/avatar", callback=self.get_user_avatar)
        app.route("/users/<id>/avatar", callback=self.update_user_avatar, method="PUT")
    def test_unit__load_files_input__error__none_file_given(
            self, serpyco_processor: SerpycoProcessor) -> None:
        serpyco_processor.set_schema(OneFileSchema)

        with pytest.raises(OutputValidationException):
            serpyco_processor.load_files_input({"file1": None})
def serpyco_processor() -> SerpycoProcessor:
    yield SerpycoProcessor()
Beispiel #7
0
class AiohttpSerpycoController(object):
    @hapic.with_api_doc()
    @hapic.output_body(AboutResponseSchema)
    # FIXME BS 2018-12-13: Manage error cases (#118)
    # @hapic.handle_exception(ZeroDivisionError, http_code=400)
    async def about(self, request):
        """
        General information about this API.
        """
        return AboutResponseSchema(version="1.2.3",
                                   datetime=datetime(2017, 12, 7, 10, 55, 8,
                                                     488996))

    @hapic.with_api_doc()
    @hapic.output_body(ListsUserSchema)
    async def get_users(self, request):
        """
        Obtain users list.
        """
        some_user = UserSchema(
            id=4,
            username="******",
            display_name="Damien Accorsi",
            company="Algoo",
            first_name="Damien",
            last_name="Accorsi",
            email_address="damien@local",
        )
        return ListsUserSchema(
            item_nb=1,
            items=[some_user],
            pagination=PaginationSchema(first_id=0, last_id=5, current_id=0),
        )

    @hapic.with_api_doc()
    @hapic.output_body(
        UserSchema,
        processor=SerpycoProcessor(
            many=True, only=["id", "username", "display_name", "company"]),
    )
    async def get_users2(self, request):
        """
        Obtain users list.
        """
        return [
            DictLikeObject({
                "id": 4,
                "username": "******",
                "display_name": "Damien Accorsi",
                "company": "Algoo",
            })
        ]

    @hapic.with_api_doc()
    @hapic.input_path(UserPathSchema)
    @hapic.output_body(UserSchema)
    async def get_user(self, request, hapic_data: HapicData):
        """
        Obtain one user
        """
        return UserSchema(
            id=4,
            username="******",
            email_address="*****@*****.**",
            first_name="Damien",
            last_name="Accorsi",
            display_name="Damien Accorsi",
            company="Algoo",
        )

    @hapic.with_api_doc()
    @hapic.input_body(UserSchema, processor=SerpycoProcessor(exclude=["id"]))
    @hapic.output_body(UserSchema)
    async def add_user(self, request, hapic_data: HapicData):
        """
        Add new user
        """
        return DictLikeObject({
            "id": 4,
            "username": "******",
            "email_address": "*****@*****.**",
            "first_name": "Damien",
            "last_name": "Accorsi",
            "display_name": "Damien Accorsi",
            "company": "Algoo",
        })

    @hapic.with_api_doc()
    @hapic.output_body(NoContentSchema, default_http_code=204)
    @hapic.input_path(UserPathSchema)
    async def del_user(self, request, hapic_data: HapicData):
        """
        delete user
        """

    def bind(self, app):
        """

        app.route('/about', callback=self.about)
        app.route('/users', callback=self.get_users)
        app.route('/users2', callback=self.get_users2)
        app.route('/users/<id>', callback=self.get_user)
        app.route('/users/', callback=self.add_user,  method='POST')
        app.route('/users/<id>', callback=self.del_user, method='DELETE')
        :param app:
        :return:
        """

        app.add_routes([
            web.get("/about", self.about),
            web.get("/users", self.get_users),
            web.get("/users2", self.get_users2),
            web.get(r"/users/{id}", self.get_user),
            web.post("/users/", self.add_user),
            web.delete("/users/{id}", self.del_user),
        ])