def _create_prediction_endpoint(
            self,
            to_numpy=True,
            data_loader=json_numpy_loader,
            preprocessor=lambda x: x,
            input_validation=lambda data: (True, None),
            postprocessor=lambda x: x,
            make_serializable_post=True):
        """Create an endpoint to serve predictions.

        Arguments:
            - input_validation (fn): takes a numpy array as input;
                returns True if validation passes and False otherwise
            - data_loader (fn): reads flask request and returns data preprocessed to be
                used in the `predict` method
            - postprocessor (fn): transforms the predictions from the `predict` method
        """
        # copy instance variables to local scope for resource class
        predict = self.predict
        logger = self.app.logger

        # create restful resource
        class Predictions(Resource):
            @staticmethod
            def post():
                # read data from API request
                try:
                    data = data_loader()
                except Exception as e:
                    return exception_log_and_respond(e, logger, 'Unable to fetch data', 400)

                try:
                    if hasattr(preprocessor, '__iter__'):
                        for preprocessor_step in preprocessor:
                            data = preprocessor_step(data)
                    else:
                        data = preprocessor(data)  # preprocess data
                    data = np.array(data) if to_numpy else data  # convert to numpy
                except Exception as e:
                    return exception_log_and_respond(e, logger, 'Could not preprocess data', 400)

                # sanity check using user defined callback (default is no check)
                validation_pass, validation_reason = input_validation(data)
                if not validation_pass:
                    # if validation fails, log the reason code, log the data, and send a 400 response
                    validation_message = 'Input validation failed with reason: {}'.format(validation_reason)
                    logger.error(validation_message)
                    logger.debug('Data: {}'.format(data))
                    return make_response(validation_message, 400)

                try:
                    prediction = predict(data)
                except Exception as e:
                    # log exception and return the message in a 500 response
                    logger.debug('Data: {}'.format(data))
                    return exception_log_and_respond(e, logger, 'Unable to make prediction', 500)
                logger.debug(prediction)
                try:
                    # preprocess data
                    if hasattr(postprocessor, '__iter__'):
                        for postprocessor_step in postprocessor:
                            prediction = postprocessor_step(prediction)
                    else:
                        prediction = postprocessor(prediction)

                    # cast to serializable types
                    if make_serializable_post:
                        return make_serializable(prediction)
                    else:
                        return prediction

                except Exception as e:
                    return exception_log_and_respond(e, logger, 'Postprocessing failed', 500)

        # map resource to endpoint
        self.api.add_resource(Predictions, '/predictions')
Create an endpoint to serve predictions.

        Arguments:
            - input_validation (fn): takes a numpy array as input;
                returns True if validation passes and False otherwise
            - data_loader (fn): reads flask request and returns data preprocessed to be
                used in the `predict` method
            - postprocessor (fn): transforms the predictions from the `predict` method