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
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()
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), ])