Вопрос состоит из нескольких частей:
1) Для запуска
Docker образов из
python я решил использовать библиотеку
subprocess.
main.py:
import platform
from subprocess import call, Popen, PIPE
class Docker:
def __init__(self):
self._docker_compose_up()
self.current_path_command = self._get_current_path_command()
self.runner_images = {
'cpp': 'compilers_cpp_runner',
'python': 'compilers_python_runner'
}
@staticmethod
def _get_current_path_command():
if platform.system() == 'Windows':
return '%CD%'
return '$(pwd)'
@staticmethod
def _docker_compose_up():
call('docker-compose up -d --build --force-recreate --renew-anon-volumes')
@staticmethod
def docker_compose_down():
call('docker-compose down')
def run_code(self, filename, language):
image = self.runner_images[language]
command = f'docker run -i -v {self.current_path_command}/temp:/temp --env FILENAME={filename} {image}'
result = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, encoding='utf-8')
output, error = result.communicate(input='12 2')
return {'output': output, 'error': error}
docker = Docker()
print(docker.run_code('hello_world', 'cpp'))
print(docker.run_code('hello_world', 'python'))
docker.docker_compose_down()
Пояснение к коду:
Сначала я запускаю
docker-compose.yml
, который лежит в той же директории, что и python файл.
Потом определяю команду для получения текущего местоположения в файловой системе (Если ОС -
Windows, то это
%CD%, если что-то другое, то
$(pwd))
Потом запускаю образ (метод
run_code), передавая туда имя файла и язык.
Dockerfile для python:
FROM python
ARG FILENAME_ARG
ENV FILENAME = $FILENAME_ARG
CMD export TIMEFORMAT='%3R'
CMD bash -c "time python temp/${FILENAME}.py"
В результате выполнения функции я получаю словарь с ключами
output и
error:
{'output': '10\n', 'error': '\nreal\t0m0.071s\nuser\t0m0.053s\nsys\t0m0.011s\n'}
Отформатированный вывод:
real 0m0.072s
user 0m0.061s
sys 0m0.001s
Почему время выполнения улетает в
error, а не в
output?
2) Нормально ли я реализовываю это, или существуют какие-то другие способы сделать все правильнее и красивее?
3) Как сделать так, чтобы выводилось только real время в секундах (команда
CMD export TIMEFORMAT='%3R'
не сработала)