/
burning_hell
/
lab12_ml_testing
Обзор
Документация
Войти
/
burning_hell
/
lab12_ml_testing
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
ml_api.py
434 строки
16 KB
burning-hel
uploaded
13 дек 2025, 01:14
13 дек 2025, 01:14
659f38d
Код
Авторство
О чём код?
from flask import Flask, request, jsonify import pandas as pd from ml_pipeline import MLPipeline import joblib import os from datetime import datetime app = Flask(__name__) pipeline = MLPipeline() # Загружаем модель при старте def load_model_on_startup(): """Загружаем модель при старте приложения""" print("🚀 Загружаем ML модель...") try: success = pipeline.load_model('model') if success: print("✅ Модель успешно загружена") else: print("❌ Не удалось загрузить модель. Проверьте наличие файлов model.pkl") except Exception as e: print(f"❌ Ошибка при загрузке модели: {e}") # Загружаем модель сразу при импорте load_model_on_startup() @app.route('/', methods=['GET']) def home(): """Домашняя страница API""" return jsonify({ 'service': 'ML Prediction API', 'version': '1.0.0', 'description': 'API для предсказаний на основе машинного обучения', 'model_loaded': pipeline.model is not None, 'endpoints': { 'GET /': 'Эта страница (документация)', 'GET /health': 'Проверка здоровья API', 'POST /predict': 'Предсказание для одного клиента', 'POST /batch_predict': 'Предсказание для нескольких клиентов', 'GET /model_info': 'Информация о модели', 'GET /example': 'Примеры запросов для тестирования' }, 'quick_start': 'Отправьте POST запрос на /predict с JSON данными клиента', 'timestamp': datetime.now().isoformat() }) @app.route('/health', methods=['GET']) def health_check(): """Проверка здоровья API""" return jsonify({ 'status': 'healthy', 'timestamp': datetime.now().isoformat(), 'model_loaded': pipeline.model is not None, 'service': 'ML Prediction API', 'version': '1.0.0' }) @app.route('/predict', methods=['POST']) def predict(): """Эндпоинт для предсказаний""" try: # Получаем данные из запроса data = request.get_json() if not data: return jsonify({'error': 'No data provided'}), 400 # Проверяем что модель загружена if pipeline.model is None: return jsonify({'error': 'Model not loaded'}), 503 # Делаем предсказание predictions = pipeline.predict(data) # Формируем ответ response = { 'predictions': predictions, 'timestamp': datetime.now().isoformat(), 'model_version': '1.0', 'status': 'success', 'message': 'Prediction completed successfully' } return jsonify(response) except Exception as e: return jsonify({'error': str(e), 'status': 'error'}), 500 @app.route('/batch_predict', methods=['POST']) def batch_predict(): """Эндпоинт для батчевых предсказаний""" try: data = request.get_json() if not data or 'customers' not in data: return jsonify({'error': 'No customers data provided'}), 400 customers = data['customers'] if not isinstance(customers, list): return jsonify({'error': 'Customers should be a list'}), 400 # Делаем предсказания predictions = pipeline.predict(customers) response = { 'predictions': predictions, 'total_customers': len(customers), 'timestamp': datetime.now().isoformat(), 'status': 'success', 'message': f'Batch prediction completed for {len(customers)} customers' } return jsonify(response) except Exception as e: return jsonify({'error': str(e), 'status': 'error'}), 500 @app.route('/model_info', methods=['GET']) def model_info(): """Информация о модели""" if pipeline.model is None: return jsonify({'error': 'Model not loaded'}), 503 feature_importance = None if hasattr(pipeline.model, 'feature_importances_'): # Проверяем наличие feature_columns if hasattr(pipeline, 'feature_columns') and pipeline.feature_columns: feature_importance = [] for i, (col, importance) in enumerate(zip(pipeline.feature_columns, pipeline.model.feature_importances_)): feature_importance.append({ 'feature': col, 'importance': float(importance), 'rank': i + 1 }) # Сортируем по важности feature_importance.sort(key=lambda x: x['importance'], reverse=True) response = { 'model_type': type(pipeline.model).__name__, 'model_loaded': True, 'timestamp': datetime.now().isoformat() } # Добавляем feature_columns если есть if hasattr(pipeline, 'feature_columns'): response['feature_columns'] = pipeline.feature_columns # Добавляем target_column если есть if hasattr(pipeline, 'target_column'): response['target_column'] = pipeline.target_column # Добавляем feature importance если есть if feature_importance: response['feature_importance'] = feature_importance # Добавляем топ-5 фич response['top_5_features'] = feature_importance[:5] if len(feature_importance) > 5 else feature_importance # Добавляем параметры модели если доступны if hasattr(pipeline.model, 'get_params'): response['model_parameters'] = pipeline.model.get_params() return jsonify(response) @app.route('/example', methods=['GET']) def get_example(): """Примеры запросов для тестирования API""" example_single = { "age": 35, "income": 50000, "credit_score": 720, "loan_amount": 10000, "employment_years": 5 } example_batch = { "customers": [ { "age": 35, "income": 50000, "credit_score": 720, "loan_amount": 10000, "employment_years": 5 }, { "age": 45, "income": 80000, "credit_score": 680, "loan_amount": 20000, "employment_years": 10 }, { "age": 25, "income": 30000, "credit_score": 650, "loan_amount": 5000, "employment_years": 2 } ] } return jsonify({ 'examples': { 'single_prediction': { 'endpoint': 'POST /predict', 'description': 'Предсказание для одного клиента', 'example_request': example_single, 'curl_command': 'curl -X POST http://localhost:5000/predict -H "Content-Type: application/json" -d \'{"age": 35, "income": 50000, "credit_score": 720, "loan_amount": 10000, "employment_years": 5}\'' }, 'batch_prediction': { 'endpoint': 'POST /batch_predict', 'description': 'Предсказание для нескольких клиентов', 'example_request': example_batch, 'curl_command': 'curl -X POST http://localhost:5000/batch_predict -H "Content-Type: application/json" -d \'{"customers": [{"age": 35, "income": 50000, "credit_score": 720, "loan_amount": 10000, "employment_years": 5}]}\'' } }, 'test_commands': { 'check_health': 'curl http://localhost:5000/health', 'get_model_info': 'curl http://localhost:5000/model_info', 'get_home': 'curl http://localhost:5000/' } }) @app.route('/docs', methods=['GET']) def documentation(): """HTML документация API""" return ''' <!DOCTYPE html> <html> <head> <title>ML API Documentation</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; margin: 0; padding: 20px; background-color: #f5f5f5; } .container { max-width: 1200px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; } h2 { color: #34495e; margin-top: 30px; } .endpoint { background: #f8f9fa; border-left: 4px solid #3498db; padding: 15px; margin: 15px 0; border-radius: 0 5px 5px 0; } .method { display: inline-block; padding: 5px 12px; background: #3498db; color: white; border-radius: 4px; font-weight: bold; margin-right: 10px; } .url { font-family: 'Courier New', monospace; color: #2c3e50; font-weight: bold; } code { background: #2c3e50; color: #ecf0f1; padding: 10px; border-radius: 5px; display: block; overflow-x: auto; margin: 10px 0; } .success { color: #27ae60; } .error { color: #e74c3c; } .warning { color: #f39c12; } .model-status { padding: 10px; border-radius: 5px; margin: 10px 0; } .model-loaded { background: #d5f4e6; color: #27ae60; } .model-not-loaded { background: #fadbd8; color: #e74c3c; } </style> </head> <body> <div class="container"> <h1>🤖 ML Prediction API Documentation</h1> <div class="model-status ''' + ('model-loaded' if pipeline.model is not None else 'model-not-loaded') + '''"> <strong>Model Status:</strong> ''' + ('✅ Loaded and Ready' if pipeline.model is not None else '❌ Not Loaded') + ''' </div> <h2>📋 Overview</h2> <p>This API provides machine learning predictions for customer data. It supports single predictions and batch processing.</p> <h2>🔧 Available Endpoints</h2> <div class="endpoint"> <span class="method">GET</span> <span class="url">/</span> <p>Main API page with documentation</p> </div> <div class="endpoint"> <span class="method">GET</span> <span class="url">/health</span> <p>Health check endpoint</p> </div> <div class="endpoint"> <span class="method">POST</span> <span class="url">/predict</span> <p>Single prediction for one customer</p> </div> <div class="endpoint"> <span class="method">POST</span> <span class="url">/batch_predict</span> <p>Batch predictions for multiple customers</p> </div> <div class="endpoint"> <span class="method">GET</span> <span class="url">/model_info</span> <p>Information about the loaded ML model</p> </div> <div class="endpoint"> <span class="method">GET</span> <span class="url">/example</span> <p>Example requests for testing</p> </div> <h2>🚀 Quick Start</h2> <h3>1. Check API Health</h3> <code>curl http://localhost:5000/health</code> <h3>2. Make a Single Prediction</h3> <code>curl -X POST http://localhost:5000/predict \\ -H "Content-Type: application/json" \\ -d '{"age": 35, "income": 50000, "credit_score": 720, "loan_amount": 10000, "employment_years": 5}'</code> <h3>3. Make Batch Predictions</h3> <code>curl -X POST http://localhost:5000/batch_predict \\ -H "Content-Type: application/json" \\ -d '{"customers": [{"age": 35, "income": 50000, "credit_score": 720, "loan_amount": 10000, "employment_years": 5}]}'</code> <h2>📊 Response Format</h2> <h3>Success Response</h3> <code>{ "predictions": [...], "timestamp": "2024-01-01T12:00:00", "model_version": "1.0", "status": "success" }</code> <h3>Error Response</h3> <code>{ "error": "Error message", "status": "error" }</code> <h2>🔍 Testing</h2> <p>Open browser console (F12) and try:</p> <code>fetch('/health').then(r => r.json()).then(console.log)</code> <h2>⚙️ Technical Details</h2> <ul> <li>Framework: Flask</li> <li>Port: 5000</li> <li>Host: 0.0.0.0 (accessible from network)</li> <li>Debug Mode: Enabled</li> </ul> </div> <script> // Auto-test on page load window.addEventListener('load', function() { fetch('/health') .then(response => response.json()) .then(data => { console.log('API Health Check:', data); }) .catch(error => { console.error('API Health Check Failed:', error); }); }); </script> </body> </html> ''' if __name__ == '__main__': print("=" * 60) print("🎯 ЗАПУСК ML API") print("=" * 60) print("📚 Доступные эндпоинты:") print(" GET / - Главная страница и документация") print(" GET /docs - HTML документация") print(" GET /health - Проверка здоровья API") print(" POST /predict - Предсказание для одного клиента") print(" POST /batch_predict - Предсказание для нескольких клиентов") print(" GET /model_info - Информация о модели") print(" GET /example - Примеры запросов для тестирования") print("\n📡 Сеть:") print(" Локально: http://localhost:5000") print(" В сети: http://[ваш-ip]:5000") print("\n🔧 Статус модели: ", end="") if pipeline.model is not None: print("✅ ЗАГРУЖЕНА") else: print("❌ НЕ ЗАГРУЖЕНА") print(" Создайте модель через ml_pipeline.py или загрузите model.pkl") print("=" * 60) app.run(debug=True, host='0.0.0.0', port=5000)