Question: I am building a webapp using Flask. I imported the flask-login library to handle user login. But it shows an ImportError. Below is my folder structure: >flask_blog1 >flaskblog >static >templates >__init__.py >forms.py >models.py >routes.py >instance >site.db >venv >requirements.txt >run.py  My run.py: from flaskblog import app if __name__ == "__main__": app.run(debug=True)  My __init__.py: from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_bcrypt import Bcrypt from flask_login import LoginManager app = Flask(__name__) app.config["SECRET_KEY"] = "5791628bb0b13ce0c676dfde280ba245" app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///site.db" db = SQLAlchemy(app) bcrypt = Bcrypt(app) login_manager = LoginManager(app) from flaskblog import routes  My models.py: from datetime import datetime # from .extensions import db from flaskblog import db, login_manager from flask_login import UserMixin @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) image_file = db.Column(db.String(20), nullable=False, default="default.jpg") password = db.Column(db.String(60), nullable=False) posts = db.relationship("Post", backref="author", lazy=True) def __repr__(self): return f"User('{self.username}', '{self.email}', '{self.image_file}')" class Post(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100), nullable=False) date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) content = db.Column(db.Text, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) def __repr__(self): return f"Post('{self.title}', '{self.date_posted}')"  My routes.py: from flask import render_template, flash, redirect, url_for from flaskblog import app, db, bcrypt from flaskblog.forms import RegistrationForm, LoginForm from flaskblog.models import User, Post from flask_login import login_user posts = [ { "author": "Ashutosh Chapagain", "title": "Blog Post 1", "content": "First Post Content", "date_posted": "October 1, 2023", }, { "author": "Ash Dhakal", "title": "Blog Post 2", "content": "Second Post Content", "date_posted": "October 2, 2023", }, ] @app.route("/") @app.route("/home") def home(): return render_template("home.html", posts=posts) @app.route("/about") def about(): return render_template("about.html", title="About") @app.route("/register", methods=["GET", "POST"]) def register(): form = RegistrationForm() if form.validate_on_submit(): hashed_password = bcrypt.generate_password_hash(form.password.data).decode( "utf-8" ) user = User( username=form.username.data, email=form.email.data, password=hashed_password ) db.session.add(user) db.session.commit() flash(f"Your account has been created! You are now able to log in!", "success") return redirect(url_for("login")) return render_template("register.html", title="Register", form=form) @app.route("/login", methods=["GET", "POST"]) def login(): form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() if user and bcrypt.check_password_hash(user.password, form.password.data): login_user(user, remember=form.remember.data) return redirect(url_for("home")) else: flash("Login Unsuccessful. Please check email and password", "danger") return render_template("login.html", title="Login", form=form)  My forms.py: from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField, BooleanField from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError from flaskblog.models import User class RegistrationForm(FlaskForm): username = StringField( "Username", validators=[DataRequired(), Length(min=2, max=20)] ) email = StringField("Email", validators=[DataRequired(), Email()]) password = PasswordField("Password", validators=[DataRequired()]) confirm_password = PasswordField( "Confirm Password", validators=[DataRequired(), EqualTo("password")] ) submit = SubmitField("Sign Up") def validate_username(self, username): user = User.query.filter_by(username=username.data).first() if user: raise ValidationError( "That username is taken. Please choose a different one." ) def validate_email(self, email): user = User.query.filter_by(email=email.data).first() if user: raise ValidationError("That email is taken. Please choose a different one.") class LoginForm(FlaskForm): email = StringField("Email", validators=[DataRequired(), Email()]) password = PasswordField("Password", validators=[DataRequired()]) remember = BooleanField("Remember Me") submit = SubmitField("Login")  The exact error is: (venv) asu@asu-Lenovo-Legion-5-15ARH05:/media/asu/Data/Projects/flask_blog1$ python3 run.py Traceback (most recent call last): File "/media/asu/Data/Projects/flask_blog1/run.py", line 1, in <module> from flaskblog import app File "/media/asu/Data/Projects/flask_blog1/flaskblog/__init__.py", line 4, in <module> from flask_login import LoginManager File "/media/asu/Data/Projects/flask_blog1/venv/lib/python3.10/site-packages/flask_login/__init__.py", line 12, in <module> from .login_manager import LoginManager File "/media/asu/Data/Projects/flask_blog1/venv/lib/python3.10/site-packages/flask_login/login_manager.py", line 33, in <module> from .utils import _create_identifier File "/media/asu/Data/Projects/flask_blog1/venv/lib/python3.10/site-packages/flask_login/utils.py", line 14, in <module> from werkzeug.urls import url_decode ImportError: cannot import name 'url_decode' from 'werkzeug.urls' (/media/asu/Data/Projects/flask_blog1/venv/lib/python3.10/site-packages/werkzeug/urls.py) 

Answer: I can only assume you got the Werkzeug 3.0 update (as flask-login didn't up-bound their werkzeug dependency). In their ongoing quest to remove all the non-core public APIs of werkzeug, the developers deprecated most of werkzeug.urls in Werkzeug 2.3 (released April 25th 2023), and removed it in Werkzeug 3.0 (released September 30th 2023). Your options are:  force werkzeug to a pre-3.0 version  wait for flask-login to release a version compatible with werkzeug 3, a fix of that and a bunch of other stuff was merged a few minutes ago edit: flask-login 0.6.3 with the compatibility fix was released October 30th: https://github.com/maxcountryman/flask-login/releases/tag/0.6.3