Reputation: 11049
I am building a simple contact page using Flask and Flask-Mail. I built the app following this tutorial - Add a contact page - and now when I try to send the message I receive the eror gaierror: [Errno -2] Name or service not known
. I have been googling the error for a while and can't find any similar examples on line. I can't even figure out what name or service it can't find.
The traceback page will let me expand a row and execute some Python code. It provides a dump()
function that will show me all the variables and can be called on objects to see their info if that will help.
routes.py :
from forms import ContactForm
from flask.ext.mail import Message, Mail
mail = Mail()
app = Flask(__name__)
app.secret_key = 'development key'
app.config['MAIL_SERVER'] = 'smtp.google.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'email'
app.config['MAIL_PASSWORD'] = 'email'
mail.init_app(app)
@app.route('/contact', methods=['GET', 'POST'])
def contact():
form = ContactForm()
if request.method == 'POST':
if not form.validate():
the form:
from flask.ext.wtf import Form, validators
from wtforms.fields import TextField, TextAreaField, SubmitField
import wtforms
class ContactForm(Form):
name = TextField("Name", [wtforms.validators.Required('Please enter your name')])
email = TextField("Email", [wtforms.validators.Required('Please enter your email'), wtforms.validators.Email()])
subject = TextField("Subject", [wtforms.validators.Required('Please enter a subject')])
message = TextAreaField("Message", [wtforms.validators.Required('Please enter a message')])
submit = SubmitField("Send")
flash('All fields are required.')
return render_template('contact.html', form=form)
else:
msg = Message(form.subject.data, sender='[email protected]', recipients=['[email protected]'])
msg.body = """From: %s <%s> %s""" % (form.name.data, form.email.data, form.message.data)
mail.send(msg)
return render_template('contact.html', success=True)
elif request.method == 'GET':
return render_template('contact.html', form=form)
the traceback:
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/ian/PycharmProjects/flaskapp/app/routes.py", line 39, in contact
mail.send(msg)
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask_mail.py", line 415, in send
with self.connect() as connection:
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask_mail.py", line 123, in __enter__
self.host = self.configure_host()
File "/home/ian/PycharmProjects/flaskapp/lib/python2.7/site-packages/flask_mail.py", line 135, in configure_host
host = smtplib.SMTP_SSL(self.mail.server, self.mail.port)
File "/usr/lib/python2.7/smtplib.py", line 776, in __init__
SMTP.__init__(self, host, port, local_hostname, timeout)
File "/usr/lib/python2.7/smtplib.py", line 249, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python2.7/smtplib.py", line 309, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python2.7/smtplib.py", line 781, in _get_socket
new_socket = socket.create_connection((host, port), timeout)
File "/usr/lib/python2.7/socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno -2] Name or service not known
Upvotes: 1
Views: 2440
Reputation: 7328
OK. I know that this question is 4 years old, but here is my solution. There is a BUG. You just need to have the configuration parameters added to the flask app after app.config.from_object.
from config import config
app.config.from_object(config[config_name])
config[config_name].init_app(app)
app.config.update( DEBUG=True, MAIL_SERVER='smtp.gmail.com',
MAIL_PORT=587, MAIL_USE_SSL=False, MAIL_USE_TLS=True, MAIL_USERNAME = '[email protected]')
inside config.py I have these two parameters:
MAIL_PASSWORD = 'password'
MAIL_DEFAULT_SENDER = '[email protected]'
# IMPORTANT - the rest of the mail parameters are set inside the __init__.py because they don't work here -> BUG
If someone has time to find out, which parameters don't work with app.config.from_object( .. ), he can add an other answer.
And don't forget to switch the google security to accept less secure apps. Otherwise it won't work. Regards
Upvotes: 0
Reputation: 31
My first attempt on here but just picking out what i can see. Im assuming that you have copied your entire code from each file. Correct me if im wrong.
Ensure routes.py imports the necessary classes from flask ("request" is imperative for submitting the form as it determines if the request method is a GET or POST:
from flask import Flask, render_template, request, flash
And your Forms.py... note: you don't actually need to import the entire wtforms module...
from flask.ext.wtf import Form
from wtforms import TextField, SubmitField, TextAreaField, validators, ValidationError
In your routes.py code there is an unnecessary boolean operator if "not" statement:
if request.method == 'POST':
if not form.validate():
It should be contain a comparative operator and boolean as it is in Lalith's Post:
if form.validate() == False:
flash("All fields...
Your forms.py shouldnt contain any of this:
flash('All fields are required.')
return render_template('contact.html', form=form)
else:
msg = Message(form.subject.data, sender='[email protected]', recipients=['[email protected]'])
msg.body = """From: %s <%s> %s""" % (form.name.data, form.email.data, form.message.data)
mail.send(msg)
return render_template('contact.html', success=True)
elif request.method == 'GET':
return render_template('contact.html', form=form)
It should all be contained within the contact function in routes.py like this:
def contact():
form = ContactForm()
if request.method == 'POST':
if not form.validate():
flash('All fields are required.')
return render_template('contact.html', form=form)
else:
msg = Message(form.subject.data, sender='[email protected]', recipients=['[email protected]'])
msg.body = """From: %s <%s> %s""" % (form.name.data, form.email.data, form.message.data)
mail.send(msg)
return render_template('contact.html', success=True)
elif request.method == 'GET':
return render_template('contact.html', form=form)
Lastly I know this may seem really obvious but make sure you replace "email" with your real email and password here:
app.config['MAIL_USERNAME'] = 'email'
app.config['MAIL_PASSWORD'] = 'email'
Good luck. Hope this helps.
Upvotes: 1