Forums

Sending Email From Django App Using Zoho Mail

I have a paid account on PythonAnywhere running single Django web app.

Everything is working well except that I can't send email from the webapp via smtp.zoho.com The configuration works well on localhost and also on other web apps running on another host but can't figure out why same configuration isn't working on Pythonanywhere.

Sample configuration below:

DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL')
EMAIL_HOST = os.environ.get('EMAIL_HOST') # "smtppro.zoho.com" for org account
EMAIL_PORT = os.environ.get('EMAIL_PORT') # 587 for TLS
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD')
EMAIL_USE_TLS = False
EMAIL_USE_SSL = True

Are you getting any errors?

Am not getting errors but the logs shows that the email was composed and being logged.

Which is why am wondering if PA firewall is blocking the actual sending.

Were you looking at your web app's error log?

I have checked all the error logs including the recycled logs.

I noticed that the From Email option is being removed causing the email sending to fail. I have even hardcorded it into the email sending function yet not success.

I have also tried sending email using same function via Django shell and it works. I can't seem to figure out why PA removes Email From field which I believe is the reason the email is not being sent.

This is what the log shows:

Content-Type: multipart/alternative;#012 boundary="===============7974333680965857746=="#012MIME-Version: 1.0#012Subject: Testing After Changes#012From: None#012To: assetstrade001@gmail.com#012Date: Sun, 18 Sep 2022 16:14:28 -0000#012Message-ID: <166351766855.5.11861546650291297417@localhost>#012#012--===============7974333680965857746==#012Content-Type: text/plain; charset="utf-8"#012MIME-Version: 1.0#012Content-Transfer-Encoding: 7bit#012#012Testing the email sending function after hardcording Default_From_Email#012--===============7974333680965857746==#012Content-Type: text/html; charset="utf-8"#012MIME-Version: 1.0#012Content-Transfer-Encoding: 7bit#012#012#012<div class="container">#012    <style>#012        main.assets-email {#012            max-width: 1000px;#012            font-size: 18px;#012        }#012        main.assets-email div.img-responsive {#012            width: 100%;#012        }#012        main.assets-email div.img-responsive img {#012            width: 100%;#012            height: auto;#012        }#012        main. A
2022-09-18 16:14:28 -------------------------------------------------------------------------------

I sincerely believes that From: None from above log is the reason the send fails.

Are you sure that you have DEFAULT_FROM_EMAIL set in your environment?

@glenn all the environment variables related to email sending are properly set.

The email below shows outputs from running Django shell which you can see the settings being imported from Django's configuration file. You can also see that I used the shell to send 2 emails each from a different function defined in utils.py file that I created. Result of Django Shell Console

The second image is evidence proving that the emails sent from Django shell actually goes through. Prove that emails are being sent

Then, this third image shows server error when I try to send the mail from a page on the website. As I stated in previous comment, DEFAULT_FROM_EMAIL is showing as None which is weird considering that same configuration file and sending function is been used in all scenarios. Server Log

NOTE: I am not passing same configurations/code/views work from my webpages in localhost and on another server running somewhere else than PA.

THOUGHTS: Why is DEFAULT_FROM_EMAIL None when it is obvious that it wasn't, by referencing it via Django settings file?

What code do you have in your settings.py to set the DEFAULT_FROM_EMAIL? Are you getting it from the environment, perhaps? If so, what setup have you done to make sure that it is in the environment in your running website code?

...

I kept working through the code and later hardcoded the settings which made the email sent from the live site start working.

I was going to blame the issue on python-dotenv but on a second thought, same python-dotenv loaded the environment variables when I run the Django shell.

At this moment, the emails are being sent but I still can't conclude what was causing the failure.

If you let us know what code you're using to make python-dotenv load stuff, perhaps we can spot something in there?

I have below settings:

from dotenv import load_dotenv

load_dotenv()

DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL')
EMAIL_HOST = os.environ.get('EMAIL_HOST')
EMAIL_PORT = os.environ.get('EMAIL_PORT')
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD')

Maybe try to run load_dotenv() in the python console and then check how your os.environ look like. Then, if it is not what you want, check your .env file if you try to set some variables to some values that have special character that are not escaped or in quotes.

I already confirmed in one of my comments above that the entire configurations from the ".env" is being loaded successfully if I run python3 manage.py shell. In the shell, if I do from django.conf import settings, I can access all the variables and they are all perfect.

What beats my imagination is why it can't load when I restart the server via the web dashboard whilst it loads properly from every other source. Including on other servers elsewhere than PA.

Do you load the .env file in the uwsgi file? Have a look at this help page for details.

This really must be the issue because I loaded it right from settings.py and not anywhere else. That being the reason it is not available to the worker process even when it is for others.

I will try loading from uwsgi file and feed you back.

Let us know.