[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/AndNikDev/CodeHelperNET/main/backend/api_server.py [Back]  [Original]

#!/usr/bin/env python3
"""
Servidor API para CodeHelperNET con Ollama
Expone el chatbot RAG como una API REST
"""

from flask import Flask, request, jsonify
from flask_cors import CORS
import sys
import os
import logging
from datetime import datetime
from dotenv import load_dotenv
import requests

# Cargar variables de entorno
load_dotenv('config.env')

# Agregar el directorio actual al path para importar mdulos
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

# Importar el chatbot
from rag_chatbot import RAGChatbot

# Configurar logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = Flask(__name__)
CORS(app)  # Habilitar CORS para el frontend

# Inicializar el chatbot
chatbot = None

def check_ollama_status():
    """Verificar el estado de Ollama"""
    try:
        response = requests.get("http://localhost:11434/api/tags", timeout=5)
        if response.status_code == 200:
            models = response.json().get('models', [])
            return {
                'status': 'running',
                'models': [model['name'] for model in models],
                'model_count': len(models)
            }
        else:
            return {'status': 'error', 'message': f'HTTP {response.status_code}'}
    except Exception as e:
        return {'status': 'error', 'message': str(e)}

def initialize_chatbot():
    """Inicializar el chatbot RAG"""
    global chatbot
    try:
        logger.info("Inicializando CodeHelperNET chatbot...")
        chatbot = RAGChatbot()
        logger.info("Chatbot inicializado exitosamente")
        return True
    except Exception as e:
        logger.error(f"Error inicializando chatbot: {e}")
        return False

@app.route('/health', methods=['GET'])
def health_check():
    """Endpoint de salud del servidor"""
    ollama_status = check_ollama_status()
    
    return jsonify({
        'status': 'healthy',
        'timestamp': datetime.now().isoformat(),
        'chatbot_ready': chatbot is not None,
        'ollama': ollama_status,
        'version': '2.0.0',
        'backend': 'Ollama + RAG'
    })

@app.route('/chat', methods=['POST'])
def chat():
    """Endpoint principal para el chat"""
    try:
        # Verificar que el chatbot est inicializado
        if chatbot is None:
            return jsonify({
                'error': 'Chatbot no inicializado',
                'message': 'El servidor est iniciando, por favor espera un momento.'
            }), 503

        # Obtener el mensaje del request
        data = request.get_json()
        if not data or 'message' not in data:
            return jsonify({
                'error': 'Mensaje requerido',
                'message': 'Debes enviar un mensaje en el campo "message"'
            }), 400

        user_message = data['message'].strip()
        if not user_message:
            return jsonify({
                'error': 'Mensaje vaco',
                'message': 'El mensaje no puede estar vaco'
            }), 400

        logger.info(f"Mensaje recibido: {user_message[:100]}...")

        # Procesar el mensaje con el chatbot
        response = chatbot.chat(user_message)
        
        logger.info(f"Respuesta generada: {len(response)} caracteres")

        return jsonify({
            'response': response,
            'timestamp': datetime.now().isoformat(),
            'backend': 'Ollama + RAG'
        })

    except Exception as e:
        logger.error(f"Error procesando mensaje: {e}")
        return jsonify({
            'error': 'Error interno del servidor',
            'message': 'Ocurri un error procesando tu mensaje. Por favor, intenta de nuevo.',
            'details': str(e)
        }), 500

@app.route('/ollama/status', methods=['GET'])
def ollama_status():
    """Endpoint para verificar el estado de Ollama"""
    status = check_ollama_status()
    return jsonify(status)

@app.route('/ollama/models', methods=['GET'])
def ollama_models():
    """Endpoint para listar modelos disponibles"""
    try:
        response = requests.get("http://localhost:11434/api/tags", timeout=5)
        if response.status_code == 200:
            models = response.json().get('models', [])
            return jsonify({
                'models': models,
                'count': len(models)
            })
        else:
            return jsonify({
                'error': 'No se pudo obtener la lista de modelos',
                'status_code': response.status_code
            }), 500
    except Exception as e:
        return jsonify({
            'error': 'Error conectando con Ollama',
            'message': str(e)
        }), 500

@app.route('/info', methods=['GET'])
def get_info():
    """Endpoint para obtener informacin del chatbot"""
    if chatbot is None:
        return jsonify({
            'error': 'Chatbot no inicializado'
        }), 503

    ollama_status = check_ollama_status()

    return jsonify({
        'name': 'CodeHelperNET',
        'description': 'Asistente especializado en C# y .NET con Ollama',
        'version': '2.0.0',
        'backend': 'Ollama + RAG',
        'ollama_status': ollama_status,
        'topics': [
            'C# Fundamentals',
            'ASP.NET Core',
            'Entity Framework',
            'Design Patterns',
            'Testing',
            'Security',
            'Performance',
            'Cloud Development',
            'Microservices',
            'DevOps'
        ],
        'documents_count': len(chatbot.collection.get()['documents']) if hasattr(chatbot, 'collection') else 0
    })

@app.route('/test', methods=['POST'])
def test_chat():
    """Endpoint de prueba para verificar el funcionamiento"""
    try:
        test_message = "Cmo crear un bucle for en C#?"
        logger.info("Ejecutando prueba con mensaje de ejemplo...")
        
        if chatbot is None:
            return jsonify({
                'error': 'Chatbot no inicializado'
            }), 503

        response = chatbot.chat(test_message)
        
        return jsonify({
            'test_message': test_message,
            'response': response,
            'response_length': len(response),
            'success': True,
            'timestamp': datetime.now().isoformat()
        })

    except Exception as e:
        logger.error(f"Error en prueba: {e}")
        return jsonify({
            'error': 'Error en prueba',
            'message': str(e),
            'success': False
        }), 500

@app.errorhandler(404)
def not_found(error):
    """Manejar rutas no encontradas"""
    return jsonify({
        'error': 'Endpoint no encontrado',
        'message': 'La ruta solicitada no existe'
    }), 404

@app.errorhandler(500)
def internal_error(error):
    """Manejar errores internos"""
    return jsonify({
        'error': 'Error interno del servidor',
        'message': 'Ocurri un error inesperado'
    }), 500

if __name__ == '__main__':
    # Inicializar el chatbot al arrancar
    if not initialize_chatbot():
        logger.error("No se pudo inicializar el chatbot. Saliendo...")
        sys.exit(1)

    # Verificar Ollama
    ollama_status = check_ollama_status()
    if ollama_status['status'] == 'running':
        logger.info(f"Ollama est ejecutndose con {ollama_status['model_count']} modelos")
    else:
        logger.warning(f"Ollama no est disponible: {ollama_status['message']}")

    # Configurar el servidor
    port = int(os.environ.get('PORT', 5000))
    debug = os.environ.get('FLASK_ENV') == 'development'
    
    logger.info(f"Iniciando servidor en puerto {port}")
    logger.info(f"Modo debug: {debug}")
    
    app.run(
        host='0.0.0.0',
        port=port,
        debug=debug,
        threaded=True
    ) 

Web Proxy Viewer  |  New URL  |  Original Page