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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions