Use a decorator!
A decorator is a wrapper that takes a function as it's argument:
def decorate(func):
def wrapper(*args, **kwargs):
# *args and **kwargs are input vars passed to func() on its call
return f(*args, **kwargs)
return wrapper
@decorate
def func(arg1, arg2, **kwargs):
#do_things
In your case, this would look like:
def run_in_background(func):
def wrapper(*args, **kwargs):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
# remember, data is in *args (or **kwargs if it's a keyword arg)
loop.run_in_executor(None, func, data)
return None
return wrapper
@run_in_background
# data is an arg or positional arg here, but could easily be data=data
def update_contents(data):
# function logic
Edit: Not always a background process:
You could change your decorator to switch between background and not:
def run_in_background(func):
def wrapper(*args, **kwargs):
if background:
# run in background
else:
func(data)
return None
return wrapper
@run_in_background
def update_contact(data, background=False):
#contact func logic
That will allow you to keep your decorator and reduce code duplication, while giving you the flexibility to specify if you want a background process or not