Example #1
0
 def send_email(self, **kwargs):
     email = self._build_email(**kwargs)
     success = self._try_send(email)
     if not success:
         err_msg = 'Failed to send message with following args: ' + str(
             kwargs)
         raise EGCGError(err_msg)
Example #2
0
 def notify(self, msg):
     email = self.build_email(msg)
     success = self._try_send(email)
     if not success:
         err_msg = 'Failed to send message: ' + str(msg)
         if self.strict:
             raise EGCGError(err_msg)
         else:
             self.critical(err_msg)
Example #3
0
 def _job_finished(self):
     statuses = self._job_statuses()
     for s in statuses:
         if s in self.finished_statuses:
             pass
         elif s in self.unfinished_statuses:
             return False
         else:
             raise EGCGError('Bad job status: %s', s)
     return True
Example #4
0
 def join(self, timeout=None):
     # noinspection PyCallByClass
     Thread.join(self, timeout)
     if self.exception:
         self._stop()
         self.error(self.exception.__class__.__name__ + ': ' +
                    str(self.exception))
         raise EGCGError('Commands failed: ' + str(self.exit_statuses))
     self.info('Exit statuses: ' + str(self.exit_statuses))
     return sum(self.exit_statuses)
    def join(self, timeout=None):
        """
        Ensure that both the thread and the subprocess have finished, and return self.proc's exit status.
        :param int timeout: As Thread.join
        """
        super().join(timeout=timeout)
        if self.exception:
            self._stop()
            self.error('Encountered a %s error: %s', self.exception.__class__.__name__, self.exception)
            raise EGCGError('Command failed: ' + self.cmd) from self.exception

        return self.proc.wait()
Example #6
0
def find_all_fastq_pairs(location):
    """
    Return the results of find_all_fastqs as a list of fastq pair tuples. Assumes that fastq pairs come
    together from sorting by name.
    :param str location: Directory to search
    :return: Full paths to all fastq.gz files in the input dir, aggregated per pair
    :rtype: list[tuple[str, str]]
    """
    fastqs = find_all_fastqs(location)
    if len(fastqs) % 2 != 0:
        raise EGCGError('Expected even number of fastq files in %s, found %s' %
                        (location, len(fastqs)))
    fastqs.sort()
    return list(zip(*[iter(fastqs)] * 2))
    def test_notify_failure(self, mocked_log):
        self.notification_centre.subscribers = {
            'asana':
            Mock(notify=Mock(side_effect=EGCGError('Something broke'))),
            'email':
            Mock(notify=Mock(side_effect=ValueError('Something else broke')))
        }
        with self.assertRaises(EGCGError) as e:
            self.notification_centre.notify('a message', ('asana', 'email'))

        mocked_log.assert_called()
        assert str(e.exception) == (
            'Encountered the following errors during notification: '
            'EGCGError: Something broke, '
            'ValueError: Something else broke')
Example #8
0
    def join(self):
        """
        Set self.proc to a Popen and start.
        :rtype: tuple[bytes, bytes]
        :raises: EGCGError on any exception
        """
        try:
            out, err = self._process().communicate()
            for stream, emit in ((out, self.info), (err, self.error)):
                for line in stream.decode('utf-8').split('\n'):
                    emit(line)
            return self.proc.poll()

        except Exception as e:
            raise EGCGError('Command failed: ' + self.cmd) from e
Example #9
0
 def notify(self, msg, attachments=None):
     try:
         if self.email_template:
             self.email_sender.send_email(title=self.name,
                                          body=self._prepare_string(msg),
                                          attachments=attachments)
         else:
             self.email_sender.send_email(text_message=msg,
                                          attachments=attachments)
     except EGCGError:
         err_msg = 'Failed to send message: ' + str(msg)
         if self.strict:
             raise EGCGError(err_msg)
         else:
             self.critical(err_msg)
Example #10
0
    def add_job_array(self, *cmds):
        if self.parameters.get('jobs'):
            raise EGCGError(
                'Already written a job array - can only have one per script')

        if len(cmds) == 1:
            self.register_cmd(cmds[0])
        else:
            self._start_array()
            for idx, cmd in enumerate(cmds):
                self._register_array_cmd(
                    idx + 1,
                    cmd,
                    log_file=self.log_file +
                    str(idx + 1) if self.log_commands else None)
            self._finish_array()
            self.parameters['jobs'] = len(cmds)
Example #11
0
    def _build_email(self, **kwargs):
        """
        Create a MIMEText from plain text or Jinja2-formatted html and send by email. If attachments are provided, the
        message will be a MIMEMultipart containing the MimeText message plus MIMEApplication attachments.

        _build_email has two modes: plain text and html. The following keyword args are useable for both:
          - email_subject: (str) override the EmailSender subject
          - email_sender: (str) override the EmailSender sender
          - email_recipients: (list) override the EmailSender recipients
          - attachments: list of file paths to attach to the email

        In plain text mode:
          - text_message (str) is required and contains the plain text to send in the email
        In html mode:
          - email_template (str) can be user to override the EmailSender email_template
          - all other keyword args are passed to the Jinja template
        """
        email_template = kwargs.get('email_template', self.email_template)
        if email_template:
            content = jinja2.Template(open(email_template).read())
            text = MIMEText(content.render(**kwargs), 'html')
        elif 'text_message' in kwargs:
            text = MIMEText(kwargs.get('text_message'))
        else:
            raise EGCGError(
                'EmailSender needs either a text_message or an email template')
        if 'attachments' in kwargs and kwargs['attachments']:
            if isinstance(kwargs['attachments'], str):
                kwargs['attachments'] = [kwargs['attachments']]
            msg = MIMEMultipart()
            msg.attach(text)
            for attachment in kwargs['attachments']:
                with open(attachment, 'rb') as f:
                    part = MIMEApplication(f.read(), Name=basename(attachment))
                    part[
                        'Content-Disposition'] = 'attachment; filename="%s"' % basename(
                            attachment)
                    msg.attach(part)
        else:
            msg = text

        msg['Subject'] = kwargs.get('email_subject', self.subject)
        msg['From'] = kwargs.get('email_sender', self.sender)
        msg['To'] = COMMASPACE.join(
            kwargs.get('email_recipients', self.recipients))
        return msg
Example #12
0
def cluster_execute(*cmds, env=None, prelim_cmds=None, **cluster_config):
    """
    Execute commands on a compute cluster
    :param cmds:
    :param env: The kind of resource manager being run
    :param prelim_cmds: Any commands to execute before starting a job array
    :param cluster_config:
    :return: ClusterExecutor
    """
    env = env or cfg.query('executor', 'job_execution')
    if env == 'slurm':
        cls = SlurmExecutor
    else:
        raise EGCGError('Unknown execution environment: %s' % env)

    e = cls(*cmds, prelim_cmds=prelim_cmds, **cluster_config)
    e.start()
    return e
Example #13
0
    def notify(self, msg, subs):
        exceptions = []
        for s in subs:
            if s in self.subscribers:
                try:
                    self.subscribers[s].notify(msg)
                except Exception as e:
                    etype, value, tb = sys.exc_info()
                    stacktrace = ''.join(traceback.format_exception(etype, value, tb))
                    self.critical(stacktrace)
                    exceptions.append(e)
            else:
                self.debug('Tried to notify by %s, but no configuration present', s)

        if exceptions:
            raise EGCGError(
                'Encountered the following errors during notification: %s' % ', '.join(
                    '%s: %s' % (e.__class__.__name__, str(e))
                    for e in exceptions
                )
            )
Example #14
0
 def _submit_job(self):
     self.job_id = self._run_and_retry(cfg['executor']['qsub'] + ' ' +
                                       self.writer.script_name)
     if self.job_id is None:
         raise EGCGError('Job submission failed')
Example #15
0
 def get_species_name(query_species):
     raise EGCGError('Could not import egcg_core.ncbi.get_species_name - sqlite3 seems to be unavailable.')