def test_send_single_email_object_no_backend_kwargs(self): """ It should send email with backend_kwargs not provided. """ msg = mail.EmailMessage() tasks.send_email(msg) self.assertEqual(len(mail.outbox), 1) # we can't compare them directly as it's converted into a dict # for JSONification and then back. Compare dicts instead. self.assertEqual(email_to_dict(msg), email_to_dict(mail.outbox[0]))
def test_send_single_email_dict(self): """ It should accept and send a single EmailMessage dict. """ msg = mail.EmailMessage() tasks.send_email(email_to_dict(msg), backend_kwargs={}) self.assertEqual(len(mail.outbox), 1) # we can't compare them directly as it's converted into a dict # for JSONification and then back. Compare dicts instead. self.assertEqual(email_to_dict(msg), email_to_dict(mail.outbox[0]))
def test_send_multiple_email_dicts(self): """ It should accept and send a list of EmailMessage dicts. """ N = 10 msgs = [mail.EmailMessage() for i in range(N)] tasks.send_emails(msgs, backend_kwargs={}) self.assertEqual(len(mail.outbox), N) for i in range(N): self.assertEqual(email_to_dict(msgs[i]), email_to_dict(mail.outbox[i]))
def send_emails(messages, backend_kwargs=None, **kwargs): # backward compat: handle **kwargs and missing backend_kwargs combined_kwargs = {} if backend_kwargs is not None: combined_kwargs.update(backend_kwargs) combined_kwargs.update(kwargs) # backward compat: catch single object or dict if isinstance(messages, (EmailMessage, dict)): messages = [messages] # make sure they're all dicts messages = [email_to_dict(m) for m in messages] conn = get_connection(backend=settings.CELERY_EMAIL_BACKEND, **combined_kwargs) conn.open() messages_sent = 0 for message in messages: try: sent = conn.send_messages([dict_to_email(message)]) if sent is not None: messages_sent += sent logger.debug("Successfully sent email message to %r.", message['to']) except Exception as e: # Not expecting any specific kind of exception here because it # could be any number of things, depending on the backend logger.warning("Failed to send email message to %r, retrying. (%r)", message['to'], e) send_emails.retry([[message], combined_kwargs], exc=e, throw=False) conn.close() return messages_sent
def send_messages(self, email_messages): result_tasks = [] for chunk in chunked(email_messages, settings.CELERY_EMAIL_CHUNK_SIZE): chunk_messages = [email_to_dict(msg) for msg in chunk] result_tasks.append( send_emails.delay(chunk_messages, self.init_kwargs)) return result_tasks
def send_messages(self, email_messages): result_tasks = [] task_kwargs = {} if self.queue is not None: task_kwargs['queue'] = self.queue messages = [email_to_dict(msg) for msg in email_messages] for chunk in chunked(messages, settings.CELERY_EMAIL_CHUNK_SIZE): result_tasks.append( send_emails.apply_async( args=[chunk], kwargs={'backend_kwargs': self.init_kwargs}, **task_kwargs)) return result_tasks
def test_send_multiple_emails(self): N = 10 msgs = [mail.EmailMessage(subject="msg %d" % i) for i in range(N)] tasks.send_emails([email_to_dict(msg) for msg in msgs], backend_kwargs={'foo': 'bar'}) # Assert that only "odd"/good messages have been sent. self.assertEqual(len(mail.outbox), 5) self.assertEqual( [msg.subject for msg in mail.outbox], ["msg 1", "msg 3", "msg 5", "msg 7", "msg 9"] ) # Assert that "even"/bad messages have been requeued, # one retry task per bad message. self.assertEqual(len(self._retry_calls), 5) odd_msgs = [msg for idx, msg in enumerate(msgs) if even(idx)] for msg, (args, kwargs) in zip(odd_msgs, self._retry_calls): retry_args = args[0] self.assertEqual(retry_args, [[email_to_dict(msg)], {'foo': 'bar'}]) self.assertTrue(isinstance(kwargs.get('exc'), RuntimeError)) self.assertFalse(kwargs.get('throw', True))
def test_send_multiple_emails(self): N = 10 msgs = [mail.EmailMessage(subject="msg %d" % i) for i in range(N)] tasks.send_emails([email_to_dict(msg) for msg in msgs], backend_kwargs={'foo': 'bar'}) # Assert that only "odd"/good messages have been sent. self.assertEqual(len(mail.outbox), 5) self.assertEqual([msg.subject for msg in mail.outbox], ["msg 1", "msg 3", "msg 5", "msg 7", "msg 9"]) # Assert that "even"/bad messages have been requeued, # one retry task per bad message. self.assertEqual(len(self._retry_calls), 5) odd_msgs = [msg for idx, msg in enumerate(msgs) if even(idx)] for msg, (args, kwargs) in zip(odd_msgs, self._retry_calls): retry_args = args[0] self.assertEqual(retry_args, [[email_to_dict(msg)], { 'foo': 'bar' }]) self.assertTrue(isinstance(kwargs.get('exc'), RuntimeError)) self.assertFalse(kwargs.get('throw', True))
def send_messages(self, email_messages): result_tasks = [] task_kwargs = {} if self.queue is not None: task_kwargs['queue'] = self.queue messages = [email_to_dict(msg) for msg in email_messages] for chunk in chunked(messages, settings.CELERY_EMAIL_CHUNK_SIZE): result_tasks.append( send_emails.apply_async( args=[chunk], kwargs={'backend_kwargs': self.init_kwargs}, **task_kwargs ) ) return result_tasks
def send_messages(self, email_messages): if not email_messages: return 0 with self._lock: session_created = self.open() if not self.session or session_created is None: # We failed silently on open(). # Trying to send would be pointless. return 0 num_sent = 0 for message in email_messages: if self._send_email_rest_api(email_to_dict(message)): num_sent += 1 if session_created: self.close() return num_sent
def send_emails(messages, backend_kwargs=None, **kwargs): # backward compat: handle **kwargs and missing backend_kwargs combined_kwargs = {} if backend_kwargs is not None: combined_kwargs.update(backend_kwargs) combined_kwargs.update(kwargs) # backward compat: catch single object or dict if isinstance(messages, (EmailMessage, dict)): messages = [messages] # make sure they're all dicts messages = [email_to_dict(m) for m in messages] conn = get_connection(backend=settings.CELERY_EMAIL_BACKEND, **combined_kwargs) try: conn.open() except Exception: logger.exception("Cannot reach CELERY_EMAIL_BACKEND %s", settings.CELERY_EMAIL_BACKEND) messages_sent = 0 for message in messages: try: sent = conn.send_messages([dict_to_email(message)]) if sent is not None: messages_sent += sent logger.debug("Successfully sent email message to %r.", message['to']) except Exception as e: # Not expecting any specific kind of exception here because it # could be any number of things, depending on the backend logger.warning( "Failed to send email message to %r, retrying. (%r)", message['to'], e) send_emails.retry([[message], combined_kwargs], exc=e, throw=False) conn.close() return messages_sent
def test_uses_correct_backend(self): """ It should use the backend configured in CELERY_EMAIL_BACKEND. """ TracingBackend.called = False msg = mail.EmailMessage() tasks.send_email(email_to_dict(msg), backend_kwargs={}) self.assertTrue(TracingBackend.called)
def test_backend_parameters_kwargs(self): """ It should pass on kwargs specified as keyword params. """ TracingBackend.kwargs = None msg = mail.EmailMessage() tasks.send_email(email_to_dict(msg), foo='bar') self.assertEqual(TracingBackend.kwargs.get('foo'), 'bar')
def test_email_to_dict_extra_attrs(self): msg = mail.EmailMessage() msg.extra_attribute = {'name': 'val'} self.assertEquals( email_to_dict(msg)['extra_attribute'], msg.extra_attribute)
def test_backend_parameters(self): """ It should pass kwargs like username and password to the backend. """ TracingBackend.kwargs = None msg = mail.EmailMessage() tasks.send_email(email_to_dict(msg), backend_kwargs={'foo': 'bar'}) self.assertEqual(TracingBackend.kwargs.get('foo'), 'bar')
def check_json_of_msg(self, msg): serialized = json.dumps(email_to_dict(msg)) self.assertEqual(email_to_dict(dict_to_email(json.loads(serialized))), email_to_dict(msg))
def test_dict_to_email_extra_attrs(self): msg_dict = email_to_dict(mail.EmailMessage()) msg_dict['extra_attribute'] = {'name': 'val'} self.assertEquals(email_to_dict(dict_to_email(msg_dict)), msg_dict)
def test_email_to_dict_extra_attrs(self): msg = mail.EmailMessage() msg.extra_attribute = {'name': 'val'} self.assertEquals(email_to_dict(msg)['extra_attribute'], msg.extra_attribute)
def check_json_of_msg(self, msg): serialized = json.dumps(email_to_dict(msg)) self.assertEqual( email_to_dict(dict_to_email(json.loads(serialized))), email_to_dict(msg))
def send_messages(self, email_messages): dict_messages = [email_to_dict(msg) for msg in email_messages] TASKS[self.config['name']].delay(dict_messages, **self.task_kwargs) return len(email_messages)
def send_messages(self, email_messages): result_tasks = [] messages = [email_to_dict(msg) for msg in email_messages] for chunk in chunked(messages, settings.CELERY_EMAIL_CHUNK_SIZE): result_tasks.append(send_emails.delay(chunk, self.init_kwargs)) return result_tasks