I'm currently refactoring a larger code base which uses Flask. I see a lot of duplication around parameter checks. It's similar to this:
@api.route("/foo/bar/<string:content_id>")
def get_foo(content_id):
try:
content = get_content(content_id)
except:
return jsonify({"status": 404, "error": "not found"}), 404
...
@api.route("/foo/bar/<string:content_id>/update")
def update_foo(content_id):
try: # This is exactly the same!
content = get_content(content_id) # It's just copy-pasted
except: # and this way a lot of duplication
return jsonify({"status": 404, "error": "not found"}), 404 # is added! I want to reduce that.
...
The checks are longer and there are way more of them, but I hope this illustrates the issue well.
Is it possible to factor this check out? Maybe by using a decorator? How would that look like?
What I want
I would love to have something like this:
def get_content_validator():
try:
content = get_content(content_id)
except:
return jsonify({"status": 404, "error": "not found"}), 404
return content
@api.route("/foo/bar/<get_content_validator(string:content_id)>")
def get_foo(content_id):
...
@api.route("/foo/bar/<get_content_validator(string:content_id)>/update")
def update_foo(content):
...
The issue with that is that in one case the value is returned and the normal execution of get_foo
/ update_foo
is done and in other cases the function body of get_foo
/ update_foo
is not executed. This could be possible by checking the return type. If it's a "response" return type, the response is given. In all other cases it's just returned. But that sounds as if it could result in other issues.