# 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']]) ```