connexion: ImportError: cannot import name 'FileStorage' from 'werkzeug'

Description

Getting below import error when using connexion 1.1.15 cannot import name ‘FileStorage’ from ‘werkzeug’

Expected behaviour

import connexion should work without issues

Actual behaviour

File “/opt/bitnami/python/lib/python3.7/site-packages/connexion/decorators/validation.py”, line 9, in <module> from werkzeug import FileStorage ImportError: cannot import name ‘FileStorage’ from ‘werkzeug’ (/opt/bitnami/python/lib/python3.7/site-packages/werkzeug/init.py)

Steps to reproduce

pip install connexion == 1.1.15

import connexion

Additional info:

The issue started on Feb 7, 2020 as werkzeug ver 1.0.0 released. werkzeug is a dependency of connexion and ver 1.0.0 is installed as a pre-requisite from Feb 07, 2020. Workaround : Install werkzeug ver 0.16.1 before installing connexion

Output of the commands:

  • python --version Python 3.7.4
  • pip show connexion | grep "^Version\:" Version: 1.1.15

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 19
  • Comments: 20 (3 by maintainers)

Commits related to this issue

Most upvoted comments

We were using connexion==2.2.0 and started getting this error. Using connexion==2.6.0 (without specifying any werkzeug dependencies) solved the problem.

@jmcs thanks. Using latest version + werkzeug==0.16.1 solved this problem.

Looks like they moved the FileStorage under datastructrues.

from werkzeug.datastructures import FileStorage

Solved the problem for me.

Here is the documentation.

https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/

I know this doesn’t help in any way whatsoever, but Python is just broken in so many ways when you want to use it for production stuff.

It never works. It’s extremely confusing what version of python to use, what virtualenv tool (virtualenv, pipenv, …) , what package manager (pip, pip3, conda, easy_install, …), where actual configuration is stored…

In my opinion, it was a huge mistake to allow two supported versions of python to co-exist. I know I know, backwards compatibility, but honestly, when production software makes use of such code:


if PY2K:
    import thread
else:
    import _thread as thread

it’s just broken and needs to be dropped.

What we actually have right now are Linux servers full of two versions of Python (2 and 3) that are not compatible with each other. It’s a huge problem.

This is still an issue. cc @patrickkwang

Swagger codegen for flask emits requirements.txt with connexion == 2.2.0. Out-of-the-box, that fails to install due to connexion not declaring dependency onto Werkzeug while directly using it:

https://github.com/zalando/connexion/blob/a0ac0fd13f6857bba2563fbdda55404cfa69dde3/connexion/decorators/validation.py#L9

Off course, since the dependency is not declared (and so, not constrained) — the indirectly-updated-via-flask Werkzeug 1.0 move werkzeug.FileStoragewerkzeug.datastructures.FileStorage breaks it. @cognifloyd correctly notices the problem, too.

OK the poor programmer sighs, maybe googles this issue, tweaks the requirements.txt that Swagger generated (anyone cares to send them a patch bumping up connexion?)… only to kiss another error:

  File "/home/ulidtko/src/redacted_project/.tox/py38/lib/python3.8/site-packages/flask_testing/utils.py", line 29, in <module>
    from werkzeug import cached_property
ImportError: cannot import name 'cached_property' from 'werkzeug' (/home/ulidtko/src/redacted_project/.tox/py38/lib/python3.8/site-packages/werkzeug/__init__.py)

Long story short, with this I was able to also run tox tests on Python 3.8 in an OpenAPI swagger-generated server project:

diff --git i/requirements.txt w/requirements.txt
index b5bc506..c44cfa7 100644
--- i/requirements.txt
+++ w/requirements.txt
@@ -1,3 +1,3 @@
-connexion == 2.2.0
+connexion == 2.7.0
 python_dateutil == 2.6.0
 setuptools >= 21.0.0
diff --git i/test-requirements.txt w/test-requirements.txt
index 7f8d96e..3bff640 100644
--- i/test-requirements.txt
+++ w/test-requirements.txt
@@ -1,4 +1,4 @@
-flask_testing==0.6.1
+flask_testing
 coverage>=4.0.3
 nose>=1.3.7
 pluggy>=0.3.1

In fast-moving ecosystems, not following basic dependency management hygiene leads to issues exactly like this. Take it as a lesson “how not to”.

Hmm. It looks like connexion needs to declare werkzeug as a direct dependency and not rely on our dep to flask to pull that in.

My use case is a Flask Swagger API

I pinned to the following packages and my build resolved the issue.

Werkzeug==0.15.6
Flask==1.1.1
connexion==1.5.3

To help those that might be searching for this, here is my error

Traceback (most recent call last):
  File "./wsgi.py", line 10, in <module>
    from swagger_server.server import app
  File "./swagger_server/server.py", line 4, in <module>
    import connexion
  File "/usr/src/app/py3_env/lib/python3.6/site-packages/connexion/__init__.py", line 3, in <module>
    from .apis import AbstractAPI  # NOQA
  File "/usr/src/app/py3_env/lib/python3.6/site-packages/connexion/apis/__init__.py", line 1, in <module>
    from .abstract import AbstractAPI  # NOQA
  File "/usr/src/app/py3_env/lib/python3.6/site-packages/connexion/apis/abstract.py", line 14, in <module>
    from ..operation import Operation
  File "/usr/src/app/py3_env/lib/python3.6/site-packages/connexion/operation.py", line 10, in <module>
    from .decorators.response import ResponseValidator
  File "/usr/src/app/py3_env/lib/python3.6/site-packages/connexion/decorators/response.py", line 12, in <module>
    from .validation import ResponseBodyValidator
  File "/usr/src/app/py3_env/lib/python3.6/site-packages/connexion/decorators/validation.py", line 10, in <module>
    from werkzeug import FileStorage
ImportError: cannot import name 'FileStorage'

While this might not be THE solution, it seems to have worked for me at this time.

I’ll be experimenting with different versions but since this is a fresh issue popping up, I wanted to get something out here to help those pulling their hair out.

Just by pinning connexion==2.6.0 in requirements.txt file fixed the issue!