Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask app wont launch 'ImportError: cannot import name 'cached_property' from 'werkzeug' '

I've been working on a Flask app for a few weeks. I finished it today and went to deploy it... and now it won't launch.

I haven't added or removed any code so assume something has changed in the deployment process?

Anyway, here is the full error displayed in the terminal:

Traceback (most recent call last):
  File "C:\Users\Kev\Documents\Projects\Docket\manage.py", line 5, in <module>
    from app import create_app, db
  File "C:\Users\Kev\Documents\Projects\Docket\app\__init__.py", line 21, in <module>
    from app.api import api, blueprint, limiter
  File "C:\Users\Kev\Documents\Projects\Docket\app\api\__init__.py", line 2, in <module>
    from flask_restplus import Api
  File "C:\Users\Kev\.virtualenvs\Docket-LasDxOWU\lib\site-packages\flask_restplus\__init_
_.py", line 4, in <module>
    from . import fields, reqparse, apidoc, inputs, cors
  File "C:\Users\Kev\.virtualenvs\Docket-LasDxOWU\lib\site-packages\flask_restplus\fields.
py", line 17, in <module>
    from werkzeug import cached_property
ImportError: cannot import name 'cached_property' from 'werkzeug' (C:\Users\Kev\.virtualen
vs\Docket-LasDxOWU\lib\site-packages\werkzeug\__init__.py)

Also here's the code in the three files mentioned.

manage.py:

from apscheduler.schedulers.background import BackgroundScheduler
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand

from app import create_app, db

app = create_app()
app.app_context().push()

manager = Manager(app)

migrate = Migrate(app, db)

manager.add_command('db', MigrateCommand)

from app.routes import *
from app.models import *

def clear_data():
    with app.app_context():
        db.session.query(User).delete()
        db.session.query(Todo).delete()
        db.session.commit()
        print("Deleted table rows!")

@manager.command
def run():
    scheduler = BackgroundScheduler()
    scheduler.add_job(clear_data, trigger='interval', minutes=15)
    scheduler.start()
    app.run(debug=True)

if __name__ == '__main__':
    clear_data()
    manager.run()

app/__init__.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager

from config import Config

db = SQLAlchemy()

login = LoginManager()

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    db.init_app(app)

    login.init_app(app)
    login.login_view = 'login'

    from app.api import api, blueprint, limiter
    from app.api.endpoints import users, todos, register
    from app.api.endpoints.todos import TodosNS
    from app.api.endpoints.users import UserNS
    from app.api.endpoints.register import RegisterNS

    api.init_app(app)

    app.register_blueprint(blueprint)

    limiter.init_app(app)

    api.add_namespace(TodosNS)
    api.add_namespace(UserNS)
    api.add_namespace(RegisterNS)

    return app

api/__init__.py:

from logging import StreamHandler
from flask_restplus import Api
from flask import Blueprint
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

blueprint = Blueprint('api', __name__, url_prefix='/api')

limiter = Limiter(key_func=get_remote_address)
limiter.logger.addHandler(StreamHandler())

api = Api(blueprint, doc='/documentation', version='1.0', title='Docket API',
          description='API for Docket. Create users and todo items through a REST API.\n'
                      'First of all, begin by registering a new user via the registration form in the web interface.\n'
                      'Or via a `POST` request to the `/Register/` end point', decorators=[limiter.limit("50/day", error_message="API request limit has been reached (50 per day)")])

I've tried reinstalling flask & flask_restplus but no-luck.

like image 1000
Keva161 Avatar asked Feb 10 '20 18:02

Keva161


People also ask

Can I import cached_property from functools?

In python 3.8 you can from functools import cached_property – Martin Thoma Feb 13 '20 at 12:39 Add a comment | 6 Answers 6 ActiveOldestVotes 25 The proper answer for May 2020: flask-restplus is dead, move to flask-restx.

How to fix Werkzeug error in Jarus/flask-testing?

Fix version Werkzeug==0.16.1 for fix error in this: jarus/flask-testi… add 'Werkzeug==0.16.1' to fix python unit tests import error - see th… Load more… Pin Werkzeug dependency to make sure unittests keep running while jarus/flask-testing#143 is still open.

What happened to flask_restplus?

The flask_restplus project is dead, and is now creating serious issues in combination with Werkzeug 1.0.0+: ImportError: cannot import name 'cached_property' from 'werkzeug' It's successor is flask_restx, which does work with newer versions of Werkzeug:

What happened to the %cached_property in Werkzeug?

cached_property was recently moved to werkzeug.utils in the 1.0 releas. Which version of werkzeug are you using? If you're on an older version try imprint directly from werkzeug. by downgrading werkzeug.utils to Werkzeug==0.16.1 , resolved my issue


2 Answers

The proper answer for May 2020: flask-restplus is dead, move to flask-restx.

From noirbizarre/flask-restplus#778 (comment):

flask-restplus work has been discontinued due to maintainers not having pypi keys. See the drop in replacement, flask-restx. It's an official fork by the maintainer team. We have already fixed the issue there

From noirbizarre/flask-restplus#777 (comment):

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 the real solution is to move to flask-restx rather than pinning to an old version of Werkzeug.

like image 153
noraj Avatar answered Oct 17 '22 12:10

noraj


Downgrading to Werkzeug==0.16.1 solves this

see https://github.com/noirbizarre/flask-restplus/issues/777#issuecomment-583235327

EDIT

Wanted to add that a permanent(long term) solution would be to move to flask_restx as flask-restplus is no longer being maintained.

See how to migrate from flask-restplus

like image 20
Chidiebere Avatar answered Oct 17 '22 14:10

Chidiebere