text: # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  #
  # Licensed under the Apache License, Version 2.0 (the 'License'). You
  # may not use this file except in compliance with the License. A copy of
  # the License is located at
  #
  #     http://aws.amazon.com/apache2.0/
  #
  # or in the 'license' file accompanying this file. This file is
  # distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  # ANY KIND, either express or implied. See the License for the specific
  # language governing permissions and limitations under the License.
  """Placeholder docstring"""
  from __future__ import absolute_import
  
  import warnings
  
  import flask
  from six.moves import http_client
  
  from sagemaker_containers import _content_types, _env, _logging, _mapping
  
  env = _env.ServingEnv()
  
  
  def default_healthcheck_fn():  # type: () -> Response
      """Ping is default health-check handler. Returns 200 with no content.
  
      During a new serving container startup, Amazon SageMaker starts sending periodic GET requests
      to the /ping endpoint to ensure that the container is ready for predictions.
  
      The simplest requirement on the container is to respond with an HTTP 200 status code and an
      empty body. This indicates to Amazon SageMaker that the container is ready to accept inference
      requests at the /invocations endpoint.
  
      If the container does not begin to consistently respond with 200s during the first 30 seconds
      after startup, the CreateEndPoint and UpdateEndpoint APIs will fail.
  
      While the minimum bar is for the container to return a static 200, a container developer can use
      this functionality to perform deeper checks. The request timeout on /ping attempts is 2 seconds.
  
      More information on how health-check works can be found here:
      https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-inference-code.html#your-algorithms-inference-algo-ping-requests
  
      Returns:
          (flask.Response): with status code 200
      """
      return Response(status=http_client.OK)
  
  
  class Worker(flask.Flask):
      """Flask application that receives predictions from a Transformer ready for inferences."""
  
      def __init__(
          self,
          transform_fn,
          initialize_fn=None,
          module_name=None,
          healthcheck_fn=None,
          execution_parameters_fn=None,
      ):
          """Creates and Flask application from a transformer.
  
          Args:
              transform_fn (function): responsible to make predictions against the model.
                                       Follows the signature:
  
                  * Returns:
                      `sagemaker_containers.transformers.TransformSpec`: named tuple with prediction
                                                                         data.
  
  
              initialize_fn (function, optional): this function is called when the Flask application
                                                  starts. It doest not have return type or arguments.
  
              healthcheck_fn (function, optional): function that will be used for healthcheck calls
                                                   when the containers starts, if not specified, it
                                                   will use ping as the default healthcheck call.
                                                   Signature:
  
              execution_parameters_fn (function, optional): function that will be used for responding
                                                            to execution_parameters calls. If not
                                                            specified, execution-parameters endpoint
                                                            will not be supported.
                  * Returns:
                      `flask.app.Response`: response object with new healthcheck response.
  
              module_name (str): the module name which implements the worker. If not specified, it
                                 will use sagemaker_containers.ServingEnv().module_name as the default
                                 module name.
          """
          super(Worker, self).__init__(module_name or env.module_name)
  
          # the logger is configured after importing the framework library, allowing the framework to
          # configure logging at import time.
          _logging.configure_logger(env.log_level)
  
          if initialize_fn:
              self.before_first_request(initialize_fn)
  
          self.add_url_rule(
              rule="/invocations", endpoint="invocations", view_func=transform_fn, methods=["POST"]
          )
          self.add_url_rule(
              rule="/ping", endpoint="ping", view_func=healthcheck_fn or default_healthcheck_fn
          )
          if execution_parameters_fn:
              self.add_url_rule(
                  rule="/execution-parameters",
                  endpoint="execution-parameters",
                  view_func=execution_parameters_fn,
                  methods=["GET", "POST"],
              )
  
          self.request_class = Request
  
  
  class Response(flask.Response):
      """Placeholder docstring"""
  
      default_mimetype = _content_types.JSON
  
      def __init__(
          self,
          response=None,
          accept=None,
          status=http_client.OK,
          headers=None,
          mimetype=None,
          direct_passthrough=False,
      ):
          """Placeholder docstring"""
          if accept:
              warnings.warn(
                  'ignoring deprecated "accept" argument to Response.__init__', DeprecationWarning
              )
          super(Response, self).__init__(
              response, status, headers, mimetype, None, direct_passthrough
          )
  
  
  class Request(flask.Request, _mapping.MappingMixin):
      """The Request object used to read request data.
  
      Example:
  
      POST /invocations
      Content-Type: 'application/json'.
      Accept: 'application/json'.
  
      42
  
      >>> from sagemaker_containers import _env
  
      >>> request = Request()
      >>> data = request.data
  
      >>> print(str(request))
  
      {'content_length': '2', 'content_type': 'application/json', 'data': '42',
       'accept': 'application/json', ... }
  
  
      """
  
      default_mimetype = _content_types.JSON
  
      def __init__(self, environ=None, serving_env=None):  # type: (dict, _env.ServingEnv) -> None
          """Placeholder docstring"""
          super(Request, self).__init__(environ=environ or flask.request.environ)
  
          serving_env = serving_env or env
  
          self._default_accept = serving_env.default_accept
  
      @property
      def content_type(self):  # type: () -> str
          """The request's content-type.
  
          Returns:
              (str): The value, if any, of the header 'ContentType' (used by some AWS services) and
                     'Content-Type'. Otherwise, returns 'application/json' as default.
          """
          return (
              self.headers.get("ContentType")
              or self.headers.get("Content-Type")
              or _content_types.JSON
          )
  
      @property
      def accept(self):  # type: () -> str
          """The content-type for the response to the client.
  
          Returns:
              (str): The value of the header 'Accept' or the user-supplied
                     SAGEMAKER_DEFAULT_INVOCATIONS_ACCEPT environment variable.
          """
          accept = self.headers.get("Accept")
  
          if not accept or accept == _content_types.ANY:
              return self._default_accept
          else:
              return accept
  
      @property
      def content(self):  # type: () -> object
          """The request incoming data.
  
          It automatic decodes from utf-8
  
          Returns:
              (obj): incoming data
          """
          as_text = self.content_type in _content_types.UTF8_TYPES
  
          return self.get_data(as_text=as_text)
  