示例#1
0
    def setUp(self):
        self.app = create_app()
        self.client = self.app.test_client
        setup_db(self.app, 'trivia_test')

        db.drop_all()
        db.create_all()

        self.temp_categories = [
            Category('Science'),
            Category('Art'),
            Category('Geography'),
            Category('History'),
            Category('Entertainment'),
            Category('Sports')
        ]

        self.temp_questions = [
            Question('Whose autobiography is entitled \'I Know Why the Caged Bird Sings\'?', 'Maya Angelou', 2, 4),
            Question('What boxer\'s original name is Cassius Clay?', 'Muhammad Ali', 1, 4),
            Question('The Taj Mahal is located in which Indian city?', 'Agra', 2, 3),
            Question('Which Dutch graphic artist–initials M C was a creator of optical illusions?', 'Escher', 1, 2),
            Question('What is the heaviest organ in the human body?', 'The Liver', 4, 1)
        ]

        db.session.add_all(self.temp_categories)
        db.session.add_all(self.temp_questions)
        db.session.commit()
示例#2
0
    def setUp(self):
        """
        Define test variables and initialize app.
        Create two test questions and two categories
        """

        self.app = app
        self.client = self.app.test_client
        self.database_path = os.environ.get('URI_TEST')
        setup_db(self.app, self.database_path)


        self.sports_category = Category(type="sports")
        self.science_category = Category(type="science")

        db.session.add(self.sports_category)
        db.session.add(self.science_category)
        db.session.commit()

        self.sports_question = Question(question="Who is the GOAT of footbal",
                                        answer="Messi", difficulty=2, category_id=self.sports_category.id)
        self.science_question = Question(question="Who invented peniciline",
                                         answer="Fleming", difficulty=2, category_id=self.science_category.id)

        db.session.add(self.sports_question)
        db.session.add(self.science_question)
        db.session.commit()
示例#3
0
    def setUp(self):
        self.app = create_app()
        self.client = self.app.test_client
        # its better to use another database for testing, but here to make things simple I am using the same database
        setup_db(self.app)

        self.new_user = {'name': 'Jenny', 'email': '*****@*****.**'}
示例#4
0
    def setUp(self):
        """Define test variables and initialize app."""
        self.app = create_app()
        self.client = self.app.test_client
        self.database_name = "trivia_test"
        self.database_path = "postgres://{}:{}@{}/{}".format(
            'postgres', 'psql', 'localhost:5432', self.database_name)
        setup_db(self.app, self.database_path)
        
        self.new_question = {
            'question': 'New question',
            'answer': 'New answer',
            'category': 3,
            'difficulty': 2
        }

        self.quiz = {
            'previous_questions': [],
            'quiz_category': {
                'type': 'Art',
                'id': 1,
            }
        }
        # binds the app to the current context
        with self.app.app_context():
            self.db = SQLAlchemy()
            self.db.init_app(self.app)
            # create all tables
            self.db.create_all()
示例#5
0
    def setUp(self):
        """Define test variables and initialize app."""
        self.app = create_app()
        self.client = self.app.test_client
        self.database_name = os.getenv('TEST_DATABASE_NAME')
        self.database_user = os.getenv('DATABASE_USER')
        self.database_password = os.getenv('DATABASE_PASSWORD')
        self.database_path = "postgresql://{}:{}@{}/{}".format(
            self.database_user, self.database_password, 'localhost:5432',
            self.database_name)
        setup_db(self.app, self.database_path)

        # binds the app to the current context
        with self.app.app_context():
            self.db = SQLAlchemy()
            self.db.init_app(self.app)
            # create all tables
            self.db.create_all()
            # add a question to a category in the test database
            self.category = Category(type='Asia')
            self.db.session.add(self.category)
            self.db.session.flush()
            self.question = Question(question='Where is China?',
                                     answer='In Asia',
                                     category=self.category.id,
                                     difficulty=2)
            self.db.session.add(self.question)
            self.db.session.commit()
示例#6
0
 def setUp(self):
     """Define test variables and initialize app."""
     self.app = create_app()
     self.database_path = f"postgresql://{DATABASE_USER_PASSWORD}@{DATABASE_HOST}:{DATABASE_PORT}/{DATABASE_NAME}"
     setup_db(self.app, self.database_path)
     self.db = db
     self.db.create_all()  # Create the schema
     self.client = self.app.test_client()  # initialize the http client
示例#7
0
    def setUp(self):
        self.app = create_app(TestConfig)
        self.client = self.app.test_client()
        self.app_context = self.app.app_context()
        self.app_context.push()

        db.drop_all()
        setup_db()
    def setUp(self):
        """Define test variables and initialize app."""
        self.app = create_app()
        self.client = self.app.test_client
        setup_db(self.app)

        # binds the app to the current context
        with self.app.app_context():
            self.db = SQLAlchemy()
            self.db.init_app(self.app)
            # create all tables
            self.db.create_all()
示例#9
0
 def setUp(self):
     """Executed before each test. Define test variables and initialize app."""
     self.app = create_app()
     self.client = self.app.test_client
     self.client = self.app.test_client
     self.database_name = "bookshelf"
     self.database_path = "postgresql://{}:{}@{}/{}".format(
         'student', 'student', 'localhost:5432', self.database_name)
     setup_db(self.app, self.database_path)
     self.newbook = {
         'title': 'test_book',
         'author': 'some_one',
         'rating': 5
     }
示例#10
0
    def setUp(self):
        """Initialize testing app"""
        self.app = create_app('testing')
        self.client = self.app.test_client()

        with self.app.app_context():
            # setUp db on the app
            setup_db(self.app)

        self.new_question = {
            "question": "Do you love Coding?",
            "answer": "yes",
            "category": 5,
            "difficulty": 3
        }
示例#11
0
    def setUp(self):
        """Define test variables and initialize app."""
        self.app = create_app()
        self.client = self.app.test_client
        self.database_name = "trivia_test"
        self.database_path = "postgres://{}/{}".format(
            'localhost:5432', self.database_name)
        setup_db(self.app, self.database_path)

        # binds the app to the current context
        with self.app.app_context():
            self.db = SQLAlchemy()
            self.db.init_app(self.app)
            # create all tables
            self.db.create_all()
示例#12
0
def create_app(config=None):
    # create and configure the app
    app = Flask(__name__)

    if config is not None:
        app.config.from_object(config)

    setup_db(app)

    CORS(app)

    create_routes(app)

    create_error_handlers(app)

    return app
示例#13
0
def create_app(test_config=None):
    app = Flask(__name__)
    setup_db(app)
    CORS(app)

    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Headers',
                             'Content-Type, Authorization')
        response.headers.add('Access-Control-Allow-Methods',
                             'GET, POST, PATCH, DELETE, OPTIONS')
        return response

    @app.route('/plants', methods=['GET', 'POST'])
    def get_plants():
        page = request.args.get('page', 1, type=int)
        start = (page - 1) * 10
        end = start + 10
        plants = Plant.query.all()
        formatted_plants = []
        for plant in plants:
            formatted_plants.append(plant.name)

        return jsonify({
            "success": True,
            "plants": formatted_plants[start:end],
            "total_plants": len(formatted_plants)
        })

    @app.route('/plants/<int:plant_id>')
    def get_specific_plant(plant_id):
        plant = Plant.query.filter(Plant.id == plant_id).one_or_none()

        if plant is None:
            abort(404)
        else:
            return jsonify({'success': True, 'plant': plant.name})

    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            "success": False,
            "error": 404,
            "message": "resource not found"
        }), 404

    return app
def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__)
    configure_app(app)
    setup_db(app)
    CORS(app)
    app.register_blueprint(trivia)

    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Headers',
                             'Content-Type,Authorization,true')
        response.headers.add('Access-Control-Allow-Methods',
                             'GET,PUT,POST,DELETE,OPTIONS')
        return response


    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            "success": False,
            "error": 404,
            "message": "resource not found"
        }), 404

    @app.errorhandler(422)
    def unprocessable(error):
        return jsonify({
            "success": False,
            "error": 422,
            "message": "unprocessable"
        }), 422

    @app.errorhandler(400)
    def bad_request(error):
        return jsonify({
            "success": False,
            "error": 400,
            "message": "bad request"
        }), 400

    return app
示例#15
0
    def setUp(self):
        """Define test variables and initialize app."""
        self.app = create_app()
        self.client = self.app.test_client
        self.database_name = "bookshelf"
        self.database_path = "postgres:///" + self.database_name
        setup_db(self.app, self.database_path)

        self.new_book = {
            'title': 'Anansi Boys',
            'author': 'Neil Gaiman',
            'rating': 5
        }

        # binds the app to the current context
        with self.app.app_context():
            self.db = SQLAlchemy()
            self.db.init_app(self.app)
            # create all tables
            self.db.create_all()
示例#16
0
    def setUp(self):
        """Define test variables and initialize app."""
        self.app = create_app()
        self.client = self.app.test_client
        self.database_name = "trivia_test"
        self.database_path = "postgresql://postgres@{}/{}".format(
            'localhost:5432', self.database_name)
        setup_db(self.app, self.database_path)

        self.new_question = {
            "question":
            "Which position player holds the NFL record for most touchdowns?",
            "answer": "Jerry Rice",
            "category": "6",
            "difficulty": 3
        }

        # binds the app to the current context
        with self.app.app_context():
            self.db = SQLAlchemy()
            self.db.init_app(self.app)
            # create all tables
            self.db.create_all()
def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__)
    setup_db(app)
    cors = CORS(app)

    QUESTIONS_PER_PAGE = 10

    @app.route('/')
    def home():
        return jsonify("hello word")

    '''
  @TODO: Set up CORS. Allow '*' for origins. Delete the sample route after completing the TODOs
  '''
    '''
  @TODO: Use the after_request decorator to set Access-Control-Allow
  '''

    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Headers',
                             'Content-Type,Authorization,true')
        response.headers.add('Access-Control-Allow-Methods',
                             'GET,PATCH,POST,DELETE,OPTIONS')
        return response

    '''
  @TODO: 
  Create an endpoint to handle GET requests 
  for all available categories.
  '''

    @app.route("/category", methods=['GET'])
    def get_categories():
        categories = Category.query.all()
        format_category = [category.format() for category in categories]
        lista = []
        for i in categories:
            lista.append(i.type)
        return jsonify({'category': lista})

    '''
  @TODO: 
  Create an endpoint to handle GET requests for questions, 
  including pagination (every 10 questions). 
  This endpoint should return a list of questions, 
  number of total questions, current category, categories. 

  TEST: At this point, when you start the application
  you should see questions and categories generated,
  ten questions per page and pagination at the bottom of the screen for three pages.
  Clicking on the page numbers should update the questions. 
  '''

    @app.route("/questions", methods=['GET'])
    def get_questions():
        page = request.args.get('page', 1, type=int)
        start = (page - 1)
        end = QUESTIONS_PER_PAGE
        questions = Question.query.all()
        format_Question = [question.format() for question in questions]
        category = Category.query.all()
        format_category = [categories.format() for categories in category]
        cat = []
        lista = []
        for i in category:
            cat.append(i.type)

        for i in questions:
            ndict = {}
            ndict["answer"] = i.answer
            categoria = Category.query.get(i.category)
            ndict["category"] = i.category
            ndict["difficulty"] = i.difficulty
            ndict["id"] = i.id
            ndict["question"] = i.question
            lista.append(ndict)

        return jsonify({
            'questions': format_Question,
            'totalQuestion': len(format_Question),
            'categories': cat,
        })

    '''
  @TODO: 
  Create an endpoint to DELETE question using a question ID. 

  TEST: When you click the trash icon next to a question, the question will be removed.
  This removal will persist in the database and when you refresh the page. 
  '''

    @app.route("/questions/<int:id>/delete", methods=['DELETE'])
    def delete_questions(id):
        question = Question.query.get(id)
        Question.delete(question)
        return jsonify({'success': True})

    @app.route("/add/questions", methods=['POST'])
    def add_questions():
        resposta = request.get_json()
        print(resposta)
        cat = int(resposta['category'])
        print(cat)
        question = Question(question=resposta['question'],
                            answer=resposta['answer'],
                            category=cat + 1,
                            difficulty=resposta['difficulty'])
        Question.insert(question)
        return jsonify({'success': True})

    '''
  @TODO: 
  Create an endpoint to POST a new question, 
  which will require the question and answer text, 
  category, and difficulty score.

  TEST: When you submit a question on the "Add" tab, 
  the form will clear and the question will appear at the end of the last page
  of the questions list in the "List" tab.  
  '''
    '''
  @TODO: 
  Create a POST endpoint to get questions based on a search term. 
  It should return any questions for whom the search term 
  is a substring of the question. 

  TEST: Search by any phrase. The questions list will update to include 
  only question that include that string within their question. 
  Try using the word "title" to start. 
  '''
    '''
  @TODO: 
  Create a GET endpoint to get questions based on category. 

  TEST: In the "List" tab / main screen, clicking on one of the 
  categories in the left column will cause only questions of that 
  category to be shown. 
  '''
    '''
  @TODO: 
  Create a POST endpoint to get questions to play the quiz. 
  This endpoint should take category and previous question parameters 
  and return a random questions within the given category, 
  if provided, and that is not one of the previous questions. 

  TEST: In the "Play" tab, after a user selects "All" or a category,
  one question at a time is displayed, the user is allowed to answer
  and shown whether they were correct or not. 
  '''

    @app.route("/searchquestion", methods=['POST'])
    def search():
        resposta = request.get_json()
        comp = resposta.lower()
        ## questions
        totQuestions = []
        question = Question.query.all()
        for i in question:
            ndict = {}
            if comp in i.question.lower():
                ndict['question'] = i.question
                ndict['category'] = i.category
                ndict['difficulty'] = i.difficulty
                ndict['answer'] = i.answer
                totQuestions.append(ndict)
        ## totalquestions
        ## currentcategory
        return jsonify({
            'questions': totQuestions,
            'totalQuestions': len(totQuestions),
        })

    @app.route("/categories/<int:id>/questions", methods=['GET'])
    def get_questions_categories(id):
        questions = Question.query.filter_by(category=str(id + 1))
        format_Question = [question.format() for question in questions]
        current_categorie = Category.query.get(int(id + 1))
        ques = []

        for i in questions:
            ques.append(i.question)

        return jsonify({
            'questions': format_Question,
            'totalQuestion': len(ques),
            'category': current_categorie.type
        })

    @app.route("/quizzes", methods=['POST'])
    def play_game():
        resposta = request.get_json()
        previous = resposta['previous_questions']
        category = int(resposta['quiz_category']['id']) + 1
        if resposta['quiz_category']['type'] == 'click':
            question = Question.query.all()
        else:
            question = Question.query.filter_by(category=str(category))
        if len(previous) <= 5:
            format_Question = [question.format() for question in question]
            numero = random.randrange(0, len(format_Question))
            print(numero)
            actual_question = format_Question[numero]
            if actual_question['id'] in previous:
                actual_question = ""
        return jsonify({'question': actual_question})

    '''
  @TODO: 
  Create error handlers for all expected errors 
  including 404 and 422.
  '''

    @app.errorhandler(404)
    def page_not_found(e):
        # note that we set the 404 status explicitly
        return jsonify('BAD request!'), 404

    @app.errorhandler(422)
    def other_error(e):
        # note that we set the 404 status explicitly
        return jsonify('Empty page!'), 404

    return app
示例#18
0
from flask import Flask
from flask_cors import CORS
from flaskr.models import setup_db

app = Flask(__name__)
setup_db(app)

CORS(app,
     resources={r"/api/v1/*": {
         "origins": "*"
     }},
     supports_credentials=True)


@app.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Headers',
                         'Content-Type,Authorization,true')
    response.headers.add('Access-Control-Allow-Methods',
                         'GET,PUT,POST,DELETE,PATCH,OPTIONS')
    return response


import flaskr.controllers.error
import flaskr.controllers.category
import flaskr.controllers.question
示例#19
0
def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__)
    setup_db(app)
    '''
  @TODO: Set up CORS. Allow '*' for origins.
  Delete the sample route after completing the TODOs
  '''
    CORS(app, resources={r"/api/*": {"origins": "*"}})
    '''
  @TODO: Use the after_request decorator to set Access-Control-Allow
  '''
    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Headers',
                             'Content-Type,Authorization,true')
        response.headers.add('Access-Control-Allow-Methods',
                             'GET,PUT,POST,DELETE,OPTIONS')
        return response

    '''
  @TODO:
  Create an endpoint to handle GET requests
  for all available categories.
  '''

    @app.route('/categories')
    def retrieve_categories():
        try:
            selection = Category.query.order_by('id').all()
            result = [item.format for item in selection]
            return jsonify({
                'success': True,
                'categories': result,
                'total_categories': len(Category.query.all())
            })
        except ():
            abort(500)

    '''
  @TODO:

  Create an endpoint to handle GET requests for questions,
  including pagination (every 10 questions).
  This endpoint should return a list of questions,
  number of total questions, current category, categories.
  TEST: At this point, when you start the application
  you should see questions and categories generated,
  ten questions per page and pagination at the
  bottom of the screen for three pages.
  Clicking on the page numbers should update the questions.
  '''

    @app.route('/questions', methods=['GET'])
    def retrieve_questions():
        try:
            selection = Question.query.order_by('id').all()
            result = [item.format for item in selection]
            page = request.args.get('page')

            if page:
                paged_result = paginate_questions(request, selection)
            else:
                paged_result = result

            categories = Category.query.order_by('id').all()
            formateed_categories = [item.format for item in categories]

            return jsonify({
                'success': True,
                'questions': paged_result,
                'total_questions': len(selection),
                'current_category': None,
                'categories': formateed_categories
            })
        except ():
            return abort(500)

    '''
  @TODO:
  Create an endpoint to DELETE question using a question ID.
  TEST: When you click the trash icon next to a question,
  the question will be removed.
  This removal will persist in the database and when you refresh the page.
  '''

    @app.route('/questions/<int:question_id>', methods=['DELETE'])
    def delete_question_by_Id(question_id):
        try:
            question = Question.query.get(question_id)

            if question is None:
                abort(404)

            question.delete()
            selection = Question.query.order_by('id').all()
            result = [item.format for item in selection]
            paged_result = paginate_questions(request, selection)

            return jsonify({
                'success': True,
                'deleted': question.id,
                'questions': paged_result,
                'total_questions': len(selection)
            })

        except ():
            abort(422)

    '''
  @TODO:
  Create an endpoint to POST a new question,
  which will require the question and answer text,
  category, and difficulty score.
  TEST: When you submit a question on the "Add" tab,
  the form will clear and the question will appear at the end of the last page
  of the questions list in the "List" tab.
  '''

    @app.route('/questions', methods=['POST'])
    def create_question():
        try:
            body = request.get_json()
            search_term = body.get('search', None)

            if body == {}:
                abort(422)

            # question search
            if search_term is not None:
                search = "{}".format(search_term.lower())

                search_results = Question.query.filter(
                    Question.question.ilike('%' + search + '%')).all()

                formatted_search_results = [
                    question.format for question in search_results
                ]
                paginated_results = paginate_questions(request, search_results)

                return jsonify({
                    'success': True,
                    'questions': paginated_results,
                    'total_questions': len(search_results)
                })
            # question add
            else:
                question = body.get('question', None)
                answer = body.get('answer', None)
                category = body.get('category', None)
                difficulty = body.get('difficulty', None)

                if question is None or answer is None or category is None or difficulty is None:
                    abort(422)

                new_question = Question(question=question,
                                        answer=answer,
                                        category=category,
                                        difficulty=difficulty)
                new_question.insert()

                selection = Question.query.order_by('id').all()
                paged_questions = paginate_questions(request, selection)

                return jsonify({
                    'success': True,
                    'created': new_question.id,
                    'questions': paged_questions,
                    'total_questions': len(selection)
                }), 201

        except ():
            abort(422)

    '''
  @TODO:
  Create a POST endpoint to get questions based on a search term.
  It should return any questions for whom the search term
  is a substring of the question.
  TEST: Search by any phrase. The questions list will update to include
  only question that include that string within their question.
  Try using the word "title" to start.
  '''
    '''
  @TODO:
  Create a GET endpoint to get questions based on category.
  TEST: In the "List" tab / main screen, clicking on one of the
  categories in the left column will cause only questions of that
  category to be shown.
  '''

    @app.route('/questions/<int:question_id>')
    def get_question_by_Id(question_id):
        try:
            question = Question.query.get(question_id)

            if question is None:
                abort(404)

            formatted_question = question.format

            return jsonify({'success': True, 'question': formatted_question})
        except ():
            abort(500)

    @app.route('/categories/<int:category_id>/questions', methods=['GET'])
    def get_questions_by_category(category_id):
        try:
            questions = Question.query.filter(
                Question.category == str(category_id)).all()

            category = Category.query.get(str(category_id))

            get_all_cat = Category.query.order_by('id').all()
            formatted_cat = [item.format for item in get_all_cat]

            if category_id < 1 or category is None:
                abort(404)

            if questions is None:
                total_questions = 0
                paginated_questions = []
            else:
                total_questions = [question.format for question in questions]
                paginated_questions = paginate_questions(request, questions)

            return jsonify({
                'success':
                True,
                'questions':
                paginated_questions,
                'total_questions':
                len(total_questions),
                'current_category':
                Category.query.get(str(category_id)).format,
                'categories':
                formatted_cat
            })

        except ():
            abort(500)

    '''
  @TODO:
  Create a POST endpoint to get questions to play the quiz.
  This endpoint should take category and previous question parameters
  and return a random questions within the given category,
  if provided, and that is not one of the previous questions.
  TEST: In the "Play" tab, after a user selects "All" or a category,
  one question at a time is displayed, the user is allowed to answer
  and shown whether they were correct or not.
  '''

    @app.route('/quizzes', methods=['POST'])
    def play_quiz():
        try:
            body = request.get_json()

            if body.get('quiz_category') is None or body.get(
                    'previous_questions') is None:
                abort(422)

            quiz_category_id = body.get('quiz_category', None)['id']
            previous_questions = body.get('previous_questions', None)

            if quiz_category_id == 0:
                questions = Question.query.order_by(func.random()).all()
            else:
                questions = Question.query.\
                    filter(
                        Question.category == quiz_category_id).\
                    order_by(func.random()).all()

            formatted_questions = [question.format for question in questions]
            available_questions = []
            for q in formatted_questions:
                if len(previous_questions) == 0:
                    available_questions.append(q)
                elif len(previous_questions) >= 0:
                    found = q['id'] not in previous_questions
                    if found is True:
                        available_questions.append(q)

            if len(available_questions) > 0:
                return jsonify({
                    'success': True,
                    'question': available_questions[0]
                })
            else:
                return jsonify({'success': True, 'question': None})
        except ():
            abort(422)

    '''
  @TODO:
  Create error handlers for all expected errors
  including 404 and 422.
  '''

    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            "success": False,
            "error": 404,
            "message": "resource not found"
        }), 404

    @app.errorhandler(422)
    def not_processable(error):
        return jsonify({
            "success": False,
            "error": 422,
            "message": "unprocessable"
        }), 422

    @app.errorhandler(500)
    def server_error(error):
        return jsonify({
            "success": False,
            "error": 500,
            "message": "internal server error"
        }), 500

    return app
示例#20
0
def create_app(test_config=None):
    app = Flask(__name__)
    setup_db(app)
    CORS(app)

    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Headers',
                             'Content-Type, Authorization')
        response.headers.add('Access-Control-Allow-Methods',
                             'GET, POST, PATCH, DELETE, OPTIONS')
        return response

    @app.route('/users')
    def get_users():
        users = User.query.order_by(User.id).all()
        current_users = paginate_users(request, users)

        if len(current_users) == 0:
            abort(404)

        try:
            return jsonify({
                'success': True,
                'users': current_users,
                'total_users': len(User.query.all())
            })
        except:
            abort(400)

    @app.route('/users/<int:user_id>')
    def get_specific_user(user_id):
        user = User.query.filter(User.id == user_id).one_or_none()

        if user is None:
            abort(404)

        else:
            return jsonify({'success': True, 'user': user.format()})

    @app.route('/users/<int:user_id>', methods=['PATCH'])
    def update_user(user_id):
        body = request.get_json()

        try:
            user = User.query.filter(User.id == user_id).one_or_none()
            if user is None:
                abort(404)

            if 'name' in body:
                user.name = str(body.get('name'))
            else:
                abort(400)

            user.update()

            return jsonify({'success': True, 'id': user_id})

        except:
            abort(400)

    @app.route('/users', methods=['POST'])
    def create_user():
        body = request.get_json()

        name = body.get('name', None)
        email = body.get('email', None)

        try:
            user = User(name=name, email=email)
            user.insert()

            users = User.query.order_by(User.id).all()
            current_users = paginate_users(request, users)

            return jsonify({
                'success': True,
                'created': user.id,
                'users': current_users,
                'total_users': len(User.query.all())
            })

        except:
            abort(422)

    @app.route('/users/<int:user_id>', methods=['DELETE'])
    def delete_user(user_id):
        try:
            user = User.query.filter(User.id == user_id).one_or_none()

            if user is None:
                abort(404)

            user.delete()

            users = User.query.order_by(User.id).all()
            current_users = paginate_users(request, users)

            return jsonify({
                'success': True,
                'deleted': user_id,
                'users': current_users,
                'total_users': len(User.query.all())
            })

        except:
            abort(422)

    @app.route('/users/search', methods=['POST'])
    def search_user():
        try:
            body = request.get_json()
            name = str(body.get('name'))

            users = User.query.filter(User.name.ilike(
                '%{}%'.format(name))).all()

            if users is None:
                abort(404)

            current_users = paginate_users(request, users)

            return jsonify({
                'success': True,
                'users': current_users,
                'total_users': len(users)
            })
        except:
            abort(422)

    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            'success': False,
            'error': 404,
            'message': 'resource not found'
        }), 404

    @app.errorhandler(422)
    def unprocessable(error):
        return jsonify({
            'success': False,
            'error': 422,
            'message': 'unprocessable'
        }), 422

    @app.errorhandler(400)
    def bad_request(error):
        return jsonify({
            'success': False,
            'error': 400,
            'message': 'bad request'
        }), 400

    @app.errorhandler(405)
    def not_allowed(error):
        return jsonify({
            'success': False,
            'error': 405,
            'message': 'method not allowed'
        }), 405

    return app