Flask崩溃并显示ValueError: too many values to unpack。

9

我有一个使用flask构建的应用,它需要和另外一个web服务进行通信。当这两个应用同时在同一台服务器上运行时,我遇到了一个错误,但是我并不知道它的源头在哪里。Flask应用通过Apache中的WSGIScriptAlias托管在/tools路径下。

[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114] mod_wsgi (pid=25705): Exception occurred processing WSGI script '/opt/tools-frontend/wsgi.py'.
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114] Traceback (most recent call last):
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]   File "/opt/tools-frontend/ENV_1/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]     return self.wsgi_app(environ, start_response)
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]   File "/opt/tools-frontend/ENV_1/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]     response = self.make_response(self.handle_exception(e))
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]   File "/opt/tools-frontend/ENV_1/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]     response = self.full_dispatch_request()
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]   File "/opt/tools-frontend/ENV_1/lib/python2.7/site-packages/flask/app.py", line 1361, in full_dispatch_request
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]     response = self.make_response(rv)
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]   File "/opt/tools-frontend/ENV_1/lib/python2.7/site-packages/flask/app.py", line 1447, in make_response
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]     rv = self.response_class(rv, headers=headers, status=status)
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]   File "/opt/tools-frontend/ENV_1/lib/python2.7/site-packages/werkzeug/wrappers.py", line 627, in __init__
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]     self.headers = Headers(headers)
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]   File "/opt/tools-frontend/ENV_1/lib/python2.7/site-packages/werkzeug/datastructures.py", line 836, in __init__
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]     self.extend(defaults)
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]   File "/opt/tools-frontend/ENV_1/lib/python2.7/site-packages/werkzeug/datastructures.py", line 978, in extend
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114]     for key, value in iterable:
[Thu May 23 13:11:44 2013] [error] [client 41.164.8.114] ValueError: too many values to unpack
[Thu May 23 13:11:44 2013] [debug] mod_deflate.c(615): [client 41.164.8.114] Zlib: Compressed 590 to 372 : URL /tools/api/login/, referer: http://www.website.com/tools

这个API托管在同一台计算机上的不同域名下,查看该域名下的日志文件,可以确认它正常工作。

以下函数中进行了API调用:

@app.route('/api/', methods=['GET', 'POST', 'PUT', 'DELETE'])
@app.route('/api/<path:endpoint>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def api(endpoint=None):
    # extract POST/PUT variables
    dat = request.form
    if len(dat) == 0:
        # extract GET variables
        dat = request.args
    # submit request to API
    out = call_api(request.method, endpoint, dat, request.files)
    return out

调用此函数:

def call_api(method, endpoint, data=None, files=None):
    url = 'https://api.example.com' + endpoint
    if method.upper() == "GET":
        r = requests.get(url, data=data, verify=False)
    # ... similarly for other verbs  
    return r.text, r.status_code, r.headers

1
你是否在尝试在你的视图中设置头部?能否分享一下代码?headers 的值不是 None,也不是字典,但是它是可迭代的。可迭代对象应该产生 (key, value) 对,但这不是它得到的。 - DazWorrall
在我看来,崩溃似乎是在flask/werkzeug尝试处理响应时发生的。您可以在堆栈跟踪中看到,我的代码根本没有参与其中,顶部文件是flask/app/py。触发API调用的行是r = requests.get(url, data=data, verify=False) - Baruch
你能分享一下你的视图代码吗?它在解析响应头时出现了问题,你的代码没有出现在堆栈跟踪中,因为错误不在你的视图中,但这并不意味着它不是原因——毕竟它生成响应。 - DazWorrall
1个回答

22

我最好的猜测是,你返回了一个特殊的头部字典(来自 python-requests),而不是普通的头部字典。Flask接受两种形式的头部:

{'key': 'value'}
# and
[('key', 'value')]

由于您的特殊字典并未被识别为真正的字典,因此它将被视为元组列表,这将导致失败。

更改

return r.text, r.status_code, r.headers

return r.text, r.status_code, r.headers.items()

3
我非常无法给这个赞了!你解决了我一个星期的痛苦和挫折。 - Baruch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接