2

I have two demos, the first does not work, but the second works. I want to understand why.

Error:

raise err
error: [Errno 111] Connection refused

__init__.py

mail = Mail()

MAIL_SERVER = 'smtp.gmail.com'
MAIL_PORT = 465
MAIL_USE_TLS = False
MAIL_USE_SSL= True
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])

    mail.init_app(app)
    app.debug = True

    return app

app = create_app(os.getenv('FLASK_CONFIG') or 'default')

views.py

from ..mymail import mmail

mmail();

mymail.py

from flask.ext.mail import Message
from . import mail

def mmail():
    msg = Message(
      'Hello',
       sender='user@gmail.com',
       recipients=
       ['xxxxxxxxxx@hotmail.com'])
    msg.body = "This is the email body"
    mail.send(msg)
    return "Sent"

What is strange, this example will work correctly:

from flask.ext.mail import Mail, Message
import os

DEBUG = True

MAIL_SERVER='smtp.gmail.com'
MAIL_PORT=465
MAIL_USE_TLS = False
MAIL_USE_SSL= True
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(__name__)
    mail = Mail(app)

    msg = Message(
      'Hello',
       sender='user@gmail.com',
       recipients=
       ['xxxxxxxxxx@hotmail.com'])
    msg.body = "This is the email body"
    mail.send(msg)
    return "Sent"

app = create_app(os.getenv('FLASK_CONFIG') or 'default')

So, what is the problem?

user455318
  • 3,280
  • 12
  • 41
  • 66

1 Answers1

3

The issue here is that you are not comparing apples to apples.

  • In the non-working example you configure your application with values from an unspecified dictionary-like object named config passing in the key found in the environment variable named FLASK_CONFIG (falling back to "default" if FLASK_CONFIG is not defined).

    app.config.from_object(config[config_name])
    
  • In the working example you configure your application from the uppercase names defined in the current module:

    app.config.from_object(__name__)
    # config_name is ignored
    

Whatever key is being passed into the non-working example is providing an object which does not have the credentials which you want to use for Mail.

You can either:

  • Configure your application via your defaults first and then load overrides from your config dictionary:

    app.config.from_object(__name__)
    app.config.from_object(config[config_name])
    
  • Or ensure that your config has the correct values:

    config = {
        "development": SomeDevConfig,
        "staging": SomeStagingConfig,
        "production": SomeProductionConfig,
        "default": SomeDefaultConfig
    }
    
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293