Skip to content

Instantly share code, notes, and snippets.

@pre
Created September 7, 2017 09:55
Show Gist options
  • Save pre/67c04d0a64abc1929c9ef9ffd3c4469c to your computer and use it in GitHub Desktop.
Save pre/67c04d0a64abc1929c9ef9ffd3c4469c to your computer and use it in GitHub Desktop.
Run Python from Ruby, stream stdout to logs and print stderr as the exception message
require 'pty'
class PythonCmd
class ExecutionError < StandardError; end
attr_reader :file
def initialize(file, args = [])
@file = file
@args = args
end
def run!
stderr_reader, stderr_writer = IO.pipe
PTY.spawn('python3', @file, *@args, err: stderr_writer.fileno) do |stdout, _stdin, pid|
begin
stdout.sync
stdout.each { |line| Nephew::Application.logger.info line }
rescue Errno::EIO => e
Nephew::Application.logger.debug "Errno::EIO error, but this probably means
that the process has finished giving output: #{e.message}".squish
ensure
::Process.wait(pid)
stderr_writer.close
end
if $CHILD_STATUS.exitstatus.nonzero?
msg = <<-EOL.squish
Non-zero exit code: #{$CHILD_STATUS.exitstatus}: '#{stderr_reader.read}'
(file #{@file}, args #{@args})
EOL
raise ExecutionError, msg
end
end
rescue PTY::ChildExited => e
raise ExecutionError, e.message
ensure
stderr_reader.close
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment