Si votre application C++ est un programme en ligne de commande qui prend uniquement deux arguments (un fichier d'entrée et un fichier de sortie) et ne connaît pas HTTP ou les appels réseau, vous pouvez tout de même créer une API pour la piloter en utilisant une architecture où un serveur web intermédiaire exécute l'application C++ en arrière-plan.
Dans ce cas, vous n'avez pas besoin d'ajouter de code HTTP dans votre application C++. Vous créerez un conteneur Docker qui :
Expose une API via un serveur web léger (comme Flask ou Express). Utilise cette API pour déclencher l'exécution de votre application C++ en ligne de commande avec les arguments appropriés. Solution globale : L'API : Un serveur web léger (Flask) qui accepte les requêtes HTTP pour lancer votre programme en ligne de commande. L'application C++ : Elle reste inchangée. Le serveur web appelle l'application en utilisant subprocess ou un équivalent pour exécuter les commandes en ligne. Étapes détaillées
Supposons que votre programme C++ s'appelle my_program.cpp
et ressemble à ceci :
// my_program.cpp
#include <iostream>
#include <fstream>
int main(int argc, char* argv[]) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " <input_file> <output_file>" << std::endl;
return 1;
}
std::ifstream input(argv[1]);
std::ofstream output(argv[2]);
if (!input.is_open() || !output.is_open()) {
std::cerr << "Error: could not open files." << std::endl;
return 1;
}
std::string line;
while (std::getline(input, line)) {
// Exemple simple : écrire chaque ligne en majuscules dans le fichier de sortie
for (auto & c: line) c = toupper(c);
output << line << std::endl;
}
input.close();
output.close();
std::cout << "Processing complete!" << std::endl;
return 0;
}
Ce programme prend un fichier d'entrée et un fichier de sortie, puis écrit le contenu en majuscules dans le fichier de sortie.
Vous allez maintenant créer un serveur Flask pour accepter une requête HTTP et appeler le programme C++ avec les fichiers spécifiés.
Créez un fichier Python server.py :
# server.py
import subprocess
from flask import Flask, request, jsonify
import os
app = Flask(__name__)
@app.route('/run', methods=['POST'])
def run_program():
data = request.json
input_file = data.get('input_file')
output_file = data.get('output_file')
if not input_file or not output_file:
return jsonify({'error': 'Missing input or output file'}), 400
# Vérifiez que les fichiers existent pour éviter les erreurs
if not os.path.exists(input_file):
return jsonify({'error': 'Input file does not exist'}), 400
try:
# Exécuter le programme C++ avec subprocess
result = subprocess.run(['./my_program', input_file, output_file], capture_output=True, text=True)
if result.returncode != 0:
return jsonify({'error': 'Execution failed', 'details': result.stderr}), 500
return jsonify({'message': 'Execution successful', 'output_file': output_file})
except Exception as e:
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Le Dockerfile compile l'application C++, installe Python et Flask, et configure le conteneur pour exécuter le serveur Flask et appeler l'application C++.
# Utiliser une image Ubuntu de base
FROM ubuntu:20.04
# Installer les dépendances
RUN apt-get update && apt-get install -y \
g++ \
python3 \
python3-pip
# Installer Flask pour Python
RUN pip3 install flask
# Créer un dossier de travail
WORKDIR /app
# Copier les fichiers C++ et Python
COPY my_program.cpp .
COPY server.py .
# Compiler le programme C++
RUN g++ -o my_program my_program.cpp
# Exposer le port 5000 pour l'API Flask
EXPOSE 5000
# Exécuter le serveur Flask
CMD ["python3", "server.py"]
Construisez l'image Docker en exécutant la commande suivante dans le même répertoire que le Dockerfile et les fichiers :
docker build -t cpp-api-server .
Lancez le conteneur avec cette commande :
docker run -p 5000:5000 cpp-api-server
Vous pouvez maintenant envoyer une requête POST à l'API pour exécuter le programme C++ en fournissant les fichiers d'entrée et de sortie.
Exemple de requête avec curl :
curl -X POST http://localhost:5000/run -H "Content-Type: application/json" \
-d '{"input_file": "/path/to/input.txt", "output_file": "/path/to/output.txt"}'
Ou avec Postman ou un autre client HTTP.
L'API appelle votre programme C++ avec les fichiers spécifiés, traite le fichier d'entrée, et enregistre les résultats dans le fichier de sortie. Si tout se passe bien, l'API renverra une réponse JSON indiquant le succès de l'exécution et mentionnant le fichier de sortie.
-
my_program.cpp
: Votre application C++ qui traite un fichier d'entrée et génère un fichier de sortie. -
server.py
: Un serveur Flask qui accepte les requêtes HTTP et appelle votre programme C++. -
Dockerfile
: Instructions pour créer l'image Docker, compiler le programme C++ et exécuter le serveur Flask.
- Votre application C++ reste inchangée.
- Le serveur Flask sert d'intermédiaire pour permettre l'accès via HTTP.
- Flexibilité pour l'intégration avec d'autres systèmes via l'API.
Pour appeler votre API exposée par le serveur Flask depuis une page web, vous utiliserez JavaScript (avec fetch ou une bibliothèque comme Axios) pour envoyer une requête HTTP à l'API Flask hébergée dans Docker.
Voici les étapes pour appeler l'API depuis une page web :
Voici un exemple de page web simple qui contient un formulaire permettant de spécifier les noms des fichiers d'entrée et de sortie, puis d'envoyer une requête à votre API Flask via JavaScript.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Appel API C++</title>
</head>
<body>
<h1>Appel de l'application C++ via API</h1>
<form id="fileForm">
<label for="inputFile">Fichier d'entrée :</label>
<input type="text" id="inputFile" name="inputFile" placeholder="/path/to/input.txt" required><br><br>
<label for="outputFile">Fichier de sortie :</label>
<input type="text" id="outputFile" name="outputFile" placeholder="/path/to/output.txt" required><br><br>
<button type="submit">Envoyer</button>
</form>
<p id="result"></p>
<script>
document.getElementById('fileForm').addEventListener('submit', function(event) {
event.preventDefault(); // Empêche le rechargement de la page
// Récupération des valeurs du formulaire
const inputFile = document.getElementById('inputFile').value;
const outputFile = document.getElementById('outputFile').value;
// Préparation des données à envoyer
const data = {
input_file: inputFile,
output_file: outputFile
};
// Envoi de la requête POST avec fetch
fetch('http://localhost:5000/run', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
// Affiche le résultat sur la page
if (data.error) {
document.getElementById('result').innerText = `Erreur : ${data.error}`;
} else {
document.getElementById('result').innerText = `Succès : fichier de sortie généré à ${data.output_file}`;
}
})
.catch(error => {
document.getElementById('result').innerText = `Erreur : ${error}`;
});
});
</script>
</body>
</html>
Formulaire HTML : Un formulaire simple avec deux champs où l'utilisateur peut entrer les chemins du fichier d'entrée et du fichier de sortie. JavaScript (fetch API) : Le formulaire est lié à une fonction JavaScript qui intercepte la soumission du formulaire, empêche le rechargement de la page avec event.preventDefault(), puis envoie une requête POST à l'API Flask. fetch : Envoie une requête POST avec un corps JSON contenant les noms de fichiers d'entrée et de sortie. Gestion de la réponse : Une fois la réponse reçue de l'API Flask, la page affiche le message de succès ou d'erreur dans un paragraphe avec l'id result.
Lancement de Docker : Assurez-vous que votre conteneur Docker (avec le serveur Flask et l'application C++) est en cours d'exécution :
docker run -p 5000:5000 cpp-api-server
Tester la page web : Ouvrez le fichier HTML dans un navigateur web (vous pouvez simplement l'ouvrir en double-cliquant dessus). Remplissez les champs du formulaire avec les chemins du fichier d'entrée et de sortie, puis cliquez sur Envoyer. Le JavaScript dans la page web enverra la requête POST à l'API Flask, et le résultat sera affiché directement dans la page.
Si la page web et l'API Flask sont hébergées sur des origines différentes (par exemple, l'API est sur localhost:5000 et la page web sur un autre port), vous devrez gérer les Cross-Origin Resource Sharing (CORS) dans Flask.
Ajoutez la gestion de CORS dans votre serveur Flask en installant le module flask-cors et en l'activant dans votre application.
Ajoutez cette ligne dans votre Dockerfile avant la commande CMD :
RUN pip3 install flask-cors
Modifiez le fichier server.py pour activer le CORS :
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # Permettre les requêtes Cross-Origin
Cela permettra à votre page web d'envoyer des requêtes à l'API Flask même si elles sont sur des origines différentes.
Pour une utilisation en production, il serait préférable d'héberger l'API Flask et la page web sur un serveur, plutôt que d'utiliser localhost. Vous pouvez :
Déployer l'API sur un service comme AWS, Heroku, ou une machine virtuelle. Héberger la page web avec un serveur HTTP léger comme Nginx ou Apache, ou directement sur un service d'hébergement web.
Appel de l'API : La page web envoie une requête HTTP via JavaScript à votre API Flask exposée par Docker. API en ligne de commande : Le serveur Flask exécute l'application C++ en ligne de commande, prend les fichiers spécifiés en entrée, et génère les résultats. Cela vous permet de déclencher l'exécution de votre programme C++ depuis une interface web de manière simple et intuitive.