title: upload files using flask-uploads
body: <p>I am trying to upload files using the <a href="http://pythonhosted.org/Flask-Uploads/" rel="noreferrer">flask-uploads</a> extension.
  The problem is that, each time it seems I find a solution, I fund an other problem, and I feel the documentation cryptic.</p>
  
  <p>Here is the code :</p>
  
  <pre><code>from flask.ext.uploads import UploadSet, IMAGES, configure_uploads 
  import os
  from werkzeug import secure_filename
  
  photos = UploadSet('photos', IMAGES)
  configure_uploads(app, photos)
  
  @app.route('/edit_book', methods = ['GET', 'POST'])
  def edit_book():
  form = BookForm()
  if form.validate_on_submit():
              b.summary = form.summary.data
      if request.method == 'POST':
          try:
              secure_filename = photos.save(request.files['cover'])
          except:
              print 'not ok'
              db.session.add(b)
      db.session.commit()
      return redirect('/admin')
  return render_template('edit_book.html', title = 'Add a book', form = form )
  </code></pre>
  
  <p>The current error give just :</p>
  
  <pre><code>KeyError: 'images'.
  </code></pre>
  
  <p>I have nothing more ! Does any one issue in using this extension, as I find no suitable piece of code anywhere that give a full solution (from the start of an upload to the saving of the file in a folder).</p>
  
  <p>Thank you in advance for your help.</p>
  
  <h2>Template code</h2>
  
  <pre><code>&lt;!-- extend from admin layout --&gt;
  {% extends "admin.html" %}
  
  {% block content %}
   &lt;form action="" method="post" name="edit_book" enctype="multipart/form-data"&gt;
  {{form.hidden_tag()}}
  
  {% if dico %}
   &lt;h1&gt;Ajouter le livre &lt;i&gt;{{dico.title}}&lt;/i&gt; à la base de données&lt;/h1&gt;
  {% else %}
  {% set dico = [] %}
   &lt;h1&gt;Ajouter un livre à la base de données&lt;/h1&gt;
   {% endif %}
  &lt;p&gt;Titre (obligatoire) :    {{form.title(value=dico.title)}}&lt;/p&gt;
  &lt;p&gt;ISBN 13 (EAN) :      {{form.ean(value=dico.EAN)}}&lt;/p&gt;
  &lt;p&gt;ISBN :           {{form.isbn(value=dico.ISBN)}}&lt;/p&gt;
  &lt;p&gt;Maison d'édition :       {{form.publisher(value=dico.publisher)}}&lt;/p&gt;
  &lt;p&gt;epaisseur (cm) :     {{form.thickness(value=dico.thickness)}}&lt;/p&gt;
  &lt;p&gt;longueur (cm) :      {{form.length(value=dico.length)}}&lt;/p&gt;
  &lt;p&gt;largeur (cm) :       {{form.width(value=dico.width)}}&lt;/p&gt;
  &lt;p&gt;masse (kg) :         {{form.mass(value=dico.mass)}}&lt;/p&gt;
  &lt;p&gt;Nombre de pages :        {{form.numberofpages(value=dico.pages)}}&lt;/p&gt;
  &lt;p&gt;Couverture du livre :    {{form.cover(value=dico.img)}}&lt;/p&gt;
  &lt;p&gt;Quatrième de couverture :    {{form.summary(cols="35", rows="20")|safe}}&lt;/p&gt;
  &lt;p&gt;&lt;input type="submit" value="Envoyez"&gt;&lt;/p&gt;
  &lt;/form&gt;
  {% endblock %}
  </code></pre>
  
  <h2>Error Stacktrace</h2>
  
  <pre><code>* Running on http://127.0.0.1:5000/
  * Restarting with reloader
  127.0.0.1 - - [22/Jul/2013 15:16:18] "POST /edit_book HTTP/1.1" 500 -
  Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1701, in __call__
  return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1689, in wsgi_app
  response = self.make_response(self.handle_exception(e))
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1687, in wsgi_app
  response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1360, in    full_dispatch_request
  rv = self.handle_user_exception(e)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1358, in  full_dispatch_request
  rv = self.dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1344, in  dispatch_request
  return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/stephane/git/biblib-flask/app/views.py", line 117, in edit_book
  if form.validate_on_submit():
  File "/usr/local/lib/python2.7/dist-packages/flask_wtf/form.py", line 125, in  validate_on_submit
  return self.is_submitted() and self.validate()
   File "/usr/local/lib/python2.7/dist-packages/wtforms/form.py", line 265, in validate
  return super(Form, self).validate(extra)
   File "/usr/local/lib/python2.7/dist-packages/wtforms/form.py", line 130, in validate
  if not field.validate(self, extra):
   File "/usr/local/lib/python2.7/dist-packages/wtforms/fields/core.py", line 176, in  validate
   stop_validation = self._run_validation_chain(form, chain)
   File "/usr/local/lib/python2.7/dist-packages/wtforms/fields/core.py", line 196, in _run_validation_chain
   validator(form, self)
   File "/usr/local/lib/python2.7/dist-packages/flask_wtf/file.py", line 69, in __call__
  if not self.upload_set.file_allowed(field.data, field.data.filename):
   File "/usr/local/lib/python2.7/dist-packages/Flask_Uploads-0.1.3-    py2.7.egg/flaskext/uploads.py", line 346, in file_allowed
   return self.extension_allowed(extension(basename))
   File "/usr/local/lib/python2.7/dist-packages/Flask_Uploads-0.1.3-py2.7.egg/flaskext/uploads.py", line 356, in extension_allowed
   return ((ext in self.config.allow) or
   File "/usr/local/lib/python2.7/dist-packages/Flask_Uploads-0.1.3-py2.7.egg/flaskext/uploads.py", line 308, in config
   return current_app.upload_set_config[self.name]
   KeyError: 'images'
   127.0.0.1 - - [22/Jul/2013 15:16:18] "GET /edit_book?    __debugger__=yes&amp;cmd=resource&amp;f=style.css HTTP/1.1" 200 -
   127.0.0.1 - - [22/Jul/2013 15:16:18] "GET /edit_book?__debugger__=yes&amp;cmd=resource&amp;f=jquery.js HTTP/1.1" 200 -
   127.0.0.1 - - [22/Jul/2013 15:16:18] "GET /edit_book?__debugger__=yes&amp;cmd=resource&amp;f=debugger.js HTTP/1.1" 200 -
   127.0.0.1 - - [22/Jul/2013 15:16:18] "GET /edit_book?__debugger__=yes&amp;cmd=resource&amp;f=ubuntu.ttf HTTP/1.1" 200 -
   127.0.0.1 - - [22/Jul/2013 15:16:18] "GET /edit_book?__debugger__=yes&amp;cmd=resource&amp;f=console.png HTTP/1.1" 200 -
   127.0.0.1 - - [22/Jul/2013 15:16:18] "GET /edit_book?__debugger__=yes&amp;cmd=resource&amp;f=source.png HTTP/1.1" 200 -
  </code></pre>
  
  <p>I just checked the code more largely, and find only one thing that is exactly 'images' :
  a validator in the forms.</p>
  
  <pre><code> from flaskext.uploads import UploadSet, IMAGES
   images = UploadSet("images", IMAGES)
  
   class BookForm(Form):
      summary = TextAreaField('summary', [validators.optional()])
  cover = FileField("cover", [validators.optional(),file_allowed(images, "Images only!")])
  </code></pre>