Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions EXPLANATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Explanation of the project

## Description

As a MLE we take the responsibility of the entire ML pipeline, from data ingestion to model deployment. In this case, we will use Docker to containerize our API and ensure it is easy to deploy and run in production. For testing purposes, we will use Docker Compose to run the API and the model in a local environment. And a makefile to automate the process of building and running the Docker containers.

## Project Structure

```markdown
pipeline/
|
├── api/
| ├── main.py
| ├── Dockerfile
| ├── pyproject.toml
| ├── uv.lock
|── processes/
| ├── preprocess/
| | ├── main.py
| | ├── Dockerfile
| | ├── pyproject.toml
| | ├── uv.lock
| ├── inference/
| | ├── main.py
| | ├── Dockerfile
| | ├── pyproject.toml
| | ├── uv.lock
| ├── train/
| | ├── main.py
| | ├── Dockerfile
| | ├── pyproject.toml
| | ├── uv.lock
```

pipeline is the root folder of the project. It contains the following folders:
- api: contains the API code and Dockerfile
- processes: contains the code for the different processes (preprocess, inference, train) and their respective Dockerfiles

## Requirements
- Python 3.12
- Docker
- Docker Compose
- Make
- [UV](https://docs.astral.sh/uv/getting-started/installation/)
Empty file added pipeline/api/Dockerfile
Empty file.
Empty file added pipeline/api/README.md
Empty file.
Empty file added pipeline/api/__init__.py
Empty file.
20 changes: 20 additions & 0 deletions pipeline/api/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from fastapi import FastAPI

from models import InferenceRequest, InferenceResponse

app = FastAPI()

@app.get("/health")
def health_check():
return {"status": "ok"}

@app.get("/inference")
def inference(input: InferenceRequest) -> InferenceResponse:
# Placeholder for inference logic
# Replace with actual model inference code
response = InferenceResponse(
status="success",
predictions=[{"label": "cat", "confidence": 0.95}],
metadata={"model_version": "1.0"}
)
return response
26 changes: 26 additions & 0 deletions pipeline/api/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from pydantic import BaseModel, Field, field_validator


class InferenceRequest(BaseModel):
"""Request model for inference."""

input_data: str = Field(..., description="Input data for the model.")

@field_validator("input_data")
def validate_input_data(cls, value):
if not isinstance(value, str):
raise ValueError("Input data must be a string.")
return value

class InferenceResponse(BaseModel):
"""Response model for inference."""

status: str = Field(..., description="Status of the inference request.")
predictions: list[dict] = Field(..., description="Predictions from the model.")
metadata: dict = Field(..., description="Metadata about the inference process.")

@field_validator("status")
def validate_status(cls, value):
if value not in ["success", "failure"]:
raise ValueError("Status must be 'success' or 'failure'.")
return value
13 changes: 13 additions & 0 deletions pipeline/api/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[project]
name = "api"
version = "0.1.0"
description = "Rest API"
readme = "README.md"
requires-python = "~=3.13"
dependencies = [
"fastapi==0.115.12",
"loguru==0.7.3",
]
dependency-groups = [
{ name = "dev", dependencies = ["pytest==8.3.5", "ruff==0.11.5"] },
]
179 changes: 179 additions & 0 deletions pipeline/api/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
Empty file.
Empty file.
8 changes: 8 additions & 0 deletions pipeline/processes/inference/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from loguru import logger

if __name__ == "__main__":
logger.info("Inference started")

logger.info("Inferencing...")

logger.info("Inference finished")
12 changes: 12 additions & 0 deletions pipeline/processes/inference/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[project]
name = "predict"
version = "0.1.0"
description = "Process to make an inference prediction"
readme = "README.md"
requires-python = "~=3.13"
dependencies = [
"loguru==0.7.3",
]
dependency-groups = [
{ name = "dev", dependencies = ["pytest==8.3.5", "ruff==0.11.5"] },
]
45 changes: 45 additions & 0 deletions pipeline/processes/inference/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
Empty file.
Empty file.
8 changes: 8 additions & 0 deletions pipeline/processes/preprocess/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from loguru import logger

if __name__ == "__main__":
logger.info("Preprocess started")

logger.info("Preprocessing...")

logger.info("Preprocess finished")
Loading