I was refactoring the codebase at my company because there is a lot of tech debt. One of the things that I wanted was to have whitelisted methods in one place, but this was not a good approach, because it’s hard to keep track of those.
The other thing is to have a configuration script in which you can dynamically add or remove whitelisted methods and I came up with this script.
In the directory where hooks.py
is located create a new python file called whitelist_endpoint.py
and add this block of code
"""
Whitelist specific methods. Keep it here all-in-one
rather than separating it in different files.
Added on `hooks.py`
# before_request = ["<app_name>.whitelist_endpoint.run"]
"""
import asyncio
import importlib
import frappe
methods = [
{"scope": "modules.shipping", "fn": "get_rates_for_quotation"},
{
"scope": "modules.shipping",
"fn": "track_shipping",
"args": {"allow_guest": True},
},
]
async def add_to_whitelist(method):
args = method.get("args", {})
if "methods" not in args:
args["methods"] = ["GET"]
scope = importlib.import_module(
"<app_name>.{scope}".format(scope=method["scope"])
)
fn = getattr(scope, method["fn"])
whitelisted_method = frappe.whitelist(**args)(fn)
setattr(scope, method["fn"], whitelisted_method)
async def whitelist():
tasks: list = []
for e in methods:
tasks.append(add_to_whitelist(e))
_ = await asyncio.gather(*tasks)
def run(**_):
"""
Whitelist configured methods
"""
asyncio.run(whitelist())
In hooks.py
, add or modify before_request
hook.
before_request = ["<app_name>.whitelist_endpoint.run"]
This script will have a configuration of whitelisted method in one place. I’d like your opinion on this approach as well.