Skip to content

Commit c4620d2

Browse files
committed
Initial Commit 🚀
0 parents  commit c4620d2

File tree

8 files changed

+85
-0
lines changed

8 files changed

+85
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM python:3.11-slim
2+
3+
WORKDIR /app
4+
COPY requirements.txt .
5+
RUN pip install -r requirements.txt
6+
7+
COPY . .
8+
9+
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# 🚀 Logistic Regression API
2+
3+
ML API that predicts binary classes using scikit-learn and FastAPI.
4+
5+
- [x] Model trained on breast cancer dataset
6+
- [x] REST API with FastAPI
7+
- [x] Docker support
8+
- [x] Built by [Pierre-Henry Soria](https://pierrehenry.be)
9+
10+
## 🔋 Run Locally
11+
12+
```bash
13+
cd train/
14+
python train_model.py
15+
16+
cd ..
17+
uvicorn app.main:app --reload
18+
```
19+
20+
## 🐟 Docker
21+
22+
```bash
23+
docker build -t ml-api .
24+
docker run -p 8000:8000 ml-api
25+
```
26+
27+
Visit `http://127.0.0.1:8000/docs` for Swagger UI.
28+
29+
30+
## 👋 Author
31+
32+
[![Pierre-Henry Soria](https://avatars0.githubusercontent.com/u/1325411?s=200)](https://ph7.me "Pierre-Henry Soria, Software Developer")
33+
34+
Made with ❤️ by **[Pierre-Henry Soria](https://pierrehenry.be)**. A super passionate & enthusiastic Problem-Solver / Senior Software Engineer. Also a true cheese 🧀, ristretto ☕️, and dark chocolate lover! 😋
35+
36+
[![@phenrysay](https://img.shields.io/badge/x-000000?style=for-the-badge&logo=x)](https://x.com/phenrysay "Follow Me on X") [![pH-7](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/pH-7 "My GitHub") [![YouTube Video](https://img.shields.io/badge/YouTube-FF0000?style=for-the-badge&logo=youtube&logoColor=white)](https://youtu.be/cWBuZ4DXGK4 "YouTube SucceedAI Video") [![Bluesky](https://img.shields.io/badge/bluesky-1e90ff?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjI0cHgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMwIDZsLTIuOTk5LTEuNjY2TDMyIDMuMzQgMjMuMTg5IDAgMTYuMDA2IDUuMzQgOC44MTMgMCAwIDMuMzQgNC45OTkgNC4zMzQgMCA2bDUuMDAxIDQuODAzTDQgMjAuODFWMjRsNS4wMDEtMS42NjZMMTYgMjhMMjIuOTk5IDIyLjM0IDMyIDI0di0zLjE4OUwyNy4wMDIgMTIgMzAgNiIgLz48L3N2Zz4=)](https://bsky.app/profile/ph7s.bsky.social "Bluesky Profile")

app/main.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from fastapi import FastAPI
2+
from app.schemas import PredictionInput
3+
from app.model import predict
4+
5+
app = FastAPI()
6+
7+
@app.post("/predict")
8+
def get_prediction(input: PredictionInput):
9+
result = predict(input.data)
10+
return {"prediction": result}

app/model.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import joblib
2+
3+
model = joblib.load("model/logistic_model.pkl")
4+
5+
def predict(data):
6+
prediction = model.predict([data])
7+
return int(prediction[0])

app/schemas.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from pydantic import BaseModel
2+
3+
class PredictionInput(BaseModel):
4+
data: list[float]

requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fastapi
2+
uvicorn
3+
scikit-learn
4+
joblib
5+
pydantic

train/train_model.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from sklearn.datasets import load_breast_cancer
2+
from sklearn.linear_model import LogisticRegression
3+
from sklearn.model_selection import train_test_split
4+
import joblib
5+
import os
6+
7+
data = load_breast_cancer()
8+
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target)
9+
10+
model = LogisticRegression(max_iter=10000)
11+
model.fit(X_train, y_train)
12+
13+
os.makedirs('../model', exist_ok=True)
14+
joblib.dump(model, '../model/logistic_model.pkl')

0 commit comments

Comments
 (0)