Pass cap parameters to decorator

I wrote a decorator that tries to verify that we have data for the POST route:

Here is my decorator:

def require_post_data(required_fields=None): def decorator(f): @wraps(f) def decorated_function(*args, **kwargs): for required_field in required_fields: if not request.form.get(required_field, None): return jsonify({"error": "Missing %s from post data." % required_field}), 400 else: if not request.form: return jsonify({"error": "No post data, aborting."}), 400 return f(*args, **kwargs) return decorated_function return decorator 

And I have two routes, with the URL parameter and the other without:

 from flask import Blueprint, jsonify, request mod = Blueprint('contacts', __name__, url_prefix='/contacts') @mod.route('/', methods=['POST']) @require_post_data(['customer_id', 'some_other_required_field']) def create_contact(): # Do some business @mod.route('/<int:contact_id>', methods=['POST']) @require_post_data def update_contact(contact_id): # Do some business 

When I run a test that falls into update_contact , I get the following exception:

 TypeError: decorator() got an unexpected keyword argument 'contact_id' 

But it seems that create_contact working as expected.

Why is contact_id passed to decorator() ?

+4
source share
1 answer

I believe that you are just missing one thing that actually calls require_post_data to create a decorator function in the update_contact route. This should fix this:

 @mod.route('/<int:contact_id>', methods=['POST']) @require_post_data() # <- note the parens def update_contact(contact_id): # Do some business 

A detailed explanation is that what you expected (and what happens in create contact ) is that the view function is modified using the decorator created by require_post_data . In your update_contact above, what is actually happening is that the view function is passed to require_post_data itself and just used as the value of the required_fields parameter. This does not cause an error, therefore require_post_data happily returns a decorator , which is then redirected when you press /<int> , as a result of which it passes contact_id as a keyword argument, resulting in an error.

+8
source

Source: https://habr.com/ru/post/1500433/


All Articles