jmadd1221
jmadd1221

Reputation: 41

Facebook Ads API - Batch Requesting Targeting Search


Question:

I am having trouble with submitting batch requests for the Facebook Ads API, and I was wondering if anyone could provide insight on the below error.

I am attempting to take a list of artists, just 50 in this simplified example, and then submit a TargetingSearch request for those artists. However, I'm having trouble getting the request to pass through correctly to Facebook. You could imagine a case where I'm passing thousands of artists into here.

I've been using these two resources for batch requesting ad/ad-set insights in the facebook-ads-api for Python as a reference: https://github.com/facebook/facebook-python-ads-sdk/issues/116 https://github.com/linpingta/facebook-related/blob/master/facebook-ads-sdk-example/insight_related.py

My code:

import time
list_of_artists = ['Adele','Alessia Cara','Ariana Grande','Big Sean','Blake Shelton','Brantley Gilbert','Brett Young','Bruno Mars','Calvin Harris','Camila Cabello','Carrie Underwood','Chris Brown','Chris Stapleton','Chuck Berry','Cole Swindell','Dierks Bentley','DJ Khaled','Ed Sheeran','Eminem','Eric Church','Future','G-Eazy','Gucci Mane','James Arthur','Jason Aldean','John Legend','Jon Pardi','Josh Turner','Julia Michaels','Justin Bieber','Justin Timberlake','Katy Perry','Kehlani','Keith Urban','Kelsea Ballerini','Kendrick Lamar','Kenny Chesney','Khalid','Kodak Black','Kygo','Kyle Harvey','Lady Gaga','Lil Yachty','Lorde','Luis Fonsi','Luke Bryan','Luke Combs','Machine Gun Kelly (Rapper)']

def success_callback(response):
    batch_body_responses.append(response.body())

def error_callback(response):
    # Error handling here
    pass

def get_id_list(art_search_list):
    batches = []
    batch_body_responses = []
    your_app_id = '<appid>'
    your_app_secret = '<appsecret>'
    your_access_token = '<token>'
    api = FacebookAdsApi.init(your_app_id, your_app_secret, your_access_token)
    batch_limit = 25
    for batch in generate_batches(art_search_list, batch_limit):
        next_batch = api.new_batch()
        for art in batch:
            requests = TargetingSearch.search(params = {'q': art,'type': 'adinterest'})
            for req in requests:
                # adding a print to see what req looks like
                print req
                next_batch.add_request(req, success_callback, error_callback)
        batches.append(next_batch)

    for batch_request in batches:
        batch_request.execute()
        time.sleep(5)

print batch_body_responses

get_id_list(list_of_artists)

This results in the below error:

Note: the TargetingSearch is from the print req above.

<TargetingSearch> {
    "audience_size": 30176300,
    "id": "6003173089178",
    "name": "Adele",
    "path": [
        "Interests",
        "Additional Interests",
        "Adele"
    ],
    "topic": "People"
}
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-299-67aa05ef2228> in <module>()
     33     print batch_body_responses
     34 
---> 35 get_id_list(list_of_artists)
     36 
     37 # # #################

<ipython-input-299-67aa05ef2228> in get_id_list(art_search_list)
     24                 # adding a print to see what req looks like
     25                 print req
---> 26                 next_batch.add_request(req, success_callback, error_callback)
     27         batches.append(next_batch)
     28 

//anaconda/lib/python2.7/site-packages/facebookads/api.pyc in add_request(self, request, success, failure)
    445                 A dictionary describing the call.
    446         """
--> 447         updated_params = copy.deepcopy(request._params)
    448         if request._fields:
    449             updated_params['fields'] = ','.join(request._fields)

AttributeError: 'TargetingSearch' object has no attribute '_params'

If I could correctly pass the batches to Facebook, I would expect an answer that gave me the TargetingSearch results for each artist. Here's an example for Adele, but you could imagine this being replicated for each:

[<TargetingSearch> {
    "audience_size": 30176300,
    "id": "6003173089178",
    "name": "Adele",
    "path": [
        "Interests",
        "Additional Interests",
        "Adele"
    ],
    "topic": "People"
}, <TargetingSearch> {
    "audience_size": 20449710,
    "id": "6003701797690",
    "name": "21 (Adele album)",
    "path": [
        "Interests",
        "Additional Interests",
        "21 (Adele album)"
    ],
    "topic": "News and entertainment"
}, <TargetingSearch> {
    "audience_size": 256080,
    "disambiguation_category": "Song",
    "id": "6005916496872",
    "name": "Someone like You (Adele song)",
    "path": [
        "Interests",
        "Additional Interests",
        "Someone like You (Adele song)"
    ],
    "topic": "News and entertainment"
}, <TargetingSearch> {
    "audience_size": 130230,
    "disambiguation_category": "Home",
    "id": "6002994499323",
    "name": "Adele Live",
    "path": [
        "Interests",
        "Additional Interests",
        "Adele Live"
    ]
}, <TargetingSearch> {
    "audience_size": 31410,
    "disambiguation_category": "Song",
    "id": "6004484416351",
    "name": "Rumour Has It (Adele song)",
    "path": [
        "Interests",
        "Additional Interests",
        "Rumour Has It (Adele song)"
    ],
    "topic": "News and entertainment"
}, <TargetingSearch> {
    "audience_size": 4560,
    "disambiguation_category": "Public Figure",
    "id": "6003446313480",
    "name": "Adele Parks",
    "path": [
        "Interests",
        "Additional Interests",
        "Adele Parks"
    ],
    "topic": "People"
}, <TargetingSearch> {
    "audience_size": 2290,
    "id": "6002970343768",
    "name": "Adele ring",
    "path": [
        "Interests",
        "Additional Interests",
        "Adele ring"
    ],
    "topic": "Education"
}, <TargetingSearch> {
    "audience_size": 990,
    "disambiguation_category": "Musician/Band",
    "id": "6003213600533",
    "name": "Adele - Official Website",
    "path": [
        "Interests",
        "Additional Interests",
        "Adele - Official Website"
    ]
}]

I think I'm having trouble understanding how to pass around / customize the requests and generate them in a batch that can be executed.

-Thanks, Jordan

Upvotes: 2

Views: 2442

Answers (1)

jmadd1221
jmadd1221

Reputation: 41


My Solution (Perhaps Room for Improvement)

I ended up figuring our a solution to my question, it's most likely not the best one but it works for now. I've left the question and incorrect code that I initially submitted below under its own header just in case anyone else learning about batch requests with the Facebook API and would find it helpful to see how I fixed this.

My initials concerns were right, I was essentially trying to submit TargetingSearch calls as a request, but in actuality they were executing before ever being passed as batch requests.

What I needed to do was:

  • Use FacebookRequest to create a "GET" request using the "/targetingsearch" endpoint and then append the parameters for the query using .add_params which change depending on the item in the batch.

  • Add in some error handling to the callback function. Some of the artists searched might not actually return anything for a result, if you tried to pull the ID and Name using indexing, you'd get an error.

  • I elected to import pandas and turn the results into a dataframe just so that it was easier to read.

Tip: Intentionally submitting incorrect calls to FB helped me troubleshoot because the error messaging that gets spit back shows you the actual request being made.

Code:

import time
from facebookads.api import FacebookRequest
import pandas as pd
account = '<act_accountID>'
list_of_artists = ['Adele','Alessia Cara','Ariana Grande','Big Sean','Blake Shelton','Brantley Gilbert','Brett Young','Bruno Mars','Calvin Harris','Camila Cabello','Carrie Underwood','Chris Brown','Chris Stapleton','Chuck Berry','Cole Swindell','Dierks Bentley','DJ Khaled','Ed Sheeran','Eminem','Eric Church','Future','G-Eazy','Gucci Mane','James Arthur','Jason Aldean','John Legend','Jon Pardi','Josh Turner','Julia Michaels','Justin Bieber','Justin Timberlake','Katy Perry','Kehlani','Keith Urban','Kelsea Ballerini','Kendrick Lamar','Kenny Chesney','Khalid','Kodak Black','Kygo','Kyle Harvey','Lady Gaga','Lil Yachty','Lorde','Luis Fonsi','Luke Bryan','Luke Combs','Machine Gun Kelly (Rapper)']

batch_body_responses = []

def success_callback(response):
    try:
        pair = [response.json()["data"][0]["name"],response.json()["data"][0]["id"]]
        batch_body_responses.append(pair)
    except IndexError:
        pass
    except UnicodeEncodeError:
        pass

def error_callback(response):
    pass

def get_id_list(art_search_list):
    batches = []
    your_app_id = '<appid>'
    your_app_secret = '<appsecret>'
    your_access_token = '<token>'
    api = FacebookAdsApi.init(your_app_id, your_app_secret, your_access_token)
    batch_limit = 25
    for batch in generate_batches(art_search_list, batch_limit):
        next_batch = api.new_batch()
        for artt in batch:
            requests = [FacebookRequest(node_id=account,method="GET",endpoint="/targetingsearch").add_params(params = {'q': artt,'type': 'adinterest'})]
            for req in requests:
                next_batch.add_request(req, success_callback, error_callback)
        batches.append(next_batch)

    for batch_request in batches:
        batch_request.execute()
        time.sleep(2)

    return batch_body_responses

df = pd.DataFrame(get_id_list(list_of_artists))
df

Result:

0   Adele   6003173089178
1   Alessia Cara    931161786931155
2   Ariana Grande   6003032339492
3   Big Sean    6002839083879
4   Blake Shelton   6003145416068
5   Brantley Gilbert    6003087234070
6   Young & hip 6006520994425
7   Bruno Mars  6003392437554
8   Calvin Harris   6003700476383
9   Fifth Harmony (Camila Cabello)  173362709468415
10  Carrie Underwood    6003320610294
11  Chris Brown 6003412995205
12  Chris Stapleton 6003632267583
13  Chuck Berry 6003381796604
14  Cole Swindell   6015941143427
15  Dierks Bentley  6003273151043
16  DJ Khaled   6003664971094
17  Ed Sheeran  6003704170491
18  Eminem  6003135347608
19  Eric Church 6003174532035
20  Future  6003289081451
21  G-Eazy  6006359491399
22  Gucci Mane  6003291602130
23  james arthur    6011082407659
24  Jason Aldean    6003138841739
25  John Legend 6003287333056
26  Jon Pardi   6005274491737
27  Josh Turner 6003547807427
28  Justin Bieber   6003143596040
29  Justin Timberlake   6003125864388
30  Katy Perry  6003514925642
31  Kehlani 1673020586319299
32  Keith Urban 6003280487023
33  Kelsea Ballerini    1649934611908779
34  Kendrick Lamar  6003436621883
35  Kenny Chesney   6003183761012
36  Khalid Yasin    6003043109915
37  Kygo    342546012613588
38  List of American Horror Story characters    6014211362622
39  Lady Gaga   6003144466384
40  Lil Yachty  1177170802403085
41  Lorde   6018616059273
42  Luis Fonsi  6003210594524
43  Luke Bryan  6003290279056
44  Machine Gun Kelly (rapper)  6003461497689

Upvotes: 2

Related Questions