Skip to content
51 changes: 26 additions & 25 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# Changelog

## v0.15.3

- [001baa4](/001baa419309edc6c84a4dae1dfa2e99bb3c75b5) - doc(evaluation): add evaluation.md, 2025-10-12 by *Guillaume Chervet*


## v0.15.2

- [1f4ebf7](/1f4ebf7243d71e42666297bc032251776dd9f911) - doc(evaluation): add evaluation.md, 2025-10-12 by *Guillaume Chervet*


## v0.15.1

- [b7edb55](/b7edb551645e123b271e11f667439a7ad3edbfe3) - doc(evaluation): add evaluation.md, 2025-10-12 by *Guillaume Chervet*


## v0.15.0

- [33b1b92](/33b1b929acd5a50d6ef9f7f4c377de34cdd8c234) - Merge branch 'main' of https://www.github.com/guillaume-chervet/MLOpsPython, 2025-09-21 by *Guillaume Chervet*
- [21f73c4](/21f73c48109465fe269583828b3f12e432ca4a6b) - feat(workshop): add library workshop, 2025-09-21 by *Guillaume Chervet*


## v0.14.11

- [ecfae26](/ecfae26c4f796ee80fbb3f6dfdf7809682667f6a) - fix(workshop): update to make it works in 2025, 2025-09-20 by *Guillaume Chervet*


## v0.14.10

- [a0310e2](/a0310e2f8248704ee42c0b776c3dcf16a9b5db7a) - refactore(all): switch to pyttest (#46), 2025-09-08 by *Guillaume Chervet*
Expand Down Expand Up @@ -268,28 +294,3 @@
- [315e72c](/315e72ca2469df17729820fcd6e1f2ef23091268) - feat(workshop): create microsoft workshop, 2023-11-24 by *Guillaume Chervet*


## v0.3.3

- [6de6e5e](/6de6e5e90c8df00578d5883cea64480d38422290) - fix: Using pip instead of poetry to init the project was causing errors (#22), 2023-10-31 by *antoinelrnld*


## v0.3.2

- [14037bc](/14037bc8cd6b65eb5dca74e00da729272ae43e2e) - fix(train): azure cluster name (#21), 2023-10-21 by *Guillaume Chervet*


## v0.3.1

- [fb2f4e2](/fb2f4e24ee6ab0c920c94b70d88d4392e7ee9063) - docs(workshop): Update workshop_cloud_nord.md, 2023-10-12 by *Guillaume Chervet*


## v0.3.0

- [e4c1a89](/e4c1a8948c9772d64526e4f954b3712d130a99fb) - feat(workshop): create cloud nord workshop (#18), 2023-10-11 by *Guillaume Chervet*


## v0.2.1

- [3997017](/3997017790f048e512b0b012f347138ed6110147) - fix: api requirements.txt doesn't work on MacOs (#19), 2023-10-11 by *Ca.phe*


56 changes: 56 additions & 0 deletions evaluation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Evaluation Notes

- **Project:** 12 points
- **In-class follow-up:** 8 points
- UV Library Publication → link to PyPI library → 3 points
- Dependency Injection for Inference → link to personal GitHub → 3 points
- MLOps Lab Work → link to personal GitHub → 2 points
---

## Startup Project with High Added Value (topic of your choice)

The project must:

- Be hosted on a **public open-source Git repository**
- Include **Pull Requests** with **review/validation** between team members
- Contain **Unit Tests**, ideally following a **TDD** (Test-Driven Development) approach
- Include a **public Kanban board**
- Contain a **preprocessing phase**, such as:
- In the MLOps lab, the preprocessing step is the **extraction of images from a PDF**
- It can also be another turnkey AI component (e.g., text detection, OCR, etc.)
- Include a **mandatory AI training phase**:
- The AI can be trained **from scratch** (requires a large dataset)
- Or **fine-tuned** from an existing model (e.g., from **Hugging Face**)
- Use **more than 100 data samples** (images, audio, videos, etc.) **created by you** (not downloaded from the internet) and **annotated manually**
- Be **exposed as a real-time API**
- Optionally include a **web front-end** (not mandatory)

---

## Evaluation Grid (Total: 12 points)

| Item | Description | Points |
|------|--------------|--------|
| Teamwork, Clean Code, Pull Requests, linked commits and cards | Proper commit history | **1** |
| Unit-tested preprocessing phase | | **2** |
| AI training phase | | **1** |
| Annotation phase | | **2** |
| Real-time API deployed in an environment | | **2** |
| Automated integration tests | | **2** |
| Final Presentation (5 minutes) | | **2** |

---

## Presentation Guidelines

1. **Purpose:** What is your project’s functional value? What problem does it solve for end users? What makes it innovative?
2. **Demo**
3. **Why are you the best?**
- You may include technical details about **MLOps**, **cost**, and **Time to Market**.
4. **What is missing** — both technically and functionally.

---

### Presentation Format

Choose the format you believe adds the **most value** to your project presentation!
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,22 @@ def load_image(filename: str|BytesIO):
BASE_PATH = Path(__file__).resolve().parent


class IModel():
def predict(self, img) -> np.ndarray:
pass

class ModelPillow(IModel):
def __init__(self, model_path: str):
self.model = load_model(model_path)

def predict(self, img) -> np.ndarray:
return self.model.predict(img)


class Inference:
def __init__(self, logging, model_path: str):
def __init__(self, logging, model: IModel):
self.logger = logging.getLogger(__name__)
self.model = load_model(model_path)
self.model = model

def execute(self, filepath:str|BytesIO):
img = load_image(filepath)
Expand Down
Binary file not shown.
12 changes: 8 additions & 4 deletions packages/mlopspython-inference/tests/test_inference.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import logging
from pathlib import Path
from unittest.mock import MagicMock

import pytest

from inference_pillow import IModel
from mlopspython_inference.inference_pillow import Inference

BASE_PATH = Path(__file__).resolve().parent
input_directory = BASE_PATH / "input"


@pytest.mark.skip(reason="Modèle lourd / GPU non requis sur CI. Enlever ce skip si nécessaire.")
#@pytest.mark.skip(reason="Modèle lourd / GPU non requis sur CI. Enlever ce skip si nécessaire.")
def test_inference_runs_with_sample_model_and_image():
model_path = input_directory / "model" / "final_model.h5"
image_path = input_directory / "images" / "cat.png"

assert model_path.is_file(), "Modèle de test manquant"
assert image_path.is_file(), "Image de test manquante"

inference = Inference(logging, str(model_path))
model_mock = MagicMock(IModel)
model_mock.execute = MagicMock(return_value=[[1, 0, 0]])

inference = Inference(logging, model_mock)
result = inference.execute(str(image_path))

assert result["prediction"] in {"Cat", "Dog", "Other"}
Expand Down
Binary file not shown.
10 changes: 8 additions & 2 deletions workshop_create_library.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
uv init --package mon_package
cd mon_package

For linux/macos :
source .venv/bin/

For windows:
.venv\Scripts\activate

# Runtime dependencies (example)
uv add httpx

Expand All @@ -18,10 +24,10 @@ uv run black . --check
uv run black .



# Run tests & code coverage
uv run pytest -q
uv run pytest --cov=mon_package --cov-report=term-missing --cov-report=html

uv run pytest -q uv run pytest --cov=mon_package --cov-report=term-missing --cov-report=html

# Build wheel + sdist
uv build
Expand Down
Loading