user2708736
user2708736

Reputation: 29

RECAPTCHA_PUBLIC_KEY config not set with Flask-WTForms

I've gone over and over the documentation and keep getting 'RuntimeError: RECAPTCHA_PUBLIC_KEY config not set' when the Contact page attempts to load using Recaptcha with wtforms in Flask. I'm open to any kind of suggestions. I am running Flask on Ubuntu 14.04 using Google's ReCaptcha 2, FWIW.

EDIT: This issue has been resolved with the advice from dirn but I am now getting a KeyError message despite the public and private keys being correctly entered.

Here is my stack trace.

File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__return self.wsgi_app(environ, start_response)
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/matt/work/bsureunion/run.py", line 71, in contact
if form.validate_on_submit():
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask_wtf/form.py", line 166, in validate_on_submit
return self.is_submitted() and self.validate()
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/wtforms/form.py", line 310, in validate
return super(Form, self).validate(extra)
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/wtforms/form.py", line 152, in validate
if not field.validate(self, extra):
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/wtforms/fields/core.py", line 200, in validate
Display the sourcecode for this frameOpen an interactive python shell in this framestop_validation = self._run_validation_chain(form, chain)
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/wtforms/fields/core.py", line 220, in _run_validation_chain
validator(form, self)
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask_wtf/recaptcha/validators.py", line 47, in __call__
if not self._validate_recaptcha(response, remote_ip):
File "/home/matt/work/bsureunion/venv/lib/python2.7/site-packages/flask_wtf/recaptcha/validators.py", line 74, in _validate_recaptcha
for error in json_resp["error-codes"]:
KeyError: 'error-codes'

forms.py

from flask.ext.wtf import Form, RecaptchaField
from wtforms import StringField, TextAreaField, SubmitField
from wtforms.validators import InputRequired, Email
from wtforms.fields.html5 import EmailField

class ContactForm(Form):
name = StringField("Name", validators=[InputRequired('Please enter your name.')])
email = EmailField("Email",  validators=[InputRequired("Please enter your email address."), Email("Please enter your email address.")])
subject = StringField("Subject", validators=[InputRequired("Please enter the subject.")])
message = TextAreaField("Message", validators=[InputRequired("Please enter your message.")])
recaptcha = RecaptchaField()
submit = SubmitField("Send")

run.py

import os
from flask import Flask, render_template, request, flash
from forms import ContactForm
from flask.ext.mail import Message, Mail

mail = Mail()

app = Flask(__name__)

app.secret_key = 'secret_'

app.config["MAIL_SERVER"] = "smtp.gmail.com"
app.config["MAIL_PORT"] = 465
app.config["MAIL_USE_SSL"] = True
app.config["MAIL_USERNAME"] = '[email protected]'
app.config["MAIL_PASSWORD"] = 'password'

SECURITY_EMAIL_SENDER = '[email protected]'

RECAPTCHA_USE_SSL = False
RECAPTCHA_PUBLIC_KEY = 'public'
RECAPTCHA_PRIVATE_KEY = 'private'
RECAPTCHA_OPTIONS = {'theme': 'white'}

mail.init_app(app)

****snip****

@app.route('/contact/', methods=['GET', 'POST'])
def contact():
form = ContactForm()

if request.method == 'POST':
    if form.validate() == False:
      flash('All fields are required.')
      return render_template('contact.html', form=form)
if form.validate_on_submit():
    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)

contact.html

{% extends "layout.html" %}

{% block body %}
<h2>Contact</h2>

{% if success %}
  <p>Thank you for your message. We'll get back to you shortly.</p>
  <p>Return to <a href="{{ url_for('home') }}">Home Page</a>.</p>

{% else %}

  {% for message in form.name.errors %}
    <div class="flash">{{ message }}</div>
  {% endfor %}

  {% for message in form.email.errors %}
    <div class="flash">{{ message }}</div>
  {% endfor %}

  {% for message in form.subject.errors %}
    <div class="flash">{{ message }}</div>
  {% endfor %}

  {% for message in form.message.errors %}
    <div class="flash">{{ message }}</div>
  {% endfor %}

  <form action="{{ url_for('contact') }}" method=post>
    {{ form.hidden_tag() }}

    {{ form.name.label }}
    {{ form.name }}

    {{ form.email.label }}
    {{ form.email }}

    {{ form.subject.label }}
    {{ form.subject }}

    {{ form.message.label }}
    {{ form.message }}

    {{ form.recaptcha }}

    {{ form.submit }}
  </form>

{% endif %}
{% endblock %}

Upvotes: 3

Views: 6194

Answers (1)

dirn
dirn

Reputation: 20739

You aren't adding the configuration settings to the application. You are defining module-level variables

RECAPTCHA_USE_SSL = False
RECAPTCHA_PUBLIC_KEY = 'public'
RECAPTCHA_PRIVATE_KEY = 'private'
RECAPTCHA_OPTIONS = {'theme': 'white'}

You need to use the names as keys for the config dictionary.

app.config['RECAPTCHA_USE_SSL'] = False
app.config['RECAPTCHA_PUBLIC_KEY'] = 'public'
app.config['RECAPTCHA_PRIVATE_KEY'] = 'private'
app.config['RECAPTCHA_OPTIONS'] = {'theme': 'white'}

Upvotes: 8

Related Questions