prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Expected XGBoost model file "model.bst" extension is undocumented? 
  On https://github.com/SeldonIO/MLServer/blob/master/runtimes/xgboost/mlserver_xgboost/xgboost.py#L21 you can see that MLServer is looking for an XGBoost model file called "model.bst". However, I cannot find any reference to that file extension in the XGBoost documentation. As far as I can see, XGBoost's documented file extensions are:
  
  - ".json" added in 1.0.0, an "open format that can be easily reused"
  - ".ubj" for Universal Binary JSON format, available in 1.6.0
  - ".model" for the "old binary internal format" prior to 1.0.0, as shown in examples
  
  Where does MLServer get the ".bst" extension from, and what model format does it use? Shouldn't it use one of the extensions mentioned in the XGBoost documentation instead, to avoid ambiguity?
  
  </issue>
  <code>
  [start of runtimes/xgboost/mlserver_xgboost/xgboost.py]
  1 import xgboost as xgb
  2 
  3 from typing import List
  4 from xgboost.sklearn import XGBModel
  5 
  6 from mlserver.errors import InferenceError
  7 from mlserver.model import MLModel
  8 from mlserver.utils import get_model_uri
  9 from mlserver.codecs import NumpyRequestCodec, NumpyCodec
  10 from mlserver.types import (
  11     InferenceRequest,
  12     InferenceResponse,
  13     RequestOutput,
  14     ResponseOutput,
  15 )
  16 
  17 PREDICT_OUTPUT = "predict"
  18 PREDICT_PROBA_OUTPUT = "predict_proba"
  19 VALID_OUTPUTS = [PREDICT_OUTPUT, PREDICT_PROBA_OUTPUT]
  20 
  21 WELLKNOWN_MODEL_FILENAMES = ["model.bst", "model.json"]
  22 
  23 
  24 def _load_sklearn_interface(model_uri: str) -> XGBModel:
  25     try:
  26         regressor = xgb.XGBRegressor()
  27         regressor.load_model(model_uri)
  28         return regressor
  29     except TypeError:
  30         # If there was an error, it's likely due to the model being a
  31         # classifier
  32         classifier = xgb.XGBClassifier()
  33         classifier.load_model(model_uri)
  34         return classifier
  35 
  36 
  37 class XGBoostModel(MLModel):
  38     """
  39     Implementationof the MLModel interface to load and serve `xgboost` models.
  40     """
  41 
  42     async def load(self) -> bool:
  43         model_uri = await get_model_uri(
  44             self._settings, wellknown_filenames=WELLKNOWN_MODEL_FILENAMES
  45         )
  46 
  47         self._model = _load_sklearn_interface(model_uri)
  48 
  49         return True
  50 
  51     def _check_request(self, payload: InferenceRequest) -> InferenceRequest:
  52         if not payload.outputs:
  53             # By default, only return the result of `predict()`
  54             payload.outputs = [RequestOutput(name=PREDICT_OUTPUT)]
  55         else:
  56             for request_output in payload.outputs:
  57                 if request_output.name not in VALID_OUTPUTS:
  58                     raise InferenceError(
  59                         f"XGBoostModel only supports '{PREDICT_OUTPUT}' and "
  60                         f"'{PREDICT_PROBA_OUTPUT}' as outputs "
  61                         f"({request_output.name} was received)"
  62                     )
  63 
  64         # Regression models do not support `predict_proba`
  65         if PREDICT_PROBA_OUTPUT in [o.name for o in payload.outputs]:
  66             if isinstance(self._model, xgb.XGBRegressor):
  67                 raise InferenceError(
  68                     f"XGBRegressor models do not support '{PREDICT_PROBA_OUTPUT}"
  69                 )
  70 
  71         return payload
  72 
  73     def _get_model_outputs(self, payload: InferenceRequest) -> List[ResponseOutput]:
  74         decoded_request = self.decode_request(payload, default_codec=NumpyRequestCodec)
  75 
  76         outputs = []
  77         for request_output in payload.outputs:  # type: ignore
  78             predict_fn = getattr(self._model, request_output.name)
  79             y = predict_fn(decoded_request)
  80 
  81             output = self.encode(y, request_output, default_codec=NumpyCodec)
  82             outputs.append(output)
  83 
  84         return outputs
  85 
  86     async def predict(self, payload: InferenceRequest) -> InferenceResponse:
  87         payload = self._check_request(payload)
  88         outputs = self._get_model_outputs(payload)
  89 
  90         return InferenceResponse(
  91             model_name=self.name,
  92             model_version=self.version,
  93             outputs=outputs,
  94         )
  95
  [end of runtimes/xgboost/mlserver_xgboost/xgboost.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/runtimes/xgboost/mlserver_xgboost/xgboost.py b/runtimes/xgboost/mlserver_xgboost/xgboost.py
  --- a/runtimes/xgboost/mlserver_xgboost/xgboost.py
  +++ b/runtimes/xgboost/mlserver_xgboost/xgboost.py
  @@ -18,7 +18,7 @@
   PREDICT_PROBA_OUTPUT = "predict_proba"
   VALID_OUTPUTS = [PREDICT_OUTPUT, PREDICT_PROBA_OUTPUT]
   
  -WELLKNOWN_MODEL_FILENAMES = ["model.bst", "model.json"]
  +WELLKNOWN_MODEL_FILENAMES = ["model.bst", "model.json", "model.ubj"]
   
   
   def _load_sklearn_interface(model_uri: str) -> XGBModel:
  
verification_info: {"golden_diff": "diff --git a/runtimes/xgboost/mlserver_xgboost/xgboost.py b/runtimes/xgboost/mlserver_xgboost/xgboost.py\n--- a/runtimes/xgboost/mlserver_xgboost/xgboost.py\n+++ b/runtimes/xgboost/mlserver_xgboost/xgboost.py\n@@ -18,7 +18,7 @@\n PREDICT_PROBA_OUTPUT = \"predict_proba\"\n VALID_OUTPUTS = [PREDICT_OUTPUT, PREDICT_PROBA_OUTPUT]\n \n-WELLKNOWN_MODEL_FILENAMES = [\"model.bst\", \"model.json\"]\n+WELLKNOWN_MODEL_FILENAMES = [\"model.bst\", \"model.json\", \"model.ubj\"]\n \n \n def _load_sklearn_interface(model_uri: str) -> XGBModel:\n", "issue": "Expected XGBoost model file \"model.bst\" extension is undocumented? \nOn https://github.com/SeldonIO/MLServer/blob/master/runtimes/xgboost/mlserver_xgboost/xgboost.py#L21 you can see that MLServer is looking for an XGBoost model file called \"model.bst\". However, I cannot find any reference to that file extension in the XGBoost documentation. As far as I can see, XGBoost's documented file extensions are:\r\n\r\n- \".json\" added in 1.0.0, an \"open format that can be easily reused\"\r\n- \".ubj\" for Universal Binary JSON format, available in 1.6.0\r\n- \".model\" for the \"old binary internal format\" prior to 1.0.0, as shown in examples\r\n\r\nWhere does MLServer get the \".bst\" extension from, and what model format does it use? Shouldn't it use one of the extensions mentioned in the XGBoost documentation instead, to avoid ambiguity?\n", "before_files": [{"content": "import xgboost as xgb\n\nfrom typing import List\nfrom xgboost.sklearn import XGBModel\n\nfrom mlserver.errors import InferenceError\nfrom mlserver.model import MLModel\nfrom mlserver.utils import get_model_uri\nfrom mlserver.codecs import NumpyRequestCodec, NumpyCodec\nfrom mlserver.types import (\n    InferenceRequest,\n    InferenceResponse,\n    RequestOutput,\n    ResponseOutput,\n)\n\nPREDICT_OUTPUT = \"predict\"\nPREDICT_PROBA_OUTPUT = \"predict_proba\"\nVALID_OUTPUTS = [PREDICT_OUTPUT, PREDICT_PROBA_OUTPUT]\n\nWELLKNOWN_MODEL_FILENAMES = [\"model.bst\", \"model.json\"]\n\n\ndef _load_sklearn_interface(model_uri: str) -> XGBModel:\n    try:\n        regressor = xgb.XGBRegressor()\n        regressor.load_model(model_uri)\n        return regressor\n    except TypeError:\n        # If there was an error, it's likely due to the model being a\n        # classifier\n        classifier = xgb.XGBClassifier()\n        classifier.load_model(model_uri)\n        return classifier\n\n\nclass XGBoostModel(MLModel):\n    \"\"\"\n    Implementationof the MLModel interface to load and serve `xgboost` models.\n    \"\"\"\n\n    async def load(self) -> bool:\n        model_uri = await get_model_uri(\n            self._settings, wellknown_filenames=WELLKNOWN_MODEL_FILENAMES\n        )\n\n        self._model = _load_sklearn_interface(model_uri)\n\n        return True\n\n    def _check_request(self, payload: InferenceRequest) -> InferenceRequest:\n        if not payload.outputs:\n            # By default, only return the result of `predict()`\n            payload.outputs = [RequestOutput(name=PREDICT_OUTPUT)]\n        else:\n            for request_output in payload.outputs:\n                if request_output.name not in VALID_OUTPUTS:\n                    raise InferenceError(\n                        f\"XGBoostModel only supports '{PREDICT_OUTPUT}' and \"\n                        f\"'{PREDICT_PROBA_OUTPUT}' as outputs \"\n                        f\"({request_output.name} was received)\"\n                    )\n\n        # Regression models do not support `predict_proba`\n        if PREDICT_PROBA_OUTPUT in [o.name for o in payload.outputs]:\n            if isinstance(self._model, xgb.XGBRegressor):\n                raise InferenceError(\n                    f\"XGBRegressor models do not support '{PREDICT_PROBA_OUTPUT}\"\n                )\n\n        return payload\n\n    def _get_model_outputs(self, payload: InferenceRequest) -> List[ResponseOutput]:\n        decoded_request = self.decode_request(payload, default_codec=NumpyRequestCodec)\n\n        outputs = []\n        for request_output in payload.outputs:  # type: ignore\n            predict_fn = getattr(self._model, request_output.name)\n            y = predict_fn(decoded_request)\n\n            output = self.encode(y, request_output, default_codec=NumpyCodec)\n            outputs.append(output)\n\n        return outputs\n\n    async def predict(self, payload: InferenceRequest) -> InferenceResponse:\n        payload = self._check_request(payload)\n        outputs = self._get_model_outputs(payload)\n\n        return InferenceResponse(\n            model_name=self.name,\n            model_version=self.version,\n            outputs=outputs,\n        )\n", "path": "runtimes/xgboost/mlserver_xgboost/xgboost.py"}]}