Skip to content

Jak udekorować funkcję, która ma już dekorator @app.get() #25

@Obsttube

Description

@Obsttube

W moim kodzie wielokrotnie powtarza się

if session_token is None:
        response.status_code = status.HTTP_401_UNAUTHORIZED
        return "Log in to access this page."

(patrz: https://github.com/Obsttube/daftcode-python-lvlup-2020/blob/master/main.py)
Side note: Ciekawe ile osób inspiruje się rozwiązaniami osób z issues, bo przecież kod każdego uczestnika jest publiczny 🤔

Chciałem użyć dekoratora, aby uniknąć powtarzania kodu.

Dla testów przygotowałem prostszą funkcję:

@app.get("/welcome")
def welcome(session_token: str = Cookie(None)):
    print(session_token) # wypisywanie do konsoli
    return "test"

Chciałem wykorzystać dekorator w uproszczeniu o tak:

def wrapper(callable):
    def inner(session_token: str = Cookie(None)):
        print(session_token)
        val = callable()
        return val
    return inner

@app.get("/welcome")
@wrapper
def welcome():
    return "test"

I jest wszystko spoko, printuje mi "961cdcfff43432b22bec6c22c3c958e1e571d0d8ffb81807d8d3f0543ca5e515", czyli wartość ciasteczka.

Problem pojawia się wtedy, gdy w welcome chcę mieć dowolne inne argumenty np. request:

def wrapper(callable):
    @wraps(callable) # bez wraps *args i **kwargs nie chce działać (nawet bez session_token)
    def inner(session_token: str = Cookie(None), *args, **kwargs):
        print(session_token)
        val = callable(*args, **kwargs)
        return val
    return inner

@app.get("/welcome")
@wrapper
def welcome(request: Request):
    return "test"

Wtedy print(session_token) printuje mi "extra={}"

Okazuje się, że @wraps(callable) to powoduje. Gdy w poprzednim przykładzie dodaję @wraps, również printuje mi "extra={}" zamiast ciasteczka. Niestety przykład z *args i **kwargs nie chce działać bez @wraps.

Jak to zrobić poprawnie?
Tzn. tak, aby mieć dowolne argumenty w welcome() oraz session_token w inner().
Da się to w ogóle zrobić?

Jakie mieliście doświadczenia z dekorowaniem @app... ? Robi się takie rzeczy w praktyce?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions