Search code examples
pythoncelerydecoratorpython-decorators

Python custom decorator not working with Celery tasks


I'm having a bit of trouble with Python decorators. I've got a scenario set up like so:

def decorated(func):
    def call_and_update(*args, **kwargs):
        # do some stuff here
        output = func(*args, **kwargs)
        # do more stuff here
        return output
    return call_and_update

@celery.task
@decorated
def testA():
    return "Test A"

@celery.task
@decorated
def testB():
    return "Test B"

For some reason, whichever function I call first seems to be persisted as the func in the decorator.

So for instance, if I start up a shell and run:

>>> testA()
Test A
>>> testB()
Test A

or, if I restart the shell and start with the second test:

>>> testB()
Test B
>>>> testA()
Test B

I found this question with a similar issue, but the few answers revolved around using extended classes for the task methods instead.

If I specifically want to do this via decorators and functions, is there a trick to getting that to work?

Note that without the @celery.task decorator, the functions work as normal. It's specifically the combination of the two decorators that's causing an issue.

Thanks!


Solution

  • Each task needs to have a unique name celery docs, since it's not provided it is using the name of your wrapper function.

    @celery.task(name='test-A')
    @decorated
    def testA():
        return 'test A'
    
    @celery.task(name='test-B')
    @decorated
    def testB():
        return 'test B'