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"       }     } 

Tag:python, json, facebook, facebook-graph-api

Only one comment.

  1. Hackerman

    Facebook Business SDK for Python sucks, I solved this issue with this:

    def fetch_adsets_for_account(ad_account_id, fields): try: data = AdAccount(ad_account_id).get_ad_sets(fields=fields, params={"limit": 2000}) data_final = [data.export_all_data() for data in data] return data_final except Exception as e: print(f"Failed to fetch ad sets for ad account {ad_account_id}: {e}") return []

    Essentially you only need to define a high limit and it will work as expected!

Add a new comment.