Python sdk bulk user creation hanging on csv loop

My current config is completely failing. trying to bulk create users from a csv using the nice cxone python sdk. it’s not throwing an exception immediately but the loop just stalls after the first few records. i’m processing about 500 agents. the first 20 go through fine then nothing. no error no response just silence. here is the chunk of code handling the creation:

import pandas as pd
from nicecxoneplatform import PlatformClient

# setup client
token = get_token()
client = PlatformClient(token)
users_client = client.users

# load csv
df = pd.read_csv('agents.csv')

for index, row in df.iterrows():
 try:
 user = users_client.users_post(
 body={
 "name": row['name'],
 "email": row['email'],
 "username": row['email'],
 "login_enabled": True,
 "routing_email": row['email'],
 "routing_phone": row['phone']
 }
 )
 print(f"created {row['name']}")
 except Exception as e:
 print(f"failed {row['name']}: {e}")

the issue seems to be rate limiting or maybe the sdk is blocking on the http request without a timeout. i’ve seen this before with the rest api where you hit the 429 too many requests and the client library doesn’t handle the retry properly. i want to add a sleep or a retry mechanism but i’m not sure if the sdk has a built-in way to handle bulk operations or if i need to wrap this in a thread pool. also the users_post method returns a response object but i’m not checking the status code explicitly. if i switch to using the raw http client from the sdk would that be faster? right now it’s taking 30 seconds per user which is way too slow for a batch job. any ideas on how to batch this or speed it up without getting throttled? i’m running this in a simple script not a proper service so i need something lightweight.

The documentation actually says rate limits hit hard when you blast requests in a tight loop without backoff. You’re likely getting throttled silently by the API gateway.

i use Guzzle with an exponential backoff strategy for this exact scenario. try adding a sleep() or a retry decorator that catches 429 responses and waits before firing the next user creation call.

check your token cache too. if it expires mid-loop, the sdk might hang waiting for a refresh that never completes properly.

trying to bulk create users from a csv… it’s not throwing an exception immediately but the loop just stalls after the first few records.

is spot on. you’re hitting the rate limiter and the SDK is probably just blocking on a failed refresh or a 429 that you’re ignoring. don’t just sleep(). use exponential backoff.

here’s a quick python snippet using time and requests logic (or just wrap the SDK call) to handle 429s gracefully. the nicecxone sdk doesn’t have built-in retry for bulk ops usually.

import time
import random

def create_user_with_backoff(client, user_data, max_retries=5):
 for attempt in range(max_retries):
 try:
 # assume client.users_api.create_user is the method
 resp = client.users_api.create_user(body=user_data)
 return resp
 except Exception as e:
 if e.status_code == 429:
 # exponential backoff with jitter
 wait = 2 ** attempt + random.uniform(0, 1)
 print(f"rate limited. waiting {wait:.2f}s...")
 time.sleep(wait)
 else:
 raise e
 raise Exception("max retries exceeded")

also check if your token expires. if the loop takes >50 mins, the access token dies. you’ll need to refresh mid-loop. i’ve seen this hang silently in react native too when the refresh promise rejects silently.

My usual workaround is to implementing a strict backoff loop around the create_user call. The Python SDK doesn’t handle 429s gracefully in a tight loop, so you’ll hang if you don’t catch the exception explicitly. don’t just sleep blindly. You need to check the status code and wait exponentially.

Here’s a quick wrapper that actually works:

import time
from nicecxoneplatform import PlatformClient

def create_user_with_retry(client, user_body, max_retries=5):
 for attempt in range(max_retries):
 try:
 resp, error = client.users_api.create_user(user_body)
 if error:
 raise Exception(error.message)
 return resp
 except Exception as e:
 if "429" in str(e) or "rate limit" in str(e).lower():
 wait = 2 ** attempt
 print(f"Rate limited. Waiting {wait}s...")
 time.sleep(wait)
 else:
 raise e
 raise Exception("Max retries exceeded")

Also check your token refresh logic. If the token expires mid-batch and the refresh fails silently, the whole thing stalls. Make sure you’re catching AccessTokenExpired exceptions and forcing a re-auth before retrying.