How can I send E-Mails through python django frequently with a cronjob?

I try to run a function in django every 5 minutes. For this I user the django-crontab package. The function which should run, checks for some conditions in the database and if they are met, sends an e-mail to the user of the app.

I have django 4 running on my linux ubuntu 20.04 server. I added the cronjob via python3 manage.py crontab add (in activated virtual environment). But then I wondered why the cronjob is not running. I tried to execute the job by hand and it worked.

I think the problem boils down to this: When I'm in the activated virtual environment and run the crontab with "python3 manage.py crontab run " it works. But when I run it outside of the virtual environment I get the following error:

Failed to complete cronjob at ('*/5 * * * *', 'evaluation_tool.scripts.cron.send_mail_if_classeval_ended')
Traceback (most recent call last):
  File "/var/www/amadeus/lib/python3.10/site-packages/django_crontab/crontab.py", line 145, in run_job
    func(*job_args, **job_kwargs)
  File "/var/www/amadeus/evaluation_tool/scripts/cron.py", line 12, in send_mail_if_classeval_ended
    send_mail_time_over_class_evaluation(class_evaluation=class_evaluation.pk,
  File "/var/www/amadeus/evaluation_tool/scripts/email_handler.py", line 122, in send_mail_time_over_class_evaluation
    send_falko_mail("AMADEUS Evaluation abgeschlossen", message, to_email_address)
  File "/var/www/amadeus/evaluation_tool/scripts/email_handler.py", line 34, in send_falko_mail
    msg.send(fail_silently=False)
  File "/var/www/amadeus/lib/python3.10/site-packages/django/core/mail/message.py", line 298, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/var/www/amadeus/lib/python3.10/site-packages/django/core/mail/backends/smtp.py", line 124, in send_messages
    new_conn_created = self.open()
  File "/var/www/amadeus/lib/python3.10/site-packages/django/core/mail/backends/smtp.py", line 87, in open
    self.connection.starttls(
  File "/usr/lib/python3.10/smtplib.py", line 769, in starttls
    self.ehlo_or_helo_if_needed()
  File "/usr/lib/python3.10/smtplib.py", line 611, in ehlo_or_helo_if_needed
    if not (200 <= self.ehlo()[0] <= 299):
  File "/usr/lib/python3.10/smtplib.py", line 451, in ehlo
    self.putcmd(self.ehlo_msg, name or self.local_hostname)
  File "/usr/lib/python3.10/smtplib.py", line 378, in putcmd
    self.send(f'{s}{CRLF}')
  File "/usr/lib/python3.10/smtplib.py", line 365, in send
    raise SMTPServerDisconnected('please run connect() first')
smtplib.SMTPServerDisconnected: please run connect() first

Why is the connection to the SMTP Server working in the activated virtual environment but not outside, which is the desired way using a cronjob?

To send emails through Python Django frequently with a cronjob, you can do the following:

  1. Create a Django management command: In your Django project, create a management command that sends the emails you want to send. You can do this by creating a management command using the Command class from django.core.management.base.
  2. Schedule the management command: Once you have created the management command, you can schedule it to run at regular intervals using a cron job. To do this, you will need to edit the crontab file on your server and add an entry for your management command. The crontab entry should specify the frequency at which you want the command to run and the path to the management command.

Here is an example of a crontab entry that runs a management command named send_emails every hour:

0 * * * * /path/to/project/manage.py send_emails
  • Test the cron job: After you have added the crontab entry, you should test that the cron job is working correctly by manually running the management command and verifying that the emails are sent as expected.

It's important to note that you will need to ensure that your Django project is properly configured to send emails. This may involve setting up an email server or using a third-party email service such as Gmail or Sendgrid.

I found the problem.

I set certain environment variables for SMTP Host, User and Password. But crontab cannot access them. So there are two possibilities:

  1. Add them directly to the head of cron file via crontab -e
EMAIL_HOST=XXX
EMAIL_HOST_USER=XXX
EMAIL_PASS=XXX
  1. Add them via a django-crontab argument in settings.py:
CRONTAB_COMMAND_PREFIX = 'EMAIL_HOST=XXX\nEMAIL_HOST_USER=XXX\nEMAIL_PASS=XXX'
Back to Top