GAE 标准 Flask 教程:ImportError: cannot import name SpooledTemporaryFile

Posted

技术标签:

【中文标题】GAE 标准 Flask 教程:ImportError: cannot import name SpooledTemporaryFile【英文标题】:GAE standard Flask tutorial: ImportError: cannot import name SpooledTemporaryFile 【发布时间】:2018-05-22 19:23:27 【问题描述】:

我正在尝试使用这个GAE Flask tutorial。我相信我完全遵循了它,并且我从 Github 下载了代码,所以没有拼写错误。

当我启动开发服务器 (dev_appserver.py app.yaml) 并转到 http://localhost:8080/form 时,我收到此错误:

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

看起来它与 GAE 沙盒有关,但我无法弄清楚。我尝试在 virtualenv 内部和外部运行开发服务器。

在使用带有应用引擎的 virtualenv 时,您有什么特别需要做的吗?

【问题讨论】:

现在没时间看它,但猜测它正在拉动最新的 werkzeug(该导入来自最近的更改),所以看看你当前拥有的版本和pip install --upgrade 版本在那之前。 (***.com/questions/41525223/… 原则上类似) 那行得通。谢谢!看起来最新的 werkzeug 昨天发布了。我回到了werkzeug 0.12.2。有空的时候请随意添加答案,我会将其标记为正确。 【参考方案1】:

本教程指定使用 Flask 版本 0.12.2。

Flask 的 setup.py 需要 0.7 之后的任何 werkzeug 版本

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

在 werkzeug 0.13 中,与添加对分块传输编码的支持相关的 this commit 将 SpooledTemporaryFile 的导入添加到 werkzeug.formparser

App Engine 沙盒disables any imports from the tempfile module apart from tempfile.TemporaryFile,因此出现错误。

要解决此问题,请将 werkzeug 降级到不包括导入的版本 0.12.2。

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

pip --upgrade 强制安装提供的版本,因此它会降级和升级)

或修改您的供应商要求文件以固定 werkzeug 版本

Flask==0.12.2
werkzeug==0.12.2

更新:

此问题现已在 Google Samples Docs repo 和 Werkzeug v0.14 中得到解决。

【讨论】:

我将 werkzeug 更新到 0.14 并且问题仍然存在,我不得不使用 Brady Huang 的解决方案(将 2 个语句添加到 appengine_config.py)【参考方案2】:

我最近也遇到这个错误。 我的 Python 版本在 Stand 环境中是 2.7.14。 相信前几天有更新,干扰了这个包。

对于我来说,请参考 Github issue here 中提到的解决方案。 我只是将它添加到 appengine_config.py 文件中:

import tempfile tempfile.SpooledTemporaryFile = tempfile.TemporaryFile

然后我的项目就像魅力一样工作。 该链接还提到如果您使用早期版本的 Python 2.7 可能会解决问题,但我还没有尝试过该解决方案。

【讨论】:

我昨天也遇到了同样的问题,您的修复适用于“无法导入名称 SpooledTemporaryFile”的问题,但后来我遇到了“无法导入名称 msvcrt”的问题。它让我发疯。 我发现 Flask==0.10.1 和 Werkzeug==0.12.2 对我有用,没有更新的方法。

以上是关于GAE 标准 Flask 教程:ImportError: cannot import name SpooledTemporaryFile的主要内容,如果未能解决你的问题,请参考以下文章

Flask 和 Webapp2 (GAE) 的区别

如何在 Flask/GAE 中渲染标签?

使用 Flask (python) 从 GAE 数据存储中提供图像

带有 GAE ndb 的 Flask Flask 安全性?

使用 Flask-Restless 进行 GAE app.yaml 路由

GAE 标准 python 2.7 运行时何时消失?