def __init__(self, my_access_token, my_account_id, my_app_id = 'XXXXXXX', my_app_secret='XXXXXXXXXX'): self.my_app_id = my_app_id self.my_app_secret = my_app_secret self.my_access_token = my_access_token self.my_account_id = my_account_id FacebookAdsApi.init(self.my_app_id, self.my_app_secret, self.my_access_token) self.api = FacebookAdsApi.get_default_api()
def search(cls, params=None, api=None): api = api or FacebookAdsApi.get_default_api() if not api: raise FacebookBadObjectError( "An Api instance must be provided as an argument or set as " "the default Api in FacebookAdsApi.", ) params = {} if not params else params.copy() response = api.call( FacebookAdsApi.HTTP_METHOD_GET, "/".join( (FacebookSession.GRAPH, FacebookAdsApi.API_VERSION, 'search')), params, ).json() ret_val = [] if response: keys = response['data'] # The response object can be either a dictionary of dictionaries # or a dictionary of lists. if isinstance(keys, list): for item in keys: search_obj = TargetingSearch() search_obj.update(item) ret_val.append(search_obj) elif isinstance(keys, dict): for item in keys: search_obj = TargetingSearch() search_obj.update(keys[item]) if keys[item]: ret_val.append(search_obj) return ret_val
def retrieve_order_level_report_data( self, from_date, to_date, business_id, pixel_id, app_id, limit=150, api=None, ): """ Retrieve order level reporting for a given time range. """ path = ( business_id, "order_id_attributions", ) params = { 'since': from_date.strftime('%s'), 'until': to_date.strftime('%s'), 'pixel_id': pixel_id, 'app_id': app_id, 'limit': limit, } if not api: api = FacebookAdsApi.get_default_api() page_index = 0 while path: page_index += 1 logger.info( "Pulling page %s for %s/%s from %s -> %s", page_index, pixel_id, app_id, from_date, to_date, ) response = api.call( FacebookAdsApi.HTTP_METHOD_GET, path, params, ).json() # only emit non-empty pages if response['data']: yield response['data'] if 'paging' in response and 'next' in response['paging']: path = response['paging']['next'] params = {} else: break
def get_by_ids(cls, ids, params=None, fields=None, api=None): api = api or FacebookAdsApi.get_default_api() params = dict(params or {}) cls._assign_fields_to_params(fields, params) params["ids"] = ",".join(map(str, ids)) response = api.call("GET", ["/"], params=params) result = [] for fbid, data in response.json().items(): obj = cls(fbid, api=api) obj._set_data(data) result.append(obj) return result
def __init__(self, fbid=None, parent_id=None, api=None): """Initializes a CRUD object. Args: fbid (optional): The id of the object ont the Graph. parent_id (optional): The id of the object's parent. api (optional): An api object which all calls will go through. If an api object is not specified, api calls will revert to going through the default api. """ super(AbstractCrudObject, self).__init__() self._api = api or FacebookAdsApi.get_default_api() self._changes = {} self._parent_id = parent_id self._data['id'] = fbid self._include_summary = True
def get_by_ids(cls, ids, params=None, fields=None, api=None): api = api or FacebookAdsApi.get_default_api() params = dict(params or {}) cls._assign_fields_to_params(fields, params) params['ids'] = ','.join(map(str, ids)) response = api.call( 'GET', ['/'], params=params, ) result = [] for fbid, data in response.json().items(): obj = cls(fbid, api=api) obj._set_data(data) result.append(obj) return result
def retrieve_order_level_report_data_parallel( self, from_date, to_date, business_id, pixel_id='', app_id='', splits=4, ): """ Parallelise the retrieval of order level reports. """ d = (to_date - from_date) / splits # Convert any dates to datetime before splitting # otherwise we lose intra-day resolution start_time = from_date if isinstance(start_time, date): start_time = datetime.combine(start_time, time()) time_partitions = [(i * d + start_time, (i + 1) * d + start_time) for i in range(splits)] # keep a copy of the Ads API session as we're going to be using # it across new threads api = FacebookAdsApi.get_default_api() return itertools.chain.from_iterable( map( lambda (start, end): self.zzz_buffer_iterable_async( # promise fetches time-ranges concurrently self.retrieve_order_level_report_data( api=api, from_date=start, to_date=end, business_id=business_id, pixel_id=pixel_id, app_id=app_id, ), buffer_size=30, ), time_partitions, ))
def __init__(self, fbid=None, parent_id=None, api=None): """Initializes a CRUD object. Args: fbid (optional): The id of the object ont the Graph. parent_id (optional): The id of the object's parent. api (optional): An api object which all calls will go through. If an api object is not specified, api calls will revert to going through the default api. """ super(AbstractCrudObject, self).__init__() self._api = api or FacebookAdsApi.get_default_api() self._changes = {} if (parent_id is not None): warning_message = "parent_id as a parameter of constructor is " \ "being deprecated." logging.warning(warning_message) self._parent_id = parent_id self._data['id'] = fbid self._include_summary = True
def remote_create_from_zip(cls, filename, parent_id, api=None): api = api or FacebookAdsApi.get_default_api() open_file = open(filename, 'rb') response = api.call( 'POST', (parent_id, cls.get_endpoint()), files={filename: open_file}, ) open_file.close() data = response.json() objs = [] for image_filename in data['images']: image = cls(parent_id=parent_id) image.update(data['images'][image_filename]) image[cls.Field.id] = '%s:%s' % ( parent_id[4:], data['images'][image_filename][cls.Field.hash], ) objs.append(image) return objs
def search(cls, params=None, api=None): api = api or FacebookAdsApi.get_default_api() if not api: raise FacebookBadObjectError( "An Api instance must be provided as an argument or set as " "the default Api in FacebookAdsApi.", ) params = {} if not params else params.copy() response = api.call( FacebookAdsApi.HTTP_METHOD_GET, "/".join(( FacebookSession.GRAPH, FacebookAdsApi.API_VERSION, 'search' )), params, ).json() ret_val = [] if response: keys = response['data'] # The response object can be either a dictionary of dictionaries # or a dictionary of lists. if isinstance(keys, list): for item in keys: search_obj = TargetingSearch() search_obj.update(item) ret_val.append(search_obj) elif isinstance(keys, dict): for item in keys: search_obj = TargetingSearch() search_obj.update(keys[item]) if keys[item]: ret_val.append(search_obj) return ret_val
class Authentication(): """ DON'T USE THIS CLASS DIRECTLY. USE `auth()` function from this module Helper class to authenticate using config.json config file from this repository. This is useful in two cases: - Testing environment - Interactive exploration in REPL This class shouldn't be used in production. It's intended for development. Use FacebookAdsApi.init in production """ _api = FacebookAdsApi.get_default_api() if _api: _is_authenticated = True else: _is_authenticated = False @property def is_authenticated(cls): return cls._is_authenticated @classmethod def load_config(cls): config_file = open(os.path.join(repo_dir, 'config.json')) config = json.load(config_file) config_file.close() return config @classmethod def auth(cls): """ Prepare for Ads API calls and return a tuple with act_id and page_id. page_id can be None but act_id is always set. """ config = cls.load_config() if cls._is_authenticated: return config['act_id'], config.get('page_id', None) if config['app_id'] and config['app_secret'] \ and config['act_id'] and config['access_token']: FacebookAdsApi.init( config['app_id'], config['app_secret'], config['access_token'], config['act_id'], ) cls._is_authenticated = True return config['act_id'], config.get('page_id', None) else: required_fields = set( ('app_id', 'app_secret', 'act_id', 'access_token')) missing_fields = required_fields - set(config.keys()) raise FacebookError( '\n\tFile config.json needs to have the following fields: {}\n' '\tMissing fields: {}\n'.format( ', '.join(required_fields), ', '.join(missing_fields), ))
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. from facebookads import test_config page_id = test_config.page_id # _DOC oncall [pruno] # _DOC open [PAGE_GET_LOCATIONS] # _DOC vars [page_id] from facebookads.api import FacebookAdsApi response = FacebookAdsApi.get_default_api().call( 'GET', ('/{}/locations'.format(page_id),), { 'fields': 'location', }).json() for location in response['data']: print("{},{}\n".format( location['location']['latitude'], location['location']['longitude'], )) # _DOC close [PAGE_GET_LOCATIONS]
def __init__(self, key, search_params=[], classify=""): self.key = key self.search_params = search_params self.classify = classify def search(self, *args, **kwargs): pass def search_params(self, *args, **kwargs): return self.search_params def __repr__(self): return "<FacebookTargeting:{}>".format(self.key) fbapi = FacebookAdsApi.get_default_api() class APIFacebookTargeting(BaseFacebookTargeting): path = ["search"] method = "POST" base_attrs = {} def __init__(self, opt_key, opt_value, path=["search"], method="GET", base_attrs={}, *args, **kwargs):
# of this software is subject to the Facebook Developer Principles and # Policies [http://developers.facebook.com/policy/]. This copyright notice # shall be included in all copies or substantial portions of the software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. from facebookads import test_config page_id = test_config.page_id # _DOC oncall [pruno] # _DOC open [PAGE_CHECK_LOCATIONS] # _DOC vars [page_id] from facebookads.api import FacebookAdsApi response = FacebookAdsApi.get_default_api().call( 'GET', ('/{}/locations'.format(page_id),), { 'limit': 1, }).json() has_locations = len(response['data']) > 0 # _DOC close [PAGE_CHECK_LOCATIONS]