-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode_execution.py
More file actions
138 lines (117 loc) · 4.73 KB
/
Copy pathcode_execution.py
File metadata and controls
138 lines (117 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# code_execution.py (Updated Version)
import subprocess
import tempfile
import os
import json
from datetime import datetime
import time
from flask import Blueprint, request, jsonify, current_app
from models import CodingAssignment
from database import db_session
def execute_code(source_code, language, test_input, timeout=5, memory_limit=512):
"""Executes code with security constraints and test case validation"""
result = {
'success': False,
'output': '',
'error': '',
'metrics': {
'execution_time': 0,
'memory_used': 0,
'cpu_usage': 0
},
'timestamp': datetime.utcnow().isoformat()
}
try:
with tempfile.TemporaryDirectory() as temp_dir:
file_ext = {
'python': 'py',
'javascript': 'js',
'java': 'java'
}.get(language, 'txt')
file_path = os.path.join(temp_dir, f'solution_{os.urandom(8).hex()}.{file_ext}')
with open(file_path, 'w') as f:
f.write(source_code)
commands = {
'python': ['python', file_path],
'javascript': ['node', file_path],
'java': ['javac', file_path, '&&', 'java', '-cp', temp_dir, 'Solution']
}[language]
# Prepare input - ensure proper formatting
input_data = test_input
if not input_data.endswith('\n'):
input_data += '\n'
start_time = time.time()
process = subprocess.run(
' '.join(commands),
input=input_data, # Remove .encode() here
shell=True,
capture_output=True,
text=True, # Keep text=True for string handling
timeout=timeout
)
end_time = time.time()
elapsed_time = end_time - start_time
result.update({
'output': process.stdout.strip(),
'error': process.stderr,
'success': process.returncode == 0,
'metrics': {
'execution_time': round(elapsed_time, 2),
'memory_used': 0,
'cpu_usage': 0
}
})
except subprocess.TimeoutExpired as e:
end_time = time.time()
result['error'] = f'Timeout after {timeout} seconds'
result['metrics']['execution_time'] = round(end_time - start_time, 2)
except Exception as e:
result['error'] = str(e)
return result
execution_bp = Blueprint('execution', __name__)
@execution_bp.route('/api/execute-code', methods=['POST'])
@execution_bp.route('/api/execute-code', methods=['POST'])
def execute_code_endpoint():
"""Handle both single execution and test case runs"""
data = request.json
current_app.logger.info(f"Execution request: {data.keys()}")
# Single code execution (Run Code button)
if 'test_input' in data:
result = execute_code(
source_code=data.get('code'),
language=data.get('language'),
test_input=data.get('test_input', '') + "\n",
timeout=data.get('timeout', 5),
memory_limit=data.get('memory_limit', 512)
)
return jsonify(result)
# Visible test execution (Run Tests button)
if 'assignment_id' in data:
try:
assignment = db_session.query(CodingAssignment).get(data['assignment_id'])
if not assignment:
return jsonify({'error': 'Assignment not found'}), 404
# Execute only visible test cases
results = []
for test_case in assignment.test_cases:
exec_result = execute_code(
source_code=data['code'],
language=data['language'],
test_input=f"{test_case['input']}\n",
timeout=assignment.time_limit_seconds,
memory_limit=assignment.memory_limit_mb
)
passed = (exec_result['output'].strip() ==
test_case['expected_output'].strip())
results.append({
'test_id': test_case['id'],
'passed': passed,
'output': exec_result['output'],
'error': exec_result['error'],
'execution_time': exec_result['metrics']['execution_time']
})
return jsonify({'visible': results})
except Exception as e:
current_app.logger.error(f"Execution error: {str(e)}")
return jsonify({'error': 'Internal server error'}), 500
return jsonify({'error': 'Invalid request format'}), 400