@api.route('/api/get_contacts')
def get_contacts():
with pymongo.MongoClient(f"mongodb+srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxxx?retryWrites=true&w=majority") as document:
This is too much to look at. I am trying to make it into:
@api.route('/api/get_contacts')
@mongo
def get_contacts():
The problem is, I don't really understand decorators. So, this is what I have done so far:
def mongo(f):
@wraps(f)
def wrap (*args,**kwargs):
with pymongo.MongoClient(f"mongodb+srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxx?retryWrites=true&w=majority") as document:
return f(document)
return wrap
Not sure what I need to do to get the decorator to prepend the code with the 'with operator', and pass x, then the document back to the route function.
Decorators works basically by replacing your function, with decorator(function)
. For instance:
@decorator
def my_function():
pass
Equals to
def my_function():
pass
my_function = decorator(my_function)
It means that you can return a callable function from the decorator, that every time you call it with arguments it will call the decorated function with the particular arguments.
For example:
import functools
def decorator(decorated_function):
@functools.wraps(decorated_function) # This means that the function that returns from this decorator, "wrapper", will keep the decorated_function's name, `__doc__` argument and more.
def wrapper(*args, **kwargs):
"""
Every time you will call the function that returned from the decorator, this function will be called with the particular arguments in args and kwargs.
"""
return decorated_function(*args, **kwargs) + 10
return wrapper
@decorator
def func(n):
return n * 2
result = func(2) # here we called the function `wrapper`, the result is func(2) + 10, as we did when we called the function.
print(result) # 14
We can also print(func)
and the result will be something like
<function func at 0x7f5eb16b0040>
, and if we didn't use functools.wraps
: <function decorator.<locals>.wrapper at 0x7fba9ba0f040>
.
Now for your question, when you stack decorators,
@c
@b
@a
def func(): pass
the order is
c(b(a(func)))
And hence, your function named mongo
should take the argument "request" from api.route('/api/get_contacts')
. (I don't know what framework this is, so I can't predict whether this framework supplies the request as a function argument).
if the framework does not pass the request as an argument:
def mongo(f):
@functools.wraps(f)
def wrap():
with pymongo.MongoClient(f"mongodb+srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxx?retryWrites=true&w=majority") as document:
return f(document)
return wrap
and if it does:
def mongo(f):
@functools.wraps(f)
def wrap(request):
# do something with the request
with pymongo.MongoClient(f"mongodb+srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxx?retryWrites=true&w=majority") as document:
return f(document)
return wrap
And then it allows you to do this:
@api.route('/api/get_contacts')
@mongo
def get_contacts(document):
pass