Search code examples
google-app-engineflaskwerkzeug

GAE standard Flask tutorial: ImportError: cannot import name SpooledTemporaryFile


I'm trying the use this GAE Flask tutorial. I believe I followed it exactly and I downloaded the code from Github so there are no typos.

When I start the dev server (dev_appserver.py app.yaml) and go to http://localhost:8080/form, I get this error:

Traceback (most recent call last):
  File "/Users/.../google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File "/Users/.../google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
    handler, path, err = LoadObject(self._handler)
  File "/Users/.../google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject
    obj = __import__(path[0])
  File "/Users/.../GIT/TEMP/main.py", line 19, in <module>
    from flask import Flask, render_template, request
  File "/Users/.../GIT/TEMP/lib/flask/__init__.py", line 17, in <module>
    from werkzeug.exceptions import abort
  File "/Users/.../GIT/TEMP/lib/werkzeug/__init__.py", line 151, in <module>
    __import__('werkzeug.exceptions')
  File "/Users/.../GIT/TEMP/lib/werkzeug/exceptions.py", line 71, in <module>
    from werkzeug.wrappers import Response
  File "/Users/.../GIT/TEMP/lib/werkzeug/wrappers.py", line 37, in <module>
    from werkzeug.formparser import FormDataParser, default_stream_factory
  File "/Users/.../GIT/TEMP/lib/werkzeug/formparser.py", line 14, in <module>
    from tempfile import SpooledTemporaryFile
ImportError: cannot import name SpooledTemporaryFile

It looks like it has something to do with the GAE sandbox, but I can't figure it out. I tried running the dev server both inside and outside of the virtualenv.

Is there something special you have to do when using virtualenv with app engine?


Solution

  • The tutorial specifies using Flask version 0.12.2.

    Flask's setup.py requires any version of werkzeug after version 0.7

    install_requires=[
        'Werkzeug>=0.7',
        'Jinja2>=2.4',
        'itsdangerous>=0.21',
        'click>=2.0',
    ],
    

    In werkzeug 0.13, this commit related to adding support for chunked transfer encoding adds the import of SpooledTemporaryFile to werkzeug.formparser.

    The App Engine sandbox disables any imports from the tempfile module apart from tempfile.TemporaryFile, hence the error.

    To workaround this problem, downgrade werkzeug to version 0.12.2, which doesn't include the import.

    pip install --target lib --upgrade werkzeug==0.12.2

    (pip --upgrade forces installation of the supplied version, so it will downgrade as well as upgrade)

    or amend your vendor requirements file to pin the werkzeug version

    Flask==0.12.2
    werkzeug==0.12.2
    

    UPDATE:

    This issue has now been addressed in both the Google Samples Docs repo and Werkzeug v0.14.