from flask import Flask, request, jsonify import subprocess import os import tempfile import uuid import time import logging from flask_cors import CORS app = Flask(__name__) CORS(app) # Habilitar CORS para todas las rutas # Configuración de logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Directorio temporal para los archivos de código TEMP_DIR = os.path.join(tempfile.gettempdir(), '42coderunner') os.makedirs(TEMP_DIR, exist_ok=True) # Tiempo máximo de ejecución (en segundos) MAX_EXECUTION_TIME = 5 @app.route('/api/execute', methods=['POST']) def execute_code(): try: # Obtener el código C del request data = request.get_json() if not data or 'code' not in data: return jsonify({'success': False, 'error': 'No se proporcionó código'}), 400 code = data['code'] # Crear un ID único para este trabajo job_id = str(uuid.uuid4()) # Crear archivos temporales para el código y la salida code_file = os.path.join(TEMP_DIR, f"{job_id}.c") executable = os.path.join(TEMP_DIR, f"{job_id}.exe") # Guardar el código en un archivo temporal with open(code_file, 'w') as f: f.write(code) # Compilar el código logger.info(f"Compilando código para job {job_id}") compile_process = subprocess.run( ['gcc', code_file, '-o', executable], capture_output=True, text=True ) # Verificar si la compilación fue exitosa if compile_process.returncode != 0: return jsonify({ 'success': False, 'error': compile_process.stderr }) # Ejecutar el código compilado logger.info(f"Ejecutando código para job {job_id}") try: start_time = time.time() run_process = subprocess.run( [executable], capture_output=True, text=True, timeout=MAX_EXECUTION_TIME ) execution_time = time.time() - start_time # Preparar la respuesta result = { 'success': run_process.returncode == 0, 'output': run_process.stdout, 'error': run_process.stderr, 'execution_time': execution_time } except subprocess.TimeoutExpired: result = { 'success': False, 'error': f'La ejecución excedió el tiempo límite de {MAX_EXECUTION_TIME} segundos' } # Limpiar archivos temporales try: os.remove(code_file) if os.path.exists(executable): os.remove(executable) except Exception as e: logger.error(f"Error al limpiar archivos temporales: {e}") return jsonify(result) except Exception as e: logger.error(f"Error inesperado: {e}") return jsonify({'success': False, 'error': f'Error interno del servidor: {str(e)}'}), 500 @app.route('/api/health', methods=['GET']) def health_check(): # Verificar que el directorio temporal existe temp_dir_exists = os.path.exists(TEMP_DIR) # Verificar que podemos compilar código C compiler_available = True try: subprocess.run(['gcc', '--version'], capture_output=True, check=True) except (subprocess.SubprocessError, FileNotFoundError): compiler_available = False return jsonify({ 'status': 'ok', 'timestamp': time.time(), 'environment': { 'temp_dir': temp_dir_exists, 'compiler': compiler_available } }) if __name__ == '__main__': port = int(os.environ.get('PORT', 5000)) app.run(host='0.0.0.0', port=port)