Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it acceptable to use **kwargs and a decorator to prevent repetitive code?

I'm currently writing an api library in python and I'm wondering if the following code is too unpythonic:

@accepts('video_id', 'reference_id', 'page_size', 'page_number',
         'get_item_count', 'fields', 'video_fields', 'custom_fields',
         'media_delivery', 'output')
@requires('video_id', 'reference_id')
def find_related_videos(self, **params):
    return ItemCollection(read_request(params))

The accepts decorator throws an error if any kwargs not in the the list are passed to the method. It also does validation for certain keywords.

The requires decorator ensures that those keyword arguments are present.

Not having the keyword args in the method definition is bugging me. However, having to build the params dictionary manually for each method also seems annoying. Also, there is validation code that is the same for every instance of the video_fields argument passed to a method, so I can call that from the accepts decorator to avoid repeating myself.

Thoughts?

like image 457
jbeluch Avatar asked Nov 28 '25 22:11

jbeluch


2 Answers

I'd definitely put the required fields in the method signature:

def find_related_videos(self, video_id, reference_id, **params):
    params.update({'video_id': video_id, 'reference_id': reference_id})
    return ItemCollection(read_request(params))

If possible, I'd even modify read_request to take keyword arguments as well:

def find_related_videos(self, video_id, reference_id, **params):
    return ItemCollection(read_request(video_id=video_id, reference_id=reference_id, **params))

As far as acceptable params go, personally I wouldn't throw errors for invalid params -- I'd just ignore the ones I didn't need.

like image 186
mipadi Avatar answered Dec 01 '25 12:12

mipadi


How about this solution?

def check_params(params):
    # Do whatever check you want to do on params
    return dict((k, v) for k, v in params
                if v is not None and k != "self")

def find_related_videos(self, video_id, reference_id, page_size=None,
                        page_number=None, get_item_count=None, fields=None,
                        video_fields=None, custom_fields=None,
                        media_delivery=None, output=None):
    params = check_prams(locals())
    return ItemCollection(read_request(params))

This will leave checking for acceptable and required parameters to Python, while facitlitating custom tests in check_params().

like image 23
Sven Marnach Avatar answered Dec 01 '25 13:12

Sven Marnach



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!