code

AssertionError : 뷰 함수 매핑이 기존 끝점 함수를 덮어 씁니다 : main

codestyles 2020. 12. 27. 10:53
반응형

AssertionError : 뷰 함수 매핑이 기존 끝점 함수를 덮어 씁니다 : main


이와 같은 두 개의 URL 규칙이있는 경우 기존 엔드 포인트 기능을 덮어 쓸 수없는 이유를 아는 사람이 있습니까?

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 (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

보기 이름은 동일한보기 방법을 가리키는 경우에도 고유해야합니다.

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'])

모듈에 API 함수가 두 개 이상 있고 각 함수를 2 개의 데코레이터로 래핑하려고 할 때 이와 동일한 문제가 발생했습니다.

  1. @ app.route ()
  2. 내 맞춤 @exception_handler 데코레이터

이 두 데코레이터로 둘 이상의 함수를 래핑하려고했기 때문에 동일한 예외가 발생했습니다.

@app.route("/path1")
@exception_handler
def func1():
    pass

@app.route("/path2")
@exception_handler
def func2():
    pass

특히 wrapper 라는 이름으로 몇 가지 함수를 등록하려고 할 때 발생합니다 .

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

함수의 이름을 변경하면 문제가 해결되었습니다 ( 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

그런 다음 둘 이상의 엔드 포인트를 장식하는 것이 효과가있었습니다.


For users that use @app.route it is better to use the key-argument endpoint rather then chaning the value of __name__ like Roei Bahumi stated. Taking his example will be:

@app.route("/path1", endpoint='func1')
@exception_handler
def func1():
    pass

@app.route("/path2", endpoint='func2')
@exception_handler
def func2():
    pass

Flask requires you to associate a single 'view function' with an 'endpoint'. You are calling Main.as_view('main') twice which creates two different functions (exactly the same functionality but different in memory signature). Short story, you should simply do

main_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"])

I would just like to add to this a more 'template' type solution.

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

would just like to add a really interesting article "Demystifying Decorators" I found recently: https://sumit-ghosh.com/articles/demystifying-decorators-python/


If you think you have unique endpoint names and still this error is given then probably you are facing issue. Same was the case with me.

This issue is with flask 0.10 in case you have same version then do following to get rid of this:

sudo pip uninstall flask
sudo pip install flask=0.9

There is a fix for Flask issue #570 introduced recenty (flask 0.10) that causes this exception to be raised.

See https://github.com/mitsuhiko/flask/issues/796

So if you go to flask/app.py and comment out the 4 lines 948..951, this may help until the issue is resovled fully in a new version.

The diff of that change is here: http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1


Your view names need to be unique even if they are pointing to the same view method, or you can add from functools import wraps and use @wraps https://docs.python.org/2/library/functools.html


use flask 0.9 instead use the following commands sudo pip uninstall flask

sudo pip install flask==0.9

This can happen also when you have identical function names on different routes.

ReferenceURL : https://stackoverflow.com/questions/17256602/assertionerror-view-function-mapping-is-overwriting-an-existing-endpoint-functi

반응형