Ejemplo n.º 1
0
 async def request_dispatcher(self, request):
     with async_trace(
             ZIPKIN_API_URL,
             service_name=self.__class__.__name__,
             span_name="[1]http request",
             is_root=True,
             standalone=True,
             sample_rate=0.001,
     ):
         api_name = request.match_info.get("name")
         if api_name in self.batch_handlers:
             req = SimpleRequest(request.raw_headers, await request.read())
             try:
                 resp = await self.batch_handlers[api_name](req)
             except RemoteException as e:
                 # known remote exception
                 logger.error(traceback.format_exc())
                 resp = aiohttp.web.Response(
                     status=e.payload.status,
                     headers=e.payload.headers,
                     body=e.payload.data,
                 )
             except Exception:  # pylint: disable=broad-except
                 logger.error(traceback.format_exc())
                 resp = aiohttp.web.InternalServerError()
         else:
             resp = await self.relay_handler(request)
     return resp
Ejemplo n.º 2
0
 def handle_request(self, request: flask.Request, func):
     if request.content_type != "application/json":
         raise BadInput(
             "Request content-type must be 'application/json' for this "
             "BentoService API")
     resps = self.handle_batch_request(
         [SimpleRequest.from_flask_request(request)], func)
     return resps[0].to_flask_response()
Ejemplo n.º 3
0
    def to_response(self, result, request: flask.Request) -> flask.Response:
        """Converts corresponding data into an HTTP response

        :param result: result of user API function
        :param request: request object
        """
        simple_req = SimpleRequest.from_flask_request(request)
        simple_resp = self.to_batch_response((result, ),
                                             requests=(simple_req, ))[0]
        return simple_resp.to_flask_response()
Ejemplo n.º 4
0
    def handle_request(self, request, func):
        """Handle http request that has jsonlized tensorflow tensor. It will convert it
        into a tf tensor for the function to consume.

        Args:
            request: incoming request object.
            func: function that will take ndarray as its arg.
        Return:
            response object
        """
        req = SimpleRequest.from_flask_request(request)
        res = self.handle_batch_request([req], func)[0]
        return res.to_flask_response()
Ejemplo n.º 5
0
def test_anno_image_input_batch_request_skip_bad(img_file, json_file):
    adapter = AnnotatedImageInput(is_batch_input=True)

    multipart_data, headers = generate_multipart_body(img_file, json_file)

    empty_request = SimpleRequest(headers=headers, data=None)

    request = SimpleRequest.from_flask_request(
        Request.from_values(
            data=multipart_data,
            content_type=headers['Content-Type'],
            content_length=headers['Content-Length'],
        ))

    image = ("image.jpg", open(img_file, "rb").read())
    json = ("annotations.jso", open(json_file, "rb").read())
    files = {"image.invalid": image, "annotations.invalid": json}
    bad_data, content_type = encode_multipart_formdata(files)

    bad_request = SimpleRequest.from_flask_request(
        Request.from_values(
            data=bad_data,
            content_type=content_type,
            content_length=len(bad_data),
        ))

    responses = adapter.handle_batch_request(
        [empty_request, request, bad_request], predict_image_and_json)

    assert len(responses) == 3
    assert responses[0] is None
    assert responses[1].status == 200 and responses[
        1].data == '[[10, 10, 3], "kaith"]'
    assert responses[2] is None

    bad_responses = adapter.handle_batch_request([empty_request],
                                                 predict_image_and_json)
    assert len(bad_responses) == 1
    assert bad_responses[0] is None
def test_bad_multi_image_batch_input(img_file):
    adapter = MultiImageInput(("imageX", "imageY"), is_batch_input=True)

    multipart_data, headers = generate_multipart_body(img_file)
    request = SimpleRequest.from_flask_request(
        Request.from_values(
            data=multipart_data,
            content_type=headers['Content-Type'],
            content_length=headers['Content-Length'],
        ))

    responses = adapter.handle_batch_request(
        [request] * 5 + [
            SimpleRequest.from_flask_request(
                Request.from_values(
                    data=multipart_data,
                    content_type='application/octet-stream',
                    content_length=headers['Content-Length'],
                ))
        ],
        predict,
    )
    print(responses[-1])
    assert isinstance(responses[-1], SimpleRequest)
def test_multi_image_batch_input(img_file):
    adapter = MultiImageInput(("imageX", "imageY"), is_batch_input=True)

    multipart_data, headers = generate_multipart_body(img_file)
    request = SimpleRequest.from_flask_request(
        Request.from_values(
            data=multipart_data,
            content_type=headers['Content-Type'],
            content_length=headers['Content-Length'],
        ))

    responses = adapter.handle_batch_request([request] * 5, predict)
    for response in responses:
        assert response.status == 200
        assert response.data == '[[10, 10, 3], [10, 10, 3]]'
Ejemplo n.º 8
0
    def to_response(self, result, request: flask.Request) -> flask.Response:
        """Converts corresponding data into an HTTP response

        :param result: result of user API function
        :param request: request object
        """
        simple_req = SimpleRequest(headers=request.headers,
                                   data=request.get_data())
        simple_resp = self.to_batch_response((result, ),
                                             requests=(simple_req, ))[0]
        return flask.Response(
            response=simple_resp.data,
            status=simple_resp.status,
            headers=simple_resp.headers,
        )
Ejemplo n.º 9
0
 async def request_dispatcher(self, request):
     with async_trace(
             ZIPKIN_API_URL,
             service_name=self.__class__.__name__,
             span_name=f"[1]http request",
             is_root=True,
             standalone=True,
             sample_rate=0.001,
     ):
         api_name = request.match_info.get("name")
         if api_name in self.batch_handlers:
             req = SimpleRequest(request.raw_headers, await request.read())
             resp = await self.batch_handlers[api_name](req)
         else:
             resp = await self.relay_handler(request)
     return resp
Ejemplo n.º 10
0
def test_anno_image_input_batch_request(img_file, json_file):
    adapter = AnnotatedImageInput(is_batch_input=True)

    multipart_data, headers = generate_multipart_body(img_file, json_file)
    request = SimpleRequest.from_flask_request(
        Request.from_values(
            data=multipart_data,
            content_type=headers['Content-Type'],
            content_length=headers['Content-Length'],
        ))

    responses = adapter.handle_batch_request([request] * 5,
                                             predict_image_and_json)
    for response in responses:
        assert response.status == 200
        assert response.data == '[[10, 10, 3], "kaith"]'
Ejemplo n.º 11
0
def test_file_input_http_request_post_binary(bin_file):
    test_file_input = FileInput()
    request = mock.MagicMock(spec=flask.Request)
    request.method = "POST"
    request.files = {}
    request.headers = {}
    request.get_data.return_value = open(str(bin_file), 'rb').read()

    response = test_file_input.handle_request(request, predict)

    assert response.status_code == 200
    assert b'{"b64": "gTCJOQ=="}' in response.data

    simple_request = SimpleRequest.from_flask_request(request)
    responses = test_file_input.handle_batch_request([simple_request], predict)

    assert responses[0].status == 200
    assert '{"b64": "gTCJOQ=="}' == responses[0].data
Ejemplo n.º 12
0
def test_image_input_http_request_post_binary(img_file):
    test_image_input = ImageInput()
    request = mock.MagicMock(spec=flask.Request)
    request.method = "POST"
    request.files = {}
    request.headers = {}
    request.get_data.return_value = open(str(img_file), 'rb').read()

    response = test_image_input.handle_request(request, predict)

    assert response.status_code == 200
    assert "[10, 10, 3]" in str(response.response)

    simple_request = SimpleRequest.from_flask_request(request)
    responses = test_image_input.handle_batch_request([simple_request],
                                                      predict)

    assert responses[0].status == 200
    assert "[10, 10, 3]" in str(responses[0].data)
Ejemplo n.º 13
0
def test_tf_tensor_handle_batch_request(test_cases):
    '''
    ref: https://www.tensorflow.org/tfx/serving/api_rest#request_format_2
    '''
    from bentoml.adapters import TfTensorInput
    from bentoml.marshal.utils import SimpleRequest

    input_adapter = TfTensorInput()
    request = MagicMock(spec=flask.Request)

    input_data, headers, except_result = test_cases
    request.get_data.return_value = json.dumps(input_data).encode('utf-8')
    request.headers = headers
    responses = input_adapter.handle_batch_request(
        [SimpleRequest.from_flask_request(request)] * 3, lambda i: i)

    for response in responses:
        prediction = json.loads(response.data)
        assert_eq_or_both_nan(except_result, prediction)