# Déployer une API Flask sur Render
Ce tutoriel explique comment déployer une API Flask qui utilise des modèles de machine learning pré-entraînés sur [Render](https://render.com).
## Étape 1 : Créer un compte Render
Si vous n'avez pas encore de compte, inscrivez-vous sur [Render](https://render.com).
## Étape 2 : Préparer votre projet
1. Créez un dossier pour votre projet, par exemple `flask_api`.
2. Dans ce dossier, créez les fichiers suivants :
- `app.py` : votre code Flask.
- `requirements.txt` : les dépendances de votre application.
```
Flask==2.3.2
scikit-learn==1.1.3
joblib==1.3.2
numpy==1.24.3
Pillow==10.0.0
requests==2.25.1
```
- `runtime.txt` : la version de Python.
```bash
python-3.9.12
```
### Fichier `app.py`
```python
import requests
import joblib
from flask import Flask, request, jsonify
import numpy as np
from PIL import Image
import io
app = Flask(__name__)
# Fonction pour télécharger le modèle depuis GitHub
def download_model(model_url, model_name):
response = requests.get(model_url)
with open(model_name, 'wb') as f:
f.write(response.content)
# Télécharger les modèles depuis GitHub
download_model('https://github.com/nevermind78/API_RENDER/raw/refs/heads/main/logistic_regression.pkl', 'logistic_regression.pkl')
download_model('https://github.com/nevermind78/API_RENDER/raw/refs/heads/main/linear_svc.pkl', 'linear_svc.pkl')
download_model('https://github.com/nevermind78/API_RENDER/raw/refs/heads/main/knn.pkl', 'knn.pkl')
# Charger les modèles
logistic_regression = joblib.load('logistic_regression.pkl')
linear_svc = joblib.load('linear_svc.pkl')
knn = joblib.load('knn.pkl')
@app.route('/predict', methods=['POST'])
def predict():
if 'file' not in request.files:
return jsonify({"error": "No file provided"}), 400
file = request.files['file']
file.seek(0)
try:
file_data = file.read()
image = Image.open(io.BytesIO(file_data)).convert('L').resize((28, 28))
except Exception as e:
return jsonify({"error": f"Failed to process image: {str(e)}"}), 400
image_array = np.array(image).reshape(1, -1) / 255.0
model_name = request.form.get('model')
if model_name == "Logistic Regression" and logistic_regression is not None:
prediction = logistic_regression.predict(image_array)
elif model_name == "Linear SVC" and linear_svc is not None:
prediction = linear_svc.predict(image_array)
elif model_name == "KNN" and knn is not None:
prediction = knn.predict(image_array)
else:
return jsonify({"error": f"Model '{model_name}' is either invalid or not loaded."}), 400
return jsonify({"prediction": int(prediction[0])})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
```
## Étape 3 : Initialiser un dépôt Git
1. Initialisez un dépôt Git dans votre projet :
```bash
git init
```
2. Ajoutez tous les fichiers au dépôt Git :
```bash
git add .
```
3. Faites un commit des fichiers ajoutés :
```bash
git commit -m "Initial commit: API Flask pour la prédiction d'images"
```
## Étape 4 : Créer un dépôt sur GitHub
1. Allez sur [GitHub](https://github.com) et créez un nouveau dépôt (par exemple `flask-render-example`).
2. Ne cochez pas **Initialize this repository with a README**.
3. Dans le terminal, liez votre dépôt local au dépôt GitHub :
```bash
git remote add origin https://github.com/votre-username/flask-render-example.git
```
4. Poussez le code sur GitHub :
```bash
git push -u origin main
```
## Étape 5 : Déployer sur Render
### 5.1. Créer un compte Render
Si ce n'est pas déjà fait, créez un compte gratuit sur [Render](https://render.com).
### 5.2. Créer un Nouveau Service Web
1. Une fois connecté, cliquez sur **New Web Service**.
2. Sélectionnez **GitHub** comme source.
3. Autorisez Render à accéder à votre dépôt GitHub.
4. Sélectionnez le dépôt contenant votre projet Flask.
### 5.3. Configurer le Service Web
1. Donnez un nom à votre service, par exemple `flask-render-example`.
2. **Build Command** : Laissez ce champ vide, Render détecte automatiquement les dépendances.
3. **Start Command** : Entrez `python app.py`.
4. Sélectionnez le plan gratuit (**Free**).
5. Cliquez sur **Create Web Service**.
### 5.4. Attendre le Déploiement
Render va cloner votre dépôt, installer les dépendances et démarrer l'API Flask. Vous pouvez suivre les logs en temps réel pour vérifier que tout se passe bien.
### 5.5. Tester l'API Déployée
Une fois le déploiement terminé, Render vous fournira une URL de votre service. Par exemple : `https://flask-render-example.onrender.com`.
Testez votre API en envoyant une requête POST avec une image pour obtenir la prédiction du modèle choisi.
## Exemple pour tester
* Vous pouvez télécharger des images de test en éxécutant ce script python
```python=
import numpy as np
import matplotlib.pyplot as plt
# installer openml avec pip
import openml as oml
import os
# Charger le dataset Fashion MNIST
fmnist = oml.datasets.get_dataset(40996)
X, y, _, _ = fmnist.get_data(target=fmnist.default_target_attribute)
# Convertir X en tableau NumPy
X = X.to_numpy()
print(y)
# Créer un dossier pour sauvegarder les images
output_dir = "test_images"
os.makedirs(output_dir, exist_ok=True)
# Sauvegarder 10 images de test
for i in range(10,20): # Vous pouvez changer le nombre d'images à sauvegarder
image = X[i].reshape(28, 28) # Redimensionner en 28x28 pixels
image_path = os.path.join(output_dir, f"test_image_{i}.png")
plt.imsave(image_path, image, cmap='gray')
print(f"Image {i} sauvegardée sous {image_path}")
```
* Vous pouvez tester l'api déployer sur **render** en utilisant ce script
```python=
import requests
# L'URL de votre API Flask
url = 'https://api-render-146a.onrender.com/predict'
# Chemin vers l'image à tester
image_path = 'test_image_1.png'
# Charger l'image et l'envoyer avec le modèle choisi
with open(image_path, 'rb') as file:
files = {'file': file}
data = {'model': 'Logistic Regression'} # Indiquez le modèle ici
response = requests.post(url, files=files, data=data)
fmnist_classes = [
"T-shirt/top", # Classe 0
"Trouser", # Classe 1
"Pullover", # Classe 2
"Dress", # Classe 3
"Coat", # Classe 4
"Sandal", # Classe 5
"Shirt", # Classe 6
"Sneaker", # Classe 7
"Bag", # Classe 8
"Ankle boot" # Classe 9
]
# Afficher la réponse
print(fmnist_classes[response.json()['prediction']])
```