forked from data-8/gofer_service
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrade_assignment.py
56 lines (50 loc) · 1.98 KB
/
grade_assignment.py
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
import asyncio
import async_timeout
async def grade_assignment(submission, section='3', assignment='lab01'):
if "hw" in assignment:
assignment_container_path_template = '/srv/repo/materials/x19/hw/{section}/{assignment}/{assignment}.ipynb'
else:
assignment_container_path_template = '/srv/repo/materials/x19/lab/{section}/{assignment}/{assignment}.ipynb'
grader_image = 'gofer'
command = [
'docker', 'run',
'--rm',
'-m', '2G',
'-i',
'--net=none',
grader_image,
"/srv/repo/grading/containergrade.bash",
assignment_container_path_template.format(section=section, assignment=assignment)
]
process = await asyncio.create_subprocess_exec(
*command,
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
with open(submission) as f:
content = f.read().encode('utf-8')
try:
async with async_timeout.timeout(300):
stdout, stderr = await process.communicate(content)
except asyncio.TimeoutError:
print(f'Grading timed out for {submission}')
return False
for line in stderr.decode('utf-8').split('\n'):
if line.strip() == '':
# Ignore empty lines
continue
if 'Killed' in line:
# Our container was killed, so let's just skip this one
return False
if "warning" not in line.lower():
print(line)
raise Exception("Found unrecognized output in stderr from {}, halting, line was {}".format(' '.join(command), line))
lines = stdout.decode("utf-8").strip().split("\n")
# print(lines)
grade = float(lines[-1])
return grade
if __name__ == '__main__':
loop = asyncio.get_event_loop()
task = loop.create_task(grade_assignment())
loop.run_until_complete(task)