def output_fn(prediction, accept):
    """Format prediction output
    
    The default accept/content-type between containers for serial inference is JSON.
    We also want to set the ContentType or mimetype as the same value as accept so the next
    container can read the response payload correctly.
    """

    accept = 'text/csv'
    if type(prediction) is not np.ndarray:
        prediction = prediction.toarray()

    if accept == "application/json":
        instances = []
        for row in prediction.tolist():
            instances.append({"features": row})

        json_output = {"instances": instances}

        return worker.Response(json.dumps(json_output), mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept),
                               mimetype=accept)
    else:
        raise RuntimeException(
            "{} accept type is not supported by this script.".format(accept))
def output_fn(inferences, accept):
    """Format inferences output
    
    The default accept/content-type between containers for serial inference is JSON.
    We also want to set the ContentType or mimetype as the same value as accept so the next
    container can read the response payload correctly.
    """
    if accept == "application/json":
        instances = []
        for inference in inferences.tolist():
            try:
                target, decision_boundary, prediction = inference
                instances.append({
                    "decision boundary": decision_boundary,
                    "prediction": prediction,
                    "target": target
                })
            except ValueError:
                decision_boundary, prediction = inference
                instances.append({
                    "decision boundary": decision_boundary,
                    "prediction": prediction
                })
        json_output = {"instances": instances}
        return worker.Response(json.dumps(json_output), mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept),
                               mimetype=accept)
    else:
        raise RuntimeError(
            "{} accept type is not supported by this script.".format(accept))
Esempio n. 3
0
def output_fn(prediction, accept):
    """Format prediction output

    The default accept/content-type between containers for serial inference is JSON.
    We also want to set the ContentType or mimetype as the same value as accept so the next
    container can read the response payload correctly.
    """
    print("output")
    print(prediction)

    if accept == "application/json":

        instances = []
        for row in prediction.tolist():
            instances.append({"features": row})
            h = np.asarray(row)
            string_row = [",".join(h.astype(str))][0]
            string_row_encode = string_row.encode()

            return worker.Response(string_row_encode,
                                   'text/csv',
                                   mimetype='text/csv')

        json_output = {"instances": instances}

        return worker.Response(json.dumps(json_output),
                               accept,
                               mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept),
                               accept,
                               mimetype=accept)
    else:
        raise RuntimeException(
            "{} accept type is not supported by this script.".format(accept))
Esempio n. 4
0
def output_fn(prediction, accept_type):
    """Encodes prediction to accept type.

    The SageMaker Scikit-learn model server invokes this method with the result of prediction and
    serializes this according to the response MIME type. It expects the input to be numpy array and encodes
    to requested response MIME type.

    Parameters
    ----------
    prediction : array-like
        the object returned from predict_fn

    accept_type : str
        the expected MIME type of the response

    Returns
    -------
    : Response obj
        serialized predictions in accept type

    """
    if isinstance(prediction, worker.Response):
        return prediction

    if _is_inverse_label_transform():
        if accept_type == 'text/csv':
            return worker.Response(response=encoders.encode(
                prediction, accept_type),
                                   status=http_client.OK,
                                   mimetype=accept_type)
        else:
            return worker.Response(
                response=f"Accept type '{accept_type}' is not supported "
                f"during inverse label transformation.",
                status=413)

    if isinstance(prediction, tuple):
        X, y = prediction
    else:
        X, y = _split_features_target(prediction)

    if accept_type == 'application/x-recordio-protobuf':
        return worker.Response(response=encoders.array_to_recordio_protobuf(
            _sparsify_if_needed(X).astype('float32'),
            y.astype('float32') if y is not None else y),
                               status=http_client.OK,
                               mimetype=accept_type)

    if accept_type == 'text/csv':
        if y is not None:
            X = np.column_stack(
                (np.ravel(y), X.todense() if sparse.issparse(X) else X))

        return worker.Response(response=encoders.encode(X, accept_type),
                               status=http_client.OK,
                               mimetype=accept_type)
    return worker.Response(
        response=f"Accept type '{accept_type}' is not supported.",
        status=http_client.NOT_ACCEPTABLE)
def execution_parameters_fn():

    if _is_feature_transform():
        return worker.Response(response='{"MaxPayloadInMB":1}',
                               status=http_client.OK,
                               mimetype="application/json")
    return worker.Response(response='{"MaxPayloadInMB":6}',
                           status=http_client.OK,
                           mimetype="application/json")
def output_fn(prediction, accept):
    if accept == "application/json":
        instances = []
        for row in prediction.tolist():
            instances.append({"features": row})
        json_output = {"instances": instances}

        return worker.Response(json.dumps(json_output), mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept), mimetype=accept)
    else:
        raise RuntimeException("{} accept type is not supported.".format(accept))
def transformation():
    print("data: ", request.data[:100])
    print("cookies: ", request.cookies)
    print("headers: ", dict(request.headers))
    print("args: ", request.args)

    load_model()

    # We want to get the 'text/csv' bit from something like 'text/csv; charset=utf-8'
    content_type = request.headers['Content-Type'].split(';', 1)[0]
    print("Content type", content_type)
    accept = request.headers['Accept']
    print("Accept", accept)

    input_data = request.data.decode()
    features = []

    if content_type == "application/json":
        decoded_payload = json.loads(input_data)
        entries = [
            entry['predicted_label']
            for entry in decoded_payload['predictions']
        ]
        predictions = np.array(entries)
        features = le.inverse_transform(predictions)
    elif content_type == "text/csv":
        entries = [int(float(label)) for label in input_data.split(',')]
        predictions = np.array(entries)
        features = le.inverse_transform(predictions)
    else:
        raise RuntimeError(
            "{} content type is not supported by this script.".format(
                content_type))

    if accept == "application/json":
        instances = []
        for row in features.tolist():
            category = prepare_category_prediction(row)
            print("Category is: ", category)
            agent = get_agent_by_category(category)
            instances.append({"category": category, "agent": agent})

        json_output = {"response": instances}

        return worker.Response(json.dumps(json_output), mimetype=accept)
    # TODO: use custom flag to indicate that this is in a pipeline rather than relying on the '*/*'
    elif accept == 'text/csv' or accept == '*/*':
        # TODO: this is wrong. fix it
        return worker.Response(encoders.encode(features, accept),
                               mimetype='text/csv')
    else:
        raise RuntimeError(
            "{} accept type is not supported by this script.".format(accept))
Esempio n. 8
0
def output_fn(prediction, accept):
    if accept == 'application/json':
        instances = []
        for row in prediction.tolist():
            instances.append({'features': row})

        json_output = {'instances': instances}
        return worker.Response(json.dumps(json_output), accept=accept, mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept), accept=accept, mimetype=accept)
    else:
        raise RuntimeError(f'{accept} accept type is not supported by this script.')
Esempio n. 9
0
def execution_parameters_fn():
    """Return the response for execution-parameters request used by SageMaker Batch transform.

    The SageMaker Scikit-learn model server invokes when execution-parameters endpoint is called.
    For the models generated by AutoML Jobs, returns the MaxPayloadInMB to be 1MB for feature transform
    used during inference and defaults to 6MB otherwise.
    """
    if _is_feature_transform():
        return worker.Response(response='{"MaxPayloadInMB":1}',
                               status=http_client.OK,
                               mimetype="application/json")
    return worker.Response(response='{"MaxPayloadInMB":6}',
                           status=http_client.OK,
                           mimetype="application/json")
def output_fn(prediction, accept):
    if (accept == 'text/csv; charset=utf-8') | (accept == 'text/csv'):
        return worker.Response(encoders.encode(prediction, accept),
                               mimetype=accept)
    else:
        raise RuntimeError(
            "{} accept type is not supported by json_parser.".format(accept))
def output_fn(prediction, accept):
    """Format prediction output
    """
    if accept == "application/json":
        return worker.Response(json.dumps(prediction), mimetype=accept)
    else:
        raise RuntimeException("{} content_type is not supported by this script.".format(accept))
Esempio n. 12
0
def output_fn(prediction, accept):
    """Format prediction output

    The default accept/content-type between containers for serial inference is JSON.
    We also want to set the ContentType or mimetype as the same value as accept so the next
    container can read the response payload correctly.
    """
    if accept == "application/json":
        return worker.Response(json.dumps(prediction), accept, mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept),
                               accept,
                               mimetype=accept)
    else:
        raise ValueError(
            "{} accept type is not supported by this script.".format(accept))
Esempio n. 13
0
def input_fn(request_body, request_content_type):
    """Decodes request body to 2D numpy array.

    The SageMaker Scikit-learn model server invokes this method to deserialize the request data into an object
    for prediction.

    Parameters
    ----------
    request_body : str
        the request body
    request_content_type : str
        the media type for the request body

    Returns
    -------
    : array-like
        decoded data as 2D numpy array

    """
    content_type = request_content_type.lower(
    ) if request_content_type else "text/csv"
    content_type = content_type.split(";")[0].strip()

    if content_type == 'text/csv':
        if isinstance(request_body, str):
            byte_buffer = request_body.encode()
        else:
            byte_buffer = request_body
        val = read_csv_data(source=byte_buffer)
        logging.info(f"Shape of the requested data: '{val.shape}'")
        return val

    return worker.Response(
        response=f"'{request_content_type}' is an unsupported content type.",
        status=http_client.UNSUPPORTED_MEDIA_TYPE)
Esempio n. 14
0
def predict_fn(input_object, model):
    """Generates prediction for the input_object based on the model.

    The SageMaker Scikit-learn model server invokes this method with the return value of the input_fn.
    This method invokes the loaded model's transform method, if it's expected to transform the input data
    and invokes the loaded model's inverse_label_transform, if the task is to perform
    inverse label transformation.

    Parameters
    ----------
    input_object : array-like
        the object returned from input_fn

    model : AutoMLTransformer
        the model returned from model_fn

    Returns
    -------
    : ndarray
        transformed input data or inverse transformed label data

    """
    if isinstance(input_object, worker.Response):
        return input_object

    if _is_inverse_label_transform():
        return model.inverse_label_transform(input_object.ravel().astype(
            np.float).astype(np.int))
    try:
        return model.transform(input_object)
    except ValueError as e:
        return worker.Response(response='{}'.format(
            str(e) or 'Unknown error.'),
                               status=http_client.BAD_REQUEST)
Esempio n. 15
0
def output_fn(prediction, accept):
    """Format prediction output
    
    The default accept/content-type between containers for serial inference is JSON.
    We also want to set the ContentType or mimetype as the same value as accept so the next
    container can read the response payload correctly.
    """
    return worker.Response("Not yet supported by script")
Esempio n. 16
0
def output_fn(prediction_output, accept):
    if accept == 'application/x-npy':
        print('output_fn input is', prediction_output, 'in format', accept)
        return _npy_dumps(prediction_output), 'application/x-npy'
    elif accept == 'application/json':
        print('output_fn input is', prediction_output, 'in format', accept)
        return worker.Response(encoders.encode(prediction_output, accept), accept, mimetype=accept)
    else:
        raise ValueError('Accept header must be application/x-npy or application/json, but it is {}'.format(accept))
Esempio n. 17
0
def default_output_fn(prediction, accept):
    """Function responsible to serialize the prediction for the response.
    Args:
        prediction (obj): prediction returned by predict_fn .
        accept (str): accept content-type expected by the client.
    Returns:
        (worker.Response): a Flask response object with the following args:
            * Args:
                response: the serialized data to return
                accept: the content-type that the data was transformed to.
    """
    return worker.Response(encoders.encode(prediction, accept), mimetype=accept)
def output_fn(prediction, accept):

    pred_array_value = np.array(prediction)
    score = pred_array_value[0]

    if accept == "application/json":
        predicted_label = 1 if score > 0.5 else 0
        return_value = {
            'predictions': [{
                'score': score.astype(float),
                'predicted_label': predicted_label
            }]
        }
        return worker.Response(json.dumps(return_value), mimetype=accept)
    elif accept == 'text/csv':
        return_value = 'yes' if score > 0.5 else 'no'
        return worker.Response(encoders.encode(prediction, accept),
                               mimetype=accept)
    else:
        raise RuntimeException(
            "{} accept type is not supported.".format(accept))
def output_fn(prediction, accept):
    """Format prediction output
    
    The default accept/content-type between containers for serial inference is JSON.
    We also want to set the ContentType or mimetype as the same value as accept so the next
    container can read the response payload correctly.
    """
    print("[output_fn] Prediction: ", prediction)
    print("[output_fn] Accept: ", accept)
    return worker.Response(encoders.encode(prediction, accept),
                           accept,
                           mimetype=accept)
def output_fn(prediction, accept):

    pred_array_value = np.array(prediction)
    score = pred_array_value[0]

    if accept == "application/json":
        predicted_label = 1 if score > 0.5 else 0
        return_value = {
            "predictions": [{
                "score": score.astype(float),
                "predicted_label": predicted_label
            }]
        }
        return worker.Response(json.dumps(return_value), mimetype=accept)
    elif accept == "text/csv":
        return_value = "yes" if score > 0.5 else "no"
        return worker.Response(encoders.encode(prediction, accept),
                               mimetype=accept)
    else:
        raise RuntimeException(
            "{} accept type is not supported.".format(accept))
Esempio n. 21
0
def output_fn(prediction, accept):

    print("OUTPUT FUNCTION START")
    print(prediction[:10])
    print(type(prediction))
    nrow = len(prediction)
    print('Prediction list number of rows:')
    print(str(nrow))

    if accept == "application/json":
        return worker.Response(json.dumps(prediction), accept, mimetype=accept)
    elif accept == 'text/csv':
        output = worker.Response(encoders.encode(prediction, accept),
                                 accept,
                                 mimetype=accept)
        print(type(output))
        print(str(output))
        return output
    else:
        raise ValueError(
            "{} accept type is not supported by this script.".format(accept))
Esempio n. 22
0
def output_fn(prediction, accept_type):

    if isinstance(prediction, worker.Response):
        return prediction

    if _is_inverse_label_transform():
        if accept_type == 'text/csv':
            return worker.Response(response=encoders.encode(
                prediction, accept_type),
                                   status=http_client.OK,
                                   mimetype=accept_type)
        else:
            return worker.Response(
                response=f"Accept type '{accept_type}' is not supported "
                f"during inverse label transformation.",
                status=413)

    if isinstance(prediction, tuple):
        X, y = prediction
    else:
        X, y = _split_features_target(prediction)

    if accept_type == 'application/x-recordio-protobuf':
        return worker.Response(response=encoders.array_to_recordio_protobuf(
            _sparsify_if_needed(X).astype('float32'),
            y.astype('float32') if y is not None else y),
                               status=http_client.OK,
                               mimetype=accept_type)

    if accept_type == 'text/csv':
        if y is not None:
            X = np.column_stack(
                (np.ravel(y), X.todense() if sparse.issparse(X) else X))

        return worker.Response(response=encoders.encode(X, accept_type),
                               status=http_client.OK,
                               mimetype=accept_type)
    return worker.Response(
        response=f"Accept type '{accept_type}' is not supported.",
        status=http_client.NOT_ACCEPTABLE)
def output_fn(prediction_output, accept):
    print(prediction_output)
    print(type(prediction_output))
    if accept == 'application/x-npy':
        print('output_fn input is', prediction_output, 'in format', accept)
        buffer = BytesIO()
        np.save(buffer, prediction_output)
        return buffer.getvalue(), 'application/x-npy'
    elif accept == 'application/json':
        print('output_fn input is', prediction_output, 'in format', accept)
        return worker.Response(encoders.encode(prediction_output, accept), accept, mimetype=accept)
    else:
        raise ValueError('Accept header must be application/x-npy or application/json, but it is {}'.format(accept))
def default_output_fn(prediction, accept):
    """A default output_fn for PyTorch. Serializes predictions from predict_fn to JSON, CSV or NPZ format.

    Args:
        prediction: a prediction result from predict_fn
        accept: type which the output data needs to be serialized

    Returns: output data serialized
    """
    if type(prediction) == torch.Tensor:
        prediction = prediction.detach().cpu().numpy()

    return worker.Response(encoders.encode(prediction, accept), accept)
Esempio n. 25
0
def predict_fn(input_object, model):

    if isinstance(input_object, worker.Response):
        return input_object

    if _is_inverse_label_transform():
        return model.inverse_label_transform(input_object.ravel().astype(
            np.float).astype(np.int))
    try:
        return model.transform(input_object)
    except ValueError as e:
        return worker.Response(response='{}'.format(
            str(e) or 'Unknown error.'),
                               status=http_client.BAD_REQUEST)
def output_fn(prediction, accept):
    """
    Required by sagemaker to write the output from predict_fn,
    two choices are supported for this script json and csv.
    """

    if accept == "application/json":
        instances = []
        for row in prediction.values.tolist():
            instances.append({"features": row})

        json_output = {"instances": instances}

        return worker.Response(json.dumps(json_output),
                               accept,
                               mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept),
                               accept,
                               mimetype=accept)
    else:
        raise RuntimeError(
            "{} accept type is not supported by this script.".format(accept))
Esempio n. 27
0
def output_fn(prediction, accept):
    """Formato do output da predição

    O formato de aceitação (accept) do tipo de conteudo (accept/content-type)
    entre os containers é JSON. Nos tambem queremos definir o ContentType
    ou o mimetype como o mesmo valor como o formato de aceitação então
    o próximo container pode ler a resposta do payload corretamente.
    """
    if accept == "application/json":
        instances = []
        for row in prediction.tolist():
            instances.append({"features": row})

        json_output = {"instances": instances}
        json_output = pd.Series(json_output).to_json(orient='values')

        return worker.Response(json.dumps(json_output), mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept),
                               mimetype=accept)
    else:
        return worker.Response(encoders.encode(prediction, accept),
                               mimetype=accept)
def output_fn(inferences, accept):
    """Format inferences output
    The default accept/content-type b/w containers for inference is JSON.
    We also want the ContentType/mimetype the same value as accept so the
    next container can read the response payload correctly.
    """
    if accept == "application/json":
        instances = []
        for inference in inferences.tolist():
            if len(inference) == 4:
                target, pred_prob, prediction, expl = inference
                instances.append({
                    "pred_prob": pred_prob,
                    "prediction": prediction,
                    "target": target,
                    "expl": expl
                })
            elif len(inference) == 3:
                pred_prob, prediction, expl = inference
                instances.append({
                    "pred_prob": pred_prob,
                    "prediction": prediction,
                    "expl": expl
                })
            else:
                pred_prob, prediction = inference
                instances.append({
                    "pred_prob": pred_prob,
                    "prediction": prediction
                })
        json_output = {"instances": instances}
        return worker.Response(json.dumps(json_output), mimetype=accept)
    elif accept == 'text/csv':
        return worker.Response(encoders.encode(prediction, accept),
                               mimetype=accept)
    else:
        raise RuntimeError(f"{accept} is not supported by this script.")
    def default_output_fn(self, prediction, accept):
        """Serialize the prediction into a response.

        Args:
            prediction (mxnet.nd.array): an MXNet NDArray that is the result of a prediction
            accept (str): the accept content type expected by the client

        Returns:
            sagemaker_containers.beta.framework.worker.Response: a Flask response object

        Raises:
            sagemaker_containers.beta.framework.errors.UnsupportedFormatError: if an unsupported
                accept type is used.
        """
        if accept in self.VALID_CONTENT_TYPES:
            return worker.Response(encoders.encode(prediction.asnumpy().tolist(), accept), accept)
        else:
            raise errors.UnsupportedFormatError(accept)
Esempio n. 30
0
def input_fn(request_body, request_content_type):

    content_type = request_content_type.lower(
    ) if request_content_type else "text/csv"
    content_type = content_type.split(";")[0].strip()

    if content_type == 'text/csv':
        if isinstance(request_body, str):
            byte_buffer = request_body.encode()
        else:
            byte_buffer = request_body
        val = read_csv_data(source=byte_buffer)
        logging.info(f"Shape of the requested data: '{val.shape}'")
        return val

    return worker.Response(
        response=f"'{request_content_type}' is an unsupported content type.",
        status=http_client.UNSUPPORTED_MEDIA_TYPE)