Weirdest issue with FB API response from Python SDK
Here's one of the weirdest issue I have ever experienced with an API. Let's see, so I am using the Facebook Business API, and it works fine for most requests I do, however there are some accounts that behave very strange.
Let's see, if I call this:
accounts_general_fields = ['account_id', 'business_name', 'account_status', 'age', 'amount_spent','balance','currency'] print(me.get_ad_accounts(fields=accounts_general_fields))
this works fine, there is not issue, however when I want to iterative over it, for example
accounts= list(me.get_ad_accounts(fields=accounts_general_fields))
accounts= me.get_ad_accounts(fields=accounts_general_fields) accounts_fixed = [account.api_get(fields=accounts_general_fields) for account in accounts]
accounts= me.get_ad_accounts(fields=accounts_general_fields) accounts_fixed = [account.export_all_data() for account in accounts]
or
accounts= me.get_ad_accounts(fields=accounts_general_fields) accounts_fixed = [account for account in accounts]
it gets this:
facebook_business.exceptions.FacebookRequestError: Message: Call was not successful Method: GET Path: https://graph.facebook.com/v20.0/me/adaccounts Params: {'fields': 'account_id,business_name,account_status,age,amount_spent,balance,currency', 'summary': 'true', 'after': 'MjM4NDM4NDA2MTg4NjAxMjkZD'} Status: 400 Response: { "error": { "message": "(#80004) There have been too many calls to this ad-account. Wait a bit and try again. For more info, please refer to https://developers.facebook.com/docs/graph-api/overview/rate-limiting#ads-management.", "type": "OAuthException", "code": 80004, "error_subcode": 2446079, "fbtrace_id": "ArA51rxNPTHAl7CrHVCaEWG" } }
This behavior happens with other endpoints, for example:
AdAccount(ad_account_id).get_campaigns(fields=fields)
and
AdAccount(ad_account_id).get_campaigns(fields=fields)
but just for specific ad accounts, like 3 or 4 accounts of 300 accounts. I don't know what could be happening. Here is my implementation for those endpoints:
def fetch_adsets_for_account(ad_account_id, fields): try: return list(AdAccount(ad_account_id).get_ad_sets(fields=fields)) except Exception as e: print(f"Failed to fetch ad sets for ad account {ad_account_id}: {e}") return [] def fetch_adsets_data(ad_account_ids, fields): all_data = [] # Use ThreadPoolExecutor to fetch data in parallel with concurrent.futures.ThreadPoolExecutor(max_workers=30) as executor: # Create a list of futures futures = {executor.submit(fetch_adsets_for_account, ad_account_id, fields): ad_account_id for ad_account_id in ad_account_ids} # As each future completes, append the result to all_data for future in concurrent.futures.as_completed(futures): try: data = future.result() all_data.extend(data) except Exception as e: ad_account_id = futures[future] print(f"An error occurred for ad account {ad_account_id}: {e}") # Convert the collected data to a DataFrame df = pd.DataFrame(all_data) return df # Example usage: ad_account_ids = df_accounts["id"].tolist()[:] fields = ['name', 'status', 'start_time', 'lifetime_budget'] start = time.time() df_individual_adsets = fetch_adsets_data(ad_account_ids, fields) df_individual_adsets["date"] = today_data end = time.time() print(end - start)
Here's one example of the problem for this:
Failed to fetch ad sets for ad account act_400136354038554: Message: Call was not successful Method: GET Path: https://graph.facebook.com/v20.0/act_400136354038554/adsets Params: {'fields': 'name,status,start_time,lifetime_budget', 'summary': 'true', 'after': 'QVFIUmM2a3VXdG5XRG43OFd3ZAVdLNlV5d1BaR3NlWFlyTk9zQW5yaElIYWZAieVF0b3pFMUphV0tIZAmR4VEE2S3J0LTIZD'} Status: 400 Response: { "error": { "message": "User request limit reached", "type": "OAuthException", "is_transient": false, "code": 17, "error_subcode": 2446079, "error_user_title": "Ad Account Has Too Many API Calls", "error_user_msg": "There have been too many calls from this ad-account. Please wait a bit and try again.", "fbtrace_id": "A-LW6ciS_vyN_vkhK5CD0tW" } }