I have to create a decorator that has parameters, and uses those parameters to modify a function also with parameters. This is a general question of how to decorate any function with parameters with additional parameters, but for my specific case, I need it for Django RQ, to determine based on an environment variable whether to use an asynchronous queue that is activated through a decorator.
There is a function in Django RQ called django_rq.job
that I use like this (it requires args
and kwargs
):
@django_rq.job('default', timeout=3600, result_ttl=86400)
def upload_missing_documents_s3(batches, projects, uuid_val):
pass
# A simpler example:
@django_rq.job('default', timeout=3600, result_ttl=86400)
def sample(content):
file = open("temp/sample.txt", "w+")
file.write(content)
file.close()
I need to essentially create a decorator that will take a boolean value and return either the modified function (with a job) or the unmodified function (no job). But I can't seem to figure it out, because there are two sets of parameters. I tried something like this:
#My attempt, I don't think it works...
def conditional_django_job(function_name, *args, **kwargs):
if settings.NO_QUEUE:
return function_name
else:
return django_rq.job("default", None, *args, **kwargs)(function_name)
@conditional_django_job('default', timeout=3600, result_ttl=86400)
def sample(content):
file = open("temp/sample.txt", "w+")
file.write(content)
file.close()
I also tried with an inner function, but I can't seem to get it right. How do I implement a decorator with parameters that decorates a function?
I tried looking at this SO question but it didn't seem to have an example where both the decorator and the function have parameters: How to make function decorators and chain them together?
Thank you!