diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f8a2ad1..135592e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,9 +66,8 @@ jobs: run: | pipenv install --dev cd src - # pipenv run coverage run -m unittest tests.inference_tests - # pipenv run coverage report - pipenv run python -m unittest tests.inference_tests + pipenv run coverage run -m unittest tests.inference_tests + pipenv run coverage report build_python_packages: runs-on: ubuntu-latest needs: packages_unit_tests diff --git a/packages/inference/src/mlopspython_inference/inference_pillow.py b/packages/inference/src/mlopspython_inference/inference_pillow.py index 63e5a9d3..7102a606 100644 --- a/packages/inference/src/mlopspython_inference/inference_pillow.py +++ b/packages/inference/src/mlopspython_inference/inference_pillow.py @@ -7,7 +7,7 @@ # load and prepare the image -def load_image(filename: str|BytesIO): +def load_image(filename: str | BytesIO): # load the image img = load_img(filename, target_size=(224, 224)) # convert to array @@ -23,12 +23,25 @@ def load_image(filename: str|BytesIO): BASE_PATH = Path(__file__).resolve().parent +class IModelLoader: + def load(self): + raise NotImplementedError() + + +class ModelLoader(IModelLoader): + def __init__(self, model_path: str): + self.model_path = model_path + + def load(self): + return load_model(self.model_path) + + class Inference: - def __init__(self, logging, model_path: str): + def __init__(self, logging, model_loader: IModelLoader): self.logger = logging.getLogger(__name__) - self.model = load_model(model_path) + self.model = model_loader.load() - def execute(self, filepath:str|BytesIO): + def execute(self, filepath: str | BytesIO): img = load_image(filepath) result = self.model.predict(img) values = [float(result[0][0]), float(result[0][1]), float(result[0][2])] diff --git a/packages/inference/src/tests/inference_tests.py b/packages/inference/src/tests/inference_tests.py index 96d3122a..f68ef427 100644 --- a/packages/inference/src/tests/inference_tests.py +++ b/packages/inference/src/tests/inference_tests.py @@ -1,8 +1,9 @@ import unittest +from dataclasses import dataclass from pathlib import Path import logging - -from mlopspython_inference.inference_pillow import Inference +from unittest.mock import MagicMock +from mlopspython_inference.inference_pillow import Inference, IModelLoader BASE_PATH = Path(__file__).resolve().parent output_directory = BASE_PATH / "output" @@ -11,7 +12,14 @@ class TestInference(unittest.TestCase): def test_inference(self): - inference = Inference(logging, str(input_directory / "model" / "final_model.h5")) + def predict(img): + return [[1.0, 2.370240289845506e-30, 0.0]] + model_mock = MagicMock() + model_mock.predict = predict + + model_loader_mock = MagicMock(IModelLoader) + model_loader_mock.load = MagicMock(return_value=model_mock) + inference = Inference(logging, model_loader_mock) inference_result = inference.execute(str(input_directory / "images" / "cat.png")) expected_result = {'prediction': 'Cat', 'values': [1.0, 2.370240289845506e-30, 0.0]} diff --git a/packages/inference/src/tests/input/model/final_model.h5 b/packages/inference/src/tests/input/model/final_model.h5 deleted file mode 100644 index 60daa135..00000000 Binary files a/packages/inference/src/tests/input/model/final_model.h5 and /dev/null differ diff --git a/production/api/core/model/inference_pillow.py b/production/api/core/model/inference_pillow.py index b4f9c4db..83ff6577 100644 --- a/production/api/core/model/inference_pillow.py +++ b/production/api/core/model/inference_pillow.py @@ -1,6 +1,6 @@ import io from pathlib import Path -from mlopspython_inference.inference_pillow import Inference as InferencePillow +from mlopspython_inference.inference_pillow import Inference as InferencePillow, ModelLoader BASE_PATH = Path(__file__).resolve().parent @@ -8,7 +8,7 @@ class Inference: def __init__(self, logging, app_settings): self.logger = logging.getLogger(__name__) model_path = (str(BASE_PATH / 'final_model.h5')) - self.inference = InferencePillow(logging, str(model_path)) + self.inference = InferencePillow(logging, ModelLoader(str(model_path))) def execute(self, file, filename, settings=None): return self.inference.execute(io.BytesIO(file.read())) diff --git a/production/api/tests/test_process.py b/production/api/tests/test_process.py index 32b3633d..8b5c8e24 100644 --- a/production/api/tests/test_process.py +++ b/production/api/tests/test_process.py @@ -11,7 +11,7 @@ class TestProcess(unittest.IsolatedAsyncioTestCase): def test_process(self): model = Inference(logging, BaseAppSettings(logging)) dir = "./tests/cats-dogs-others/f2b68110-3b7b-4cc1-98fc-caf451d71ff2/mlcli" - dest = "./tests/diff" + dest = "./tests/diff2" flist = [p for p in Path(dir).iterdir() if p.is_file()] for fp in flist: with open(fp, "rb") as pdf_stream: diff --git a/train/evaluate/evaluate.py b/train/evaluate/evaluate.py index 57b253d6..d1f1ceaa 100644 --- a/train/evaluate/evaluate.py +++ b/train/evaluate/evaluate.py @@ -1,13 +1,13 @@ import json from pathlib import Path -from mlopspython_inference.inference_pillow import Inference +from mlopspython_inference.inference_pillow import Inference, ModelLoader def evaluate(logging, input_model_directory: Path, input_images_directory: Path, output_directory: Path, integration_output: Path): model_path = input_model_directory / "final_model.h5" - model = Inference(logging, str(model_path)) + model = Inference(logging, ModelLoader(str(model_path))) statistics = { "ok": 0,