简体   繁体   中英

SOUNDCLOUD API: get body of the response for error 429 with soundcloud-python

I'm using soundcloud-python https://github.com/soundcloud/soundcloud-python for Soundcloud API on Ubuntu Server 16.04.1 (installed with pip install soundcloud ).

Soundcloud API Rate Limits official page https://developers.soundcloud.com/docs/api/rate-limits#play-requests says that, in case an app exceeds the API rate limits, the body of the 429 Client Error response would be a JSON object, containing some additional info.

I'm interested in getting reset_time field, to inform the user when the block will be over.

The problem is that when, for example, like rate limits is exceeded, doing response = client.put('/me/favorites/%d' % song_id) the app crashes and response is null .

How can I get the JSON response body?

Why don't you read the package's source code and find out by yourself ?

Let's see... You don't explain you got that client object but browsing the source code we can see there's a "client.py" module that defines a Client class. This class does'nt not define a put method explicitely but it defines the __getattr__ hook :

def __getattr__(self, name, **kwargs):
    """Translate an HTTP verb into a request method."""
    if name not in ('get', 'post', 'put', 'head', 'delete'):
        raise AttributeError
    return partial(self._request, name, **kwargs)

Ok, so Client.put(...) returns a partial object wrapping Client._request , which is a quite uselessly convoluted way to define Client.put(**kwargs) as return self._request("put", **kwargs) .

Now let's look at Client._request : it basically make a couple sanity checks, updates **kwargs and returns wrapped_resource(make_request(method, url, kwargs)) .

Looking up the imports at the beginning of the module, we can see that make_request comes from "request.py" and wrapped_resource from "resources.py".

You mention that doing an api call while over the rate limit "crashes the application" - I assume you mean "raises an exception" (BTW please post exceptions and tracebacks when saking about such problems) - so assuming this is handled at the lower level, let's start with request.make_request . A lot of data formatting / massaging obviously and finally the interesting part : a call to response.raise_for_status() . This is a hint that we are actually delegating to the famous python-requests package , which is actually confirmed a few lines above and in the requirements file

If we read python-requests fine manual , we find out what raise_for_status does - it raises a requests.exceptions.HTTPError for client (4XX) and server (5XX) status codes.

Ok now we know what exception we have. Note that you had all those informations already in your exception and traceback , which would have saved us a lot of pain here had you posted it.

But anyway... It looks like we won't get the response content, does it ? Well, wait, we're not done yet - python-requests is a fairly well designed package, so chances are we can still rescue our response. And indeed, if we look at requests.exceptions source code , we find out that HttpError is a subclass of RequestException , and that RequestException is "Initialize(d)" with " request and response objects."

Hurray, we do have our response - in the exception. So all we have to do is catch the exception and check it's response attribute - which should contains the "additional informations".

Now please understand that this took me more than half an hour to write , but about 7 minutes to sort out without the traceback - with the traceback it would have boiled down to a mere 2 minutes, the time to go to the requests.exceptions source code and make sure it keeped the request and response. Ok I'm cheating, I'm used to read source code and I use python-requests a lot, but still: you could have solved this by yourself in less than an hour, specially with python's interactive shell which let's you explore and test live objects in real time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM