
import subprocess
import logging

from delivery.models.execution import ExecutionResult, Execution

log = logging.getLogger(__name__)


class ExternalProgramService(object):
    """
    A service for running external programs
    """

    @staticmethod
    def run(cmd):
        """
        Run a process and do not wait for it to finish
        :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
        :return: A instance of Execution
        """
        log.debug("Running command: {}".format(" ".join(cmd)))
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE)
        return Execution(pid=p.pid, process_obj=p)

    @staticmethod
    def wait_for_execution(execution):
        """
        Wait for an execution to finish
        :param execution: instance of Execution
        :return: an ExecutionResult for the execution
        """
        out, err = execution.process_obj.communicate()
        status_code = execution.process_obj.wait()
        return ExecutionResult(out, err, status_code)

    @staticmethod
    def run_and_wait(cmd):
        """
        Run an external command and wait for it to finish
        :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
        :return: an ExecutionResult for the execution
        """
        execution = ExternalProgramService.run(cmd)
        return ExternalProgramService.wait_for_execution(execution)



from tornado.process import Subprocess
from tornado import gen

from subprocess import PIPE

from delivery.models.execution import ExecutionResult, Execution


class ExternalProgramService(object):
    """
    A service for running external programs
    """

    @staticmethod
    def run(cmd):
        """
        Run a process and do not wait for it to finish
        :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
        :return: A instance of Execution
        """
        p = Subprocess(cmd,
                       stdout=PIPE,
                       stderr=PIPE,
                       stdin=PIPE)
        return Execution(pid=p.pid, process_obj=p)

    @staticmethod
    @gen.coroutine
    def wait_for_execution(execution):
        """
        Wait for an execution to finish
        :param execution: instance of Execution
        :return: an ExecutionResult for the execution
        """
        status_code = yield execution.process_obj.wait_for_exit(raise_error=False)
        out = str(execution.process_obj.stdout.read())
        err = str(execution.process_obj.stderr.read())

        return ExecutionResult(out, err, status_code)

    @staticmethod
    def run_and_wait(cmd):
        """
        Run an external command and wait for it to finish
        :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
        :return: an ExecutionResult for the execution
        """
        execution = ExternalProgramService.run(cmd)
        return ExternalProgramService.wait_for_execution(execution)


Make ExternalProgramService use async process from tornado
Make ExternalProgramService use async process from tornado

  
- import subprocess
- import logging
+ 
+ from tornado.process import Subprocess
+ from tornado import gen
+ 
+ from subprocess import PIPE
  
  from delivery.models.execution import ExecutionResult, Execution
- 
- log = logging.getLogger(__name__)
  
  
  class ExternalProgramService(object):
      """
      A service for running external programs
      """
  
      @staticmethod
      def run(cmd):
          """
          Run a process and do not wait for it to finish
          :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
          :return: A instance of Execution
          """
-         log.debug("Running command: {}".format(" ".join(cmd)))
-         p = subprocess.Popen(cmd,
+         p = Subprocess(cmd,
-                              stdout=subprocess.PIPE,
+                        stdout=PIPE,
-                              stderr=subprocess.PIPE,
+                        stderr=PIPE,
-                              stdin=subprocess.PIPE)
+                        stdin=PIPE)
          return Execution(pid=p.pid, process_obj=p)
  
      @staticmethod
+     @gen.coroutine
      def wait_for_execution(execution):
          """
          Wait for an execution to finish
          :param execution: instance of Execution
          :return: an ExecutionResult for the execution
          """
-         out, err = execution.process_obj.communicate()
-         status_code = execution.process_obj.wait()
+         status_code = yield execution.process_obj.wait_for_exit(raise_error=False)
+         out = str(execution.process_obj.stdout.read())
+         err = str(execution.process_obj.stderr.read())
+ 
          return ExecutionResult(out, err, status_code)
  
      @staticmethod
      def run_and_wait(cmd):
          """
          Run an external command and wait for it to finish
          :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
          :return: an ExecutionResult for the execution
          """
          execution = ExternalProgramService.run(cmd)
          return ExternalProgramService.wait_for_execution(execution)
  
+ 
Make ExternalProgramService use async process from tornado
## Code Before:

import subprocess
import logging

from delivery.models.execution import ExecutionResult, Execution

log = logging.getLogger(__name__)


class ExternalProgramService(object):
    """
    A service for running external programs
    """

    @staticmethod
    def run(cmd):
        """
        Run a process and do not wait for it to finish
        :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
        :return: A instance of Execution
        """
        log.debug("Running command: {}".format(" ".join(cmd)))
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE)
        return Execution(pid=p.pid, process_obj=p)

    @staticmethod
    def wait_for_execution(execution):
        """
        Wait for an execution to finish
        :param execution: instance of Execution
        :return: an ExecutionResult for the execution
        """
        out, err = execution.process_obj.communicate()
        status_code = execution.process_obj.wait()
        return ExecutionResult(out, err, status_code)

    @staticmethod
    def run_and_wait(cmd):
        """
        Run an external command and wait for it to finish
        :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
        :return: an ExecutionResult for the execution
        """
        execution = ExternalProgramService.run(cmd)
        return ExternalProgramService.wait_for_execution(execution)

## Instruction:
Make ExternalProgramService use async process from tornado
## Code After:


from tornado.process import Subprocess
from tornado import gen

from subprocess import PIPE

from delivery.models.execution import ExecutionResult, Execution


class ExternalProgramService(object):
    """
    A service for running external programs
    """

    @staticmethod
    def run(cmd):
        """
        Run a process and do not wait for it to finish
        :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
        :return: A instance of Execution
        """
        p = Subprocess(cmd,
                       stdout=PIPE,
                       stderr=PIPE,
                       stdin=PIPE)
        return Execution(pid=p.pid, process_obj=p)

    @staticmethod
    @gen.coroutine
    def wait_for_execution(execution):
        """
        Wait for an execution to finish
        :param execution: instance of Execution
        :return: an ExecutionResult for the execution
        """
        status_code = yield execution.process_obj.wait_for_exit(raise_error=False)
        out = str(execution.process_obj.stdout.read())
        err = str(execution.process_obj.stderr.read())

        return ExecutionResult(out, err, status_code)

    @staticmethod
    def run_and_wait(cmd):
        """
        Run an external command and wait for it to finish
        :param cmd: the command to run as a list, i.e. ['ls','-l', '/']
        :return: an ExecutionResult for the execution
        """
        execution = ExternalProgramService.run(cmd)
        return ExternalProgramService.wait_for_execution(execution)

