Last updated: Apr 11, 2024
Reading time·4 min
The Flask error "AssertionError: View function mapping is overwriting an existing endpoint function" occurs for 2 main reasons:
Here is a simple example of how the error occurs.
from flask import Flask app = Flask(__name__) @app.route("/") def main(): return "<p>Home: bobbyhadz.com</p>" @app.route("/about") def main(): return "<p>About: bobbyhadz.com</p>" # ⛔️ AssertionError: View function mapping is overwriting an existing endpoint function: main if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)
If I run my Flask application with python app.py
, the AssertionError
is
raised.
The cause of the error is that we have 2 view functions with the same name
(main
in the example).
/
and /about
), the two view functions cannot have the same name.You can resolve the issue by renaming the second view function so they no longer clash.
from flask import Flask app = Flask(__name__) @app.route("/") def main(): return "<p>Home: bobbyhadz.com</p>" @app.route("/about") def about(): return "<p>About: bobbyhadz.com</p>" if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)
Now the first view function is named main
and the second about
, so they no
longer clash.
You might also get the error when using multiple decorators for multiple view functions.
Here is an example.
from flask import Flask app = Flask(__name__) def exception_handler(func): def wrapper(*args, **kwargs): print('exception handled') return wrapper @app.route('/') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" @app.route('/about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>" # ⛔️ AssertionError: View function mapping is overwriting an existing endpoint function: wrapper if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)
Running my application with python app.py
produces the same AssertionError
.
We wrapped the two view functions with the same 2 decorators which caused the error.
You can resolve the issue by passing the endpoint
keyword argument in the call
to @app.route()
.
from flask import Flask app = Flask(__name__) def exception_handler(func): def wrapper(*args, **kwargs): print('exception handled') return wrapper # 1) Set the endpoint keyword argument @app.route('/', endpoint='home') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" # 2) Set the endpoint keyword argument @app.route('/about', endpoint='about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>" if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)
If I start my Flask application with python app.py
, everything works as
expected.
python app.py
Note that the value of the endpoint
argument has to be different for the
different routes.
# 1) Set the endpoint keyword argument @app.route('/', endpoint='home') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" # 2) Set the endpoint keyword argument @app.route('/about', endpoint='about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>"
If you specify the same endpoint
for multiple routes, the error is raised.
You can also solve the error by setting the name of the wrapper function in the decorator to a unique value.
from flask import Flask app = Flask(__name__) def exception_handler(func): def wrapper(*args, **kwargs): print('exception handled') # ✅ Set the name of the wrapper function to a unique value wrapper.__name__ = func.__name__ return wrapper @app.route('/') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" @app.route('/about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>" if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)
I made a change to the exception_handler
decorator function.
def exception_handler(func): def wrapper(*args, **kwargs): print('exception handled') # ✅ Set the name of the wrapper function to a unique value wrapper.__name__ = func.__name__ return wrapper
The decorator takes the view function as a parameter and sets the name of the
wrapper
function to the name of the view function.
This approach also solves the error, assuming your view functions have different names.
If your view functions have the same name (e.g. main
), using this approach
won't solve the error because we're simply setting the name
of the wrapper
function to the name of each view function.
You can also use the functools.wraps decorator to solve the error.
from functools import wraps from flask import Flask app = Flask(__name__) def exception_handler(func): # ✅ Using functools.wraps @wraps(func) def wrapper(*args, **kwargs): print('exception handled') return wrapper @app.route('/') @exception_handler def main(): return "<p>Home: bobbyhadz.com</p>" @app.route('/about') @exception_handler def about(): return "<p>About: bobbyhadz.com</p>" if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)
Make sure to import wraps
from functools
as shown in the code sample.
I used the wraps()
method in the decorator function.
from functools import wraps def exception_handler(func): # ✅ Using functools.wraps @wraps(func) def wrapper(*args, **kwargs): print('exception handled') return wrapper
The functools.wraps
decorator is used when defining a wrapper function.
Without the use of the @wraps()
decorator, the name of the function would have
been wrapper
.
Using the @wraps()
decorator enables us to preserve the name and the docstring
of the decorated function.
You might also get the error if you pass multiple view functions with the same
name to the app.add_url_rule()
method.
from flask import Flask app = Flask(__name__) # 1) View function named `main` def main(): return "<p>Home: bobbyhadz.com</p>" # 👇️ Passing view_func= main app.add_url_rule('/', view_func=main, methods=['GET']) # 2) View function named `main` again def main(): return "<p>About: bobbyhadz.com</p>" # 👇️ Passing view_func= main again app.add_url_rule('/about', view_func=main, methods=['GET']) # ⛔️ AssertionError: View function mapping is overwriting an existing endpoint function: main if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)
Running the code sample with python app.py
produces the same error.
Notice that we passed a view function with the name of main
twice to the
app.add_url_rule()
method.
To solve the error, rename the second view function so that the names don't clash.
from flask import Flask app = Flask(__name__) def main(): return "<p>Home: bobbyhadz.com</p>" # 1) View function named `main` app.add_url_rule('/', view_func=main, methods=['GET']) def about(): return "<p>About: bobbyhadz.com</p>" # 1) View function named `about` app.add_url_rule('/about', view_func=about, methods=['GET']) if __name__ == '__main__': app.run(debug=True, host='localhost', port=8000)
After renaming the second view function everything works as expected.
You can learn more about the related topics by checking out the following tutorials: