Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Get original function arguments in decorator

I am trying to write a "login_required" decorator for the views in a WSGI+Werkzeug application.

In order to do this, I need to get at the user's session, which is accessible via the Request object that is passed into the view methods.

I can't figure out how to get at that instance of Request in the decorator, though. I looked at PEP318, specifically the fourth example, but I'm not quite getting it.

Here's what I'm trying:

def login_required(*args, **kw):     def goto_login(**kw):         return redirect(url_for('login'))      def decorate(f):         # args[0] should be request         args[0].client_session['test'] = True         logged_in = 0         if logged_in:             return f         else:             return goto_login     return decorate   @login_required() @expose('/hello/<string:name>') def hello(request, name):     return render_template('say_hello.html', name=name) 

but I get an index out of bounds error trying to call args[0].

Is there any way I can get access to the request argument passed into the "hello" function in the "login_required" decorator?

like image 601
ashgromnies Avatar asked Jun 17 '09 23:06

ashgromnies


People also ask

How do you pass arguments in decorator functions in Python?

To fix this, you need to change the repeat decorator so that it accepts an argument that specifies the number of times a function should execute like this: @repeat(5) def say(message): ... To define the repeat decorator, the repeat(5) should return the original decorator. The new repeat function returns a decorator.

Why decorators in Python are pure genius?

Decorators are a prime-time example of a perfectly implemented feature. It does take a while to wrap your head around, but it's worth it. As you start using them, you'll notice how they don't overcomplicate things and make your code neat and snazzy.

Can decorator take arguments Python?

Implementing Decorator Arguments You may expect that decorator arguments are somehow passed into the function along with this f argument, but sadly Python always passes the decorated function as a single argument to the decorator function.

What does a decorator return Python?

Decorators in Python are very powerful which modify the behavior of a function without modifying it permanently. It basically wraps another function and since both functions are callable, it returns a callable. In hindsight, a decorator wraps a function and modifies its behavior.


1 Answers

The decorator login_required is passed the function (hello in this case).

So what you want to do is:

def login_required(f):     # This function is what we "replace" hello with     def wrapper(*args, **kw):         args[0].client_session['test'] = True         logged_in = 0         if logged_in:             return f(*args, **kw)  # Call hello         else:             return redirect(url_for('login'))     return wrapper 
like image 181
brian-brazil Avatar answered Sep 19 '22 20:09

brian-brazil