Alguém sabe por que não consigo substituir uma função de endpoint existente se tenho duas regras 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"])
Traceback:
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
Respostas:
Os nomes de suas visualizações precisam ser únicos, mesmo que apontem para o mesmo método de visualização.
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'])
fonte
.as_view($VIEW_NAME)
chamada do método deve ser passado como um nome de string exclusivo.Esse mesmo problema aconteceu comigo quando eu tinha mais de uma função de API no módulo e tentei encapsular cada função com 2 decoradores:
Recebi a mesma exceção porque tentei encapsular mais de uma função com esses dois decoradores:
@app.route("/path1") @exception_handler def func1(): pass @app.route("/path2") @exception_handler def func2(): pass
Especificamente, é causado pela tentativa de registrar algumas funções com o wrapper de nome :
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
Alterar o nome da função resolveu para mim ( wrapper .__ name__ = func .__ name__ ):
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
Então, decorar mais de um ponto final funcionou.
fonte
functools.wraps
para alcançar a função de renomear.wrapper.__name__
vez dewrapper.func_name
. Talvez esta seja uma diferença entre python2 e python3?wrapper.__name__ = func.__name__
antes de chamar wrapper resolveu o problema.Para usuários que usam @ app.route, é melhor usar o argumento-chave em
endpoint
vez de buscar o valor de__name__
como Roei Bahumi declarou. Tomando seu exemplo será:@app.route("/path1", endpoint='func1') @exception_handler def func1(): pass @app.route("/path2", endpoint='func2') @exception_handler def func2(): pass
fonte
O Flask requer que você associe uma única 'função de visualização' a um 'ponto final'. Você está chamando
Main.as_view('main')
duas vezes, o que cria duas funções diferentes (exatamente a mesma funcionalidade, mas diferentes na assinatura de memória). História curta, você deve simplesmente fazermain_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"])
fonte
Gostaria apenas de adicionar a isso uma solução do tipo mais 'modelo'.
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
gostaria apenas de adicionar um artigo realmente interessante "Desmistificando decoradores" que encontrei recentemente: https://sumit-ghosh.com/articles/demystifying-decorators-python/
fonte
Isso também pode acontecer quando você tem nomes de função idênticos em rotas diferentes.
fonte
Se você acha que tem nomes de terminais exclusivos e ainda assim esse erro é fornecido, provavelmente você está enfrentando problemas . O mesmo foi o caso comigo.
Esse problema é com o frasco 0.10, caso você tenha a mesma versão, faça o seguinte para se livrar disso:
sudo pip uninstall flask sudo pip install flask=0.9
fonte
Há uma correção para o problema do Flask # 570 introduzido recentemente (flask 0,10) que faz com que essa exceção seja levantada.
Veja https://github.com/mitsuhiko/flask/issues/796
Portanto, se você acessar flask / app.py e comentar as 4 linhas 948..951, isso pode ajudar até que o problema seja totalmente resolvido em uma nova versão.
A diferença dessa mudança está aqui: http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1
fonte
Seus nomes de visualização precisam ser exclusivos, mesmo se estiverem apontando para o mesmo método de visualização, ou você pode adicionar a partir de funções de importação wraps e usar @wraps https://docs.python.org/2/library/functools.html
fonte
use o flask 0.9 em vez dos seguintes comandos
sudo pip uninstall flask
sudo pip install flask==0.9
fonte
Adicionar
@wraps(f)
acima a função de invólucro resolveu meu problema.def list_ownership(f): @wraps(f) def decorator(*args,**kwargs): return f(args,kwargs) return decorator
fonte