noirbizarre/flask-restplus

flask-restplus is broken by Werkzeug 1.0.0

gil0109 opened this issue ยท 43 comments

Sorry, I am an Ops guys and not a developer but I hope this helps..

Error Messages/Stack Trace

If applicable, add the stack trace produced by the error

  | Traceback (most recent call last):   | File "./manage.py", line 4, in <module>   | from qsystem import db, application   | File "/opt/app-root/src/qsystem.py", line 16, in <module>   | from flask_restplus import Api   | File "/opt/app-root/lib/python3.6/site-packages/flask_restplus/__init__.py", line 4, in <module>   | from . import fields, reqparse, apidoc, inputs, cors   | File "/opt/app-root/lib/python3.6/site-packages/flask_restplus/fields.py", line 17, in <module>   | from werkzeug import cached_property   | ImportError: cannot import name 'cached_property'

Environment

  • Python version 3.6.
  • flask-marshmallow==0.10.1
  • flask-oidc==1.4.0
  • flask-restplus==0.13.0

I too am experiencing this issue from a fresh install.

$ python app.py 
Traceback (most recent call last):
  File "app.py", line 23, in <module>
    from flask_restplus import Resource, Api
  File "/home/user/programs/python_apps/api-testing/env/lib/python3.6/site-packages/flask_restplus/__init__.py", line 4, in <module>
    from . import fields, reqparse, apidoc, inputs, cors
  File "/home/user/programs/python_apps/api-testing/env/lib/python3.6/site-packages/flask_restplus/fields.py", line 17, in <module>
    from werkzeug import cached_property
ImportError: cannot import name 'cached_property'

Environment:
aniso8601==8.0.0
attrs==19.3.0
Click==7.0
Flask==1.1.1
flask-restplus==0.13.0
importlib-metadata==1.5.0
itsdangerous==1.1.0
Jinja2==2.11.1
jsonschema==3.2.0
MarkupSafe==1.1.1
pkg-resources==0.0.0
pyrsistent==0.15.7
pytz==2019.3
six==1.14.0
Werkzeug==1.0.0
zipp==2.1.0

Edit: Downgrading to Werkzeug to 0.16.0 (temporarily) resolved the issue.

Same issue here

Traceback (most recent call last): File "manage.py", line 10, in <module> from application.boot.blueprints import BLUEPRINT as api_bp File "/application/boot/blueprints.py", line 4, in <module> from flask_restplus import Api File "/venv/lib/python3.7/site-packages/flask_restplus/__init__.py", line 4, in <module> from . import fields, reqparse, apidoc, inputs, cors File "/venv/lib/python3.7/site-packages/flask_restplus/fields.py", line 17, in <module> from werkzeug import cached_property ImportError: cannot import name 'cached_property' from 'werkzeug' (/venv/lib/python3.7/site-packages/werkzeug/__init__.py)

psycopg2-binary==2.8.3
mysqlclient==1.4.4
celery==4.3.0
coverage==4.5.4
factory-boy==2.12.0
Flask==1.1.1
Flask-Migrate==2.5.2
flask-restplus==0.13.0
Flask-Script==2.0.6
Flask-Seeder==0.1a2
Flask-SQLAlchemy==2.4.0
flake8==3.7.9
kombu==4.6.3
python-dotenv==0.10.3
pylint==2.4.4
redis==3.3.11
SQLAlchemy-Utils==0.34.2
sentry-sdk[flask]==0.13.1
Flask-Testing==0.7.1
gunicorn==19.9.0
uuid==1.30
nplusone==1.0.0
newrelic==5.2.2.130
scipy==1.3.2
pandas==0.25.3
Faker==2.0.4
Werkzeug==1.0.0

Many thanks in advance

Temporary workaround: use Werkzeug==0.16.1

Temporary workaround: use Werkzeug==0.16.1
Worked for me too.

Found the cause, but not sure how to fix it (if anybody does, please do)...
Flask-restplus has a dependency on Flask:
Flask>=0.8
The latest version of Flask is 1.1.1 and that version of Flask has a dependency on Werkzeug like this:
Werkzeug>=0.15 (https://github.com/pallets/flask/blob/master/setup.py line 56)
Werkzeug release 1.0 yesterday, breaking flask-restplus.

It's because cached_property has to be explicitly imported from werkzeug.utils now. #738 fixes that but I believe an import in api.py needs to also be fixed.

rglsk commented

Fixed here #778 Awaiting for code review.

As #777 (comment) said, you can pin the werkzeug version to 0.16.1 in your project dependencies.

This project should be considered dead as stated in #770
BUT, flask-restx is also impacted by this bug.
I'm working on a hotfix release as of now that will hopefully be available by tomorrow.

@ziirish thank you. I will ask our dev team to move over. Thank you for taking on this project!

Werkzeug package got new version(1.0.0) update today. The update is not backward compatible, many Flask based libraries are breaking.
A simple fix is that, install Werkzeug==0.16.0, which is working perfectly.
Install this version before installing flask or after it, doesn't really matter, things will work as expected.

Thanks.. done until packages are updated. I like to keep as new as possible to reduce code rewrites when vulnerabilities are found. I am hoping switching to new library will not require many changes to our code :)

We have now released flask-restx 0.1.1 that workarounds the issue.

this is the workaround

pipenv install werkzeug~=0.16.1

for those who use pipenv

this is the workaround

pipenv install werkzeug~=0.16.1

for those who use pipenv

can confirm, this solution works

pytest-flask fixed similar issue.

I'm not sure if this is the right thread to ask this question, but does flask-restplus also have a roadmap to reach 1.0.0?

No. Flask-restplus is no longer maintained. The former maintainers do not have privileges to push to pypi, and after many months of trying, we forked the project. Check out flask-restx. It's a drop in replacement and we are roadmapping, designing, and making fixes...for instance, we already patched for Werkzeug

So there is no one who can quickly create version 0.13.1 with this small fix in requirements and publish it?

No, sorry

Will it be fixed in flask-restx instead?

Will it be fixed in flask-restx instead?

It's already fixed there.

In flask-restx 0.1.1 we have workaround it (by pinning werkzeug version to 0.16.1 in the requirements).
In a future version of flask-restx we will apply a proper fix. It is actually already merged into master.

Oh, thanks! I need to check my flask-restx version then.

Can I ask a newbie question then? I have my own package, which are then dependent on flask and flask_restx (and a few other 3rd party packages). When I install my package with "pip install --upgrade mylib", the werkzeug package get upgraded to 1.0.0 all the time. flask==1.1.1 and flask_restx=0.1.1. I can set versions of flask and flask_restx in mylibs setup.py, but how can I prevent werkzeug to be upgraded?

I put install_requires=[werkzeug==0.16.1, ...] in my setup.py.

Yes sorry, that's the limitation of the patch currently shipped in restx 0.1.1.
The proper fix will be part of the next version.

jblom commented

@ziirish just now I replaced my flask-restplus with flask-restx and indeed now the Werkzeug bug is not happening anymore (in our auto build & test). Cool stuff, thanks

Just FYI, for me it was just a matter of:

  • uninstalling flask-restplus (pipenv uninstall flask-restplus)
  • installing flask-restx (pipenv install flask-restx)
  • change flask_restplus import statements to flask_restx (e.g. from flask_restx import Api instead of from flask_restplus import Api)

So now I guess eventually the real patch will flow in via flask-restx

Thanks @jblom replacing flask_restplus with flask_restx fixed it for me and was seamless.

Thank you @jblom works perfectly

got a fix around this issue in api.py just add from werkzeug.utils import cached_property , then your code will work like a charm

ntung commented

As #777 (comment) said, you can pin the werkzeug version to 0.16.1 in your project dependencies.

This solution works for me. Thanks!

Temporary workaround: use Werkzeug==0.16.1

This solution worked for me as well.

for me flask-restplus installed Werkzeug [required: >=0.15, installed: 1.0.1]

I downgraded it using pipenv install Werkzeug==0.16.1 as I am using pipenv

  • works this way!

import werkzeug
from flask.scaffold import _endpoint_from_view_func
from werkzeug.utils import cached_property

import flask

flask.helpers._endpoint_from_view_func = _endpoint_from_view_func

werkzeug.cached_property = cached_property

from flask import Flask
from flask_restplus import Api

"from werkzeug import cached_property" in file api.py file needs to be changed to "from werkzeug.uitls import cached_property"
for current werkzeug versions. It's already fixed in fields.py could you commit this change as well please?

regards,

Is someone going to fix this small bug ? Downgrading werkzeug <= 1.0.0 is not a long term solution for this problem

Is someone going to fix this small bug ? Downgrading werkzeug <= 1.0.0 is not a long term solution for this problem

Yes agree !

No, this bug won't get fixed. Flask-restplus has ceased development. There are no active maintainers. There is a fork, though we are far behind as well (but this issue has been fixed in flask-restx at least)

#770

As I see werkzeug has been updated recently(2.1+) and a workaround slightly changed because they remove BaseResponse and combine it with Response

import werkzeug
from flask.scaffold import _endpoint_from_view_func
from werkzeug.utils import cached_property
from werkzeug.wrappers import Response
import flask

flask.helpers._endpoint_from_view_func = _endpoint_from_view_func

werkzeug.cached_property = cached_property
werkzeug.wrappers.BaseResponse = Response

from flask import Flask
from flask_restplus import Api

if we downgrade werkzeug 0.16.1 , looks we need to downgrade flask as well.

flask 2.1.1 requires Werkzeug>=2.0, but you have werkzeug 0.16.1 which is incompatible

it's already two more years, Werkzeug is 2.1.2. still nobody fix the issue?

ERROR: flask 2.1.2 has requirement Werkzeug>=2.0, but you'll have werkzeug 0.16.1 which is incompatible.
ERROR: flask-login 0.6.1 has requirement Werkzeug>=1.0.1, but you'll have werkzeug 0.16.1 which is incompatible.

@NemoAng

Move to flask_restx, restplus will no longer be updated

Ask when this bug will be fixed?