beetbox / pyacoustid

Python bindings for Chromaprint acoustic fingerprinting and the Acoustid Web service
MIT License
325 stars 66 forks source link

Fixed issue with URL encoding #64

Closed lshw42 closed 3 years ago

lshw42 commented 3 years ago

The AcoustID Web Service offers the meta parameter to determine which kind of information should be included in the response. This parameter can consist of several keywords which are concatenated using +. Unfortunately, this char is typically encoded as %2B by e.g. the Requests Python library which is used in this project. This causes the parameter to be ignored by the server. To prevent this, urllib is used to preserve the +.

63

sampsyo commented 3 years ago

Cool; thanks for giving this a shot! Seems like we'd still want to support the "old" version, right? That is, we could use isinstance to check whether we've gotten a single string and, if so, just wrap that in a one-element list.

It would also be great to document the API—i.e., to add to the docstring for the relevant functions (lookup and match, I think?) a brief mention of what the meta parameter does and how to use it.

lshw42 commented 3 years ago

Oh, yea! Didn't consider that. Thank you!

In addition, what about catching the TypeError Exception in case the meta list contains a non-string object? A list like ['recordings', 1] would cause such exception, but not e.g. ['recordings', '1']. To address this join() can be done right before the session.post() within try-catch-block. Then, the catched exceptions list is expanded for the TypeError. What do you think about that? Another solution to avoid the TypeError exception is to explicitly cast the meta list items to strings everytime. This would lead to some msec delay but should be no problem since no more than three requests per sec to AcoustID Web Service is allowed.

The more I think about it, to explicitly cast the meta list seems the better way to me. It could be done like the following:

params['meta'] = '+'.join(str(item) for item in params['meta'])