¿Alguien sabe por qué no puedo sobrescribir una función de punto final existente si tengo dos reglas de URL como esta?
app.add_url_rule('/',
view_func=Main.as_view('main'),
methods=["GET"])
app.add_url_rule('/<page>/',
view_func=Main.as_view('main'),
methods=["GET"])
Rastrear:
Traceback (most recent call last):
File "demo.py", line 20, in <module> methods=["GET"])
File ".../python2.6/site-packages/flask/app.py",
line 62, in wrapper_func return f(self, *args, **kwargs)
File ".../python2.6/site-packages/flask/app.py",
line 984, in add_url_rule 'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint
function: main
Respuestas:
Los nombres de sus vistas deben ser únicos incluso si apuntan al mismo método de vista.
app.add_url_rule('/', view_func=Main.as_view('main'), methods = ['GET']) app.add_url_rule('/<page>/', view_func=Main.as_view('page'), methods = ['GET'])
fuente
.as_view($VIEW_NAME)
método $ VIEW_NAME in debe pasarse como un nombre de cadena único.Este mismo problema me sucedió cuando tenía más de una función API en el módulo y traté de envolver cada función con 2 decoradores:
Obtuve esta misma excepción porque intenté envolver más de una función con esos dos decoradores:
@app.route("/path1") @exception_handler def func1(): pass @app.route("/path2") @exception_handler def func2(): pass
Específicamente, se produce al intentar registrar algunas funciones con el contenedor de nombres :
def exception_handler(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: error_code = getattr(e, "code", 500) logger.exception("Service exception: %s", e) r = dict_to_json({"message": e.message, "matches": e.message, "error_code": error_code}) return Response(r, status=error_code, mimetype='application/json') return wrapper
Cambiar el nombre de la función lo resolvió para mí ( envoltorio .__ nombre__ = func .__ nombre__ ):
def exception_handler(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: error_code = getattr(e, "code", 500) logger.exception("Service exception: %s", e) r = dict_to_json({"message": e.message, "matches": e.message, "error_code": error_code}) return Response(r, status=error_code, mimetype='application/json') # Renaming the function name: wrapper.__name__ = func.__name__ return wrapper
Luego, la decoración de más de un punto final funcionó.
fuente
functools.wraps
para lograr el cambio de nombre de la función.wrapper.__name__
lugar dewrapper.func_name
. ¿Quizás esta es una diferencia entre python2 y python3?wrapper.__name__ = func.__name__
antes de llamar al contenedor resolvió el problema.Para los usuarios que usan @ app.route, es mejor usar el argumento clave en
endpoint
lugar de cambiar el valor__name__
como dijo Roei Bahumi . Tomando su ejemplo será:@app.route("/path1", endpoint='func1') @exception_handler def func1(): pass @app.route("/path2", endpoint='func2') @exception_handler def func2(): pass
fuente
Flask requiere que asocie una sola 'función de vista' con un 'punto final'. Está llamando
Main.as_view('main')
dos veces, lo que crea dos funciones diferentes (exactamente la misma funcionalidad pero diferente en la firma de memoria). Historia corta, simplemente debes hacermain_view_func = Main.as_view('main') app.add_url_rule('/', view_func=main_view_func, methods=["GET"]) app.add_url_rule('/<page>/', view_func=main_view_func, methods=["GET"])
fuente
Solo me gustaría agregar a esto una solución de tipo más 'plantilla'.
def func_name(f): def wrap(*args, **kwargs): if condition: pass else: whatever you want return f(*args, **kwargs) wrap.__name__ = f.__name__ return wrap
me gustaría agregar un artículo realmente interesante "Desmitificando a los decoradores" que encontré recientemente: https://sumit-ghosh.com/articles/demystifying-decorators-python/
fuente
Esto también puede suceder cuando tiene nombres de funciones idénticos en diferentes rutas.
fuente
Si cree que tiene nombres de puntos finales únicos y aún se da este error, entonces probablemente esté enfrentando un problema . Lo mismo sucedió conmigo.
Este problema es con el frasco 0.10 en caso de que tenga la misma versión, haga lo siguiente para deshacerse de esto:
sudo pip uninstall flask sudo pip install flask=0.9
fuente
Hay una solución para el problema de Flask # 570 introducido recientemente (frasco 0.10) que hace que se genere esta excepción.
Ver https://github.com/mitsuhiko/flask/issues/796
Entonces, si va a flask / app.py y comenta las 4 líneas 948..951, esto puede ayudar hasta que el problema se resuelva por completo en una nueva versión.
La diferencia de ese cambio está aquí: http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1
fuente
Los nombres de sus vistas deben ser únicos incluso si apuntan al mismo método de vista, o puede agregar desde functools import wraps y usar @wraps https://docs.python.org/2/library/functools.html
fuente
use el matraz 0.9 en su lugar use los siguientes comandos
sudo pip uninstall flask
sudo pip install flask==0.9
fuente
Agregar
@wraps(f)
arriba la función de contenedor resolvió mi problema.def list_ownership(f): @wraps(f) def decorator(*args,**kwargs): return f(args,kwargs) return decorator
fuente