Docker correctly configured
This commit is contained in:
parent
eebe89587b
commit
31c2a49304
10 changed files with 118 additions and 31 deletions
32
.github/workflows/workflow.yml
vendored
Normal file
32
.github/workflows/workflow.yml
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
name: Build and Deploy API
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build-and-run:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: ./deployment/api
|
||||
push: false
|
||||
tags: sentiment_api:latest
|
||||
|
||||
- name: Run docker-compose
|
||||
run: docker-compose up -d
|
||||
14
deployment/api/.dockerignore
Normal file
14
deployment/api/.dockerignore
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Ignorer les caches Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Ignorer les artefacts temporaires
|
||||
downloaded_artifacts/
|
||||
mlruns/
|
||||
logs/
|
||||
|
||||
# Ignorer les tests unitaires
|
||||
tests/
|
||||
|
||||
# Ignorer les variables d'environnement. Elles seront plutôt chargées dans la commande docker run `docker run --env-file ./deployment/api/.env -p 8000:8000 sentiment-api` en développement local, et via des variables définies dans le yaml
|
||||
*.env
|
||||
21
deployment/api/Dockerfile
Normal file
21
deployment/api/Dockerfile
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Utiliser une image légère Python 3.12
|
||||
FROM python:3.12-slim
|
||||
|
||||
# Définir le dossier de travail
|
||||
WORKDIR /app
|
||||
|
||||
# Copier uniquement requirements.txt d'abord (pour optimiser le cache Docker)
|
||||
COPY requirements.txt .
|
||||
|
||||
# Installer les dépendances
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copier le reste du code source
|
||||
COPY . .
|
||||
|
||||
# Exposer les ports 8000 (fastAPI) et 8501 (streamlit)
|
||||
EXPOSE 8000 8501
|
||||
|
||||
RUN chmod +x /app/start.sh
|
||||
|
||||
CMD ["/app/start.sh"]
|
||||
Binary file not shown.
31
deployment/api/docker-compose.yml
Normal file
31
deployment/api/docker-compose.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
version: "3.9"
|
||||
services:
|
||||
api:
|
||||
build:
|
||||
context: ./deployment/api
|
||||
dockerfile: Dockerfile
|
||||
container_name: sentiment_api
|
||||
ports:
|
||||
- "8000:8000" # API FastAPI
|
||||
- "8501:8501" # Streamlit
|
||||
environment:
|
||||
MLFLOW_TRACKING_URI: "${MLFLOW_TRACKING_URI}" # ex: http://mlflow:5000
|
||||
MLFLOW_S3_ENDPOINT_URL: "${MLFLOW_S3_ENDPOINT_URL}" # ex: url MinIO ou S3
|
||||
AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}" # clé ID S3
|
||||
AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}" # clé secrète S3
|
||||
|
||||
SMTP_SERVER: "${SMTP_SERVER}" # serveur SMTP
|
||||
SMTP_PORT: "${SMTP_PORT}" # port SMTP (ex: 587)
|
||||
SMTP_EMAIL: "${SMTP_EMAIL}" # email expéditeur
|
||||
SMTP_PASSWORD: "${SMTP_PASSWORD}" # mot de passe SMTP
|
||||
SMTP_FROM_ALIAS: "${SMTP_FROM_ALIAS}" # alias (optionnel)
|
||||
ADMIN_EMAIL: "${ADMIN_EMAIL}" # email admin destinataire
|
||||
|
||||
# only if you have a reverse proxy server
|
||||
# networks:
|
||||
# - swag
|
||||
restart: always
|
||||
# only if you have a reverse proxy server
|
||||
# networks:
|
||||
# swag:
|
||||
# external: true
|
||||
|
|
@ -11,10 +11,10 @@ def send_error_report_email(error_reports):
|
|||
"""
|
||||
smtp_server = os.getenv("SMTP_SERVER")
|
||||
smtp_port = int(os.getenv("SMTP_PORT", 587))
|
||||
smtp_email = os.getenv("SMTP_EMAIL")
|
||||
smtp_email = os.getenv("SMTP_EMAIL") # main email address. If smt_from_alias is not, it will also be the mail sender
|
||||
smtp_password = os.getenv("SMTP_PASSWORD")
|
||||
smtp_from_alias = os.getenv("SMTP_FROM_ALIAS", smtp_email)
|
||||
admin_email = os.getenv("ADMIN_EMAIL")
|
||||
smtp_from_alias = os.getenv("SMTP_FROM_ALIAS", smtp_email) # mail sender if not none (alias)
|
||||
admin_email = os.getenv("ADMIN_EMAIL") # this one will receive the mail
|
||||
|
||||
if not all([smtp_server, smtp_email, smtp_password, admin_email]):
|
||||
print("❌ Configuration email manquante dans .env")
|
||||
|
|
@ -23,7 +23,11 @@ def send_error_report_email(error_reports):
|
|||
try:
|
||||
# Créer le message
|
||||
msg = MIMEMultipart()
|
||||
msg['From'] = f"Air Paradis Monitor <{smtp_from_alias}>"
|
||||
if smtp_from_alias is not None:
|
||||
smtp_from = smtp_from_alias
|
||||
else:
|
||||
smtp_from = smtp_email
|
||||
msg['From'] = f"Air Paradis Monitor <{smtp_from}>"
|
||||
msg['To'] = admin_email
|
||||
msg['Subject'] = f"🚨 Rapport d'erreurs - Prédictions sentiments ({datetime.now().strftime('%d/%m/%Y %H:%M')})"
|
||||
|
||||
|
|
@ -86,7 +90,7 @@ Un nouveau rapport d'erreurs a été généré pour l'API de prédiction de sent
|
|||
---
|
||||
Cordialement,
|
||||
🤖 API Air Paradis - Système de monitoring automatique
|
||||
📧 Envoyé depuis : """ + smtp_from_alias
|
||||
📧 Envoyé depuis : """ + smtp_from
|
||||
|
||||
# Ajouter le corps du message
|
||||
msg.attach(MIMEText(body, 'plain', 'utf-8'))
|
||||
|
|
@ -97,7 +101,7 @@ Cordialement,
|
|||
server.login(smtp_email, smtp_password)
|
||||
server.send_message(msg)
|
||||
|
||||
print(f"✅ Email de rapport envoyé avec succès depuis {smtp_from_alias}")
|
||||
print(f"✅ Email de rapport envoyé avec succès depuis {smtp_from}")
|
||||
print(f"📊 JSON intégré dans le corps du message")
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from tensorflow.keras.preprocessing.sequence import pad_sequences
|
|||
PARENT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../"))
|
||||
sys.path.append(PARENT_DIR)
|
||||
# 🔐 Charger les variables d'environnement (.env à deux niveaux au-dessus)
|
||||
load_dotenv(dotenv_path=os.path.join(PARENT_DIR, ".env"))
|
||||
load_dotenv()
|
||||
|
||||
|
||||
# 🔁 Import de la fonction de prétraitement (LOCAL)
|
||||
|
|
@ -69,6 +69,7 @@ def load_model_and_artifacts(model_name=MODEL_NAME, stage=STAGE):
|
|||
# Déterminer les chemins des artefacts
|
||||
local_dir = "./downloaded_artifacts"
|
||||
os.makedirs(local_dir, exist_ok=True)
|
||||
print("Contenu de downloaded_artifacts :", os.listdir(local_dir))
|
||||
base_path = "local_artifacts"
|
||||
tokenizer_file = "tokenizer.pickle"
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ requests==2.32.4
|
|||
# === Machine Learning ===
|
||||
tensorflow==2.19.0
|
||||
mlflow==3.1.1
|
||||
boto3==1.39.2
|
||||
numpy==2.1.3
|
||||
pandas==2.3.0
|
||||
# === Traitement de texte ===
|
||||
|
|
|
|||
7
deployment/api/start.sh
Normal file
7
deployment/api/start.sh
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Lancer Streamlit en arrière-plan
|
||||
streamlit run app.py --server.port 8501 --server.address 0.0.0.0 &
|
||||
|
||||
# Lancer Uvicorn en premier plan (Docker "suit" ce processus)
|
||||
uvicorn main:app --host 0.0.0.0 --port 8000
|
||||
|
|
@ -6,30 +6,6 @@ Created on Sat Jul 5 15:03:24 2025
|
|||
@author: madfuckinman
|
||||
"""
|
||||
|
||||
# # test_alias_email.py
|
||||
# import os
|
||||
# from dotenv import load_dotenv
|
||||
# from email_service import send_error_report_email
|
||||
|
||||
# load_dotenv()
|
||||
|
||||
# print("🔧 Configuration Email:")
|
||||
# print(f"Serveur SMTP: {os.getenv('SMTP_SERVER')}")
|
||||
# print(f"Authentification: {os.getenv('SMTP_EMAIL')}")
|
||||
# print(f"Expéditeur (alias): {os.getenv('SMTP_FROM_ALIAS')}")
|
||||
# print(f"Destinataire: {os.getenv('ADMIN_EMAIL')}")
|
||||
|
||||
# # Test
|
||||
# test_reports = {
|
||||
# "Service client décevant": "positif",
|
||||
# "J'adore cette compagnie": "negatif",
|
||||
# "Vol annulé sans prévenir": "positif"
|
||||
# }
|
||||
|
||||
# print("\n📧 Test d'envoi depuis l'alias...")
|
||||
# result = send_error_report_email(test_reports)
|
||||
# print(f"Résultat : {'✅ Succès' if result else '❌ Échec'}")
|
||||
|
||||
import os
|
||||
import sys
|
||||
from dotenv import load_dotenv
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue