Too many requests error not handled by SDK

Hello

I have a problem with the request rate limits using the Python SDK. Usually, the Python SDK handles the 429 errors, so if I do this:

for i in range(200):
    print(i)
    users_api.get_users_me()

It executes 180 requests, then it waits until the rate limit is reset, and then it does the final 20.

However, now I have a Script that is raising a 429 ApiException, and I don't know why.

The case scenario is this: I have a list of 100 user emails and a list of passwords, and I want to set their passwords using the API. So, it should do the 100 user search requests to get the ids, then 80 request to change the passwords until it reaches the 180 per minute limit, wait until it is reset, and finally make the last 20 requests.

However, when it should just wait, it is raising an ApiException of type 429, without dealing with it on its own.

The code is this:

users = [
    'user1@domain.com',
    'user2@domain.com',
    'user3@domain.com',
    # ...
    'user98@domain.com',
    'user99@domain.com',
    'user100@domain.com',

]

passwords = [
    'pass1',
    'pass2',
    'pass3',
    # ...
    'pass98',
    'pass99',
    'pass100',

]

# ... SDK Auth stuff ...

users_api = PureCloudPlatformClientV2.UsersApi()

def get_user_id_by_email(email):
    body = PureCloudPlatformClientV2.UserSearchRequest()
    query = PureCloudPlatformClientV2.UserSearchCriteria()
    query.fields = ['email']
    query.value = email
    query.type = 'EXACT'
    body.query=[query]
    
    api_response = users_api.post_users_search(body)
    
    return api_response.results[0].id
    
def change_password(user_id, new_password):
    body = PureCloudPlatformClientV2.ChangePasswordRequest()
    body.new_password = new_password
    users_api.post_user_password(user_id, body)

for i in len(users):
    user_id = get_user_id_by_email(users[i])
    change_password(user_id, passwords[i])

I don't know why in the first code example, it handles the 429 errors on its own, but not with the second one.

Thank you!

Hi Adrian,

I tracked the issue down. In our Python SDK we use the urllib3 library to make all of our HTTP requests. By default urllib will only retry on the following HTTP verbs: {'DELETE', 'GET', 'HEAD', 'OPTIONS','PUT', 'TRACE'}. The users_api.post_users_search(body) is using a post to execute the search because the query parameters for the search are executed for the post, so when you hit the 180 requests within 60 seconds mark, the post-call fails and will throw an ApiException instead of just processing the request.

You have 3 options:

  1. The one most in your control. Handle the 429s yourself. This will make this one piece of code uglier,
    but you can code around this issue immediately.

  2. Patch your local copy of the /PureCloudPlatformClientV2/rest.py file. The patch itself is simple.

    1. Starting at line 43 of the file append a new line and import urllib retry code: from requests.packages.urllib3.util import Retry
    2. At about line 123 replace the code for creating the pool manager with this:
             retries = Retry(allowed_methods={'DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST','PUT', 'TRACE'})
             self.pool_manager = urllib3.PoolManager(
                 retries=retries,
                 num_pools=pools_size,
                 maxsize=max_size,
                 block=True,
                 cert_reqs=cert_reqs,
                 ca_certs=ca_certs,
                 cert_file=cert_file,
                 key_file=key_file
             )```
    
  3. The third option is to wait for us to modify the SDK. This is the longest, but safest option. I need to chat with the team about fixing it and then making sure we do some testing with it so we don't inadvertently introduce a regression. I don't think this will be a big deal, but it's better to be safe than sorry when dealing with such a low-level and widespread part of our API code.

Hope that helps.

Thanks,
John Carnell
Manager, Developer Engagement

Thank you John, now I understand it.

I think we won't use the first solution, as like you say it turns the code more messy, and for us one of the main points of using the SDK is to abstract from all the connection and request-making stuff.

How long do you think it would take to include the changes in the official SDK? So we can decide if we wait for it or if we modify it in our local copies of the package as you suggest.

Thanks!

Hi Adrian,

I just talked with one of the devs on the team and he is going to do the fix today or tomorrow, so I would expect it available sometime early next week at the latest.

Thanks,
John

Ok, thank you very much for your help John!

Just one question: Are you going to add only the POST method or all the methods the API uses, too? (PATCH, for example)

Hi Adrian,

Version 113.0.1 has just been released with the updated methods. The full list is as follows:

'DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'TRACE'

1 Like

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.