Python Decorator Functions Explained through an example of security.

~/Untitled.html


Python Decorators in action

I never really knew or understood why we actually needed python decorator functions in the first place. But after a brief stint with django, I do.

One of the good reasons to use decorators is for a purpose called Aspect Oriented Programming – those of you who know and use the Spring framework might be familiar with it – it’s the practice of isolating various Aspects of your job into a seaparate MOdule , or function. E.g: SEcurity, LOgging, etc.

If all of your function require that a user be logged in before he be able to execute that function – you can take two ways – check whether the user is blacklisted in every function, by writing 2-3 lines of code, or you can use decorator functions like this :

def check_whether_user_is_blacklisted(func):
    def inner(*args, **kwargs):
        if kwargs['username'] == 'Ramm':
            print "Sorry, Ramm is not allowed on our site."
        else:
            func(*args, **kwargs)
        return inner
@check_whether_user_is_blacklisted
def myfunc(username="Stein"):
print "Hey %s, you're logged in !" % ( username)
myfunc("test")
myfunc("Ramm")

Note the @ syntax – similar to java – was adopted after python 2.4 ( we’re in the age of python 3k, so no worries – you probably have python 2.4 installed. )

the myfunc ( a function object ) is automatically passed to check_whether_user_is_authenticated as the argument, and that function instead replaces myfunc with another function defined inside it – inner.

The inner function, as you can see – applies an additional check to see whether the user is blacklisted or not. If not, it executes the original function myfunc. If he is blacklisted, the function prints a message and exits.

so,

myfunc(“test”) – will print “Hey test, you’re logged in!”
myfunc(“Ramm”) – will print, “Sorry, Ramm is not allowed on our site.”

So, just by adding a line “@check_whether_user_is_blacklisted” before any of our functions that we don’t want blacklisted users to be able to execute, we can achieve this effect.

[  Courtesy SmileyChris ]:

Here’s another hint, use “wraps” to make the decorated function retain the docstring and any other view attributes:

from django.utils.functional import wraps
def check_whether_user_is_blacklisted(func):
    @wraps(func)
    def inner(*args, **kwargs):


Happy decorating !

-anonymouscowherd

Advertisement

3 Comments »

  1. SmileyChris said

    Here’s another hint, use “wraps” to make the decorated function retain the docstring and any other view attributes:

    from django.utils.functional import wraps

    def check_whether_user_is_blacklisted(func):
    @wraps(func)
    def inner(*args, **kwargs):

    • anonymouscowherd said

      Thanks – tried it and it works :D

  2. Great post.. this is really a great information..This will be useful post.. I will

    comeback for more..

    Cheers,
    gadgettechblog.com

RSS feed for comments on this post · TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.