Skip to content

Commit

Permalink
Parse nested objects (#666)
Browse files Browse the repository at this point in the history
Summary:
In the current version nested objects are not handled correctly.

For example, we want to retrieve Ads for the campaign using only one request. With this fix, we'll be able to make requests like:

```
campaigns = account.get_campaigns(fields=['name,ads{id,name,status}'])
campaign = campaigns[0]
```

In this example nested Ads objects will be available as

```
campaign.get('ads')
```

Pull Request resolved: #666

Reviewed By: mengxuanzhangz

Differential Revision: D54815751

Pulled By: stcheng

fbshipit-source-id: f23299bc168c33e485830ce500d8c8841cfbaf02
  • Loading branch information
aluminiumgeek authored and facebook-github-bot committed Mar 13, 2024
1 parent 3d68190 commit 0cff587
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions facebook_business/adobjects/objectparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
)
from facebook_business.adobjects.abstractobject import AbstractObject


class ObjectParser:
"""
Parser for API response
Expand Down Expand Up @@ -39,30 +40,48 @@ def __init__(
self._custom_parse_method = custom_parse_method
self._api = api

def parse_single(self, response):
def parse_single(self, response, override_target_class=None):
if self._custom_parse_method is not None:
return self._custom_parse_method(response, self._api)

from .ad import Ad
from .adpreview import AdPreview
from .adset import AdSet
from .campaign import Campaign

data = response
if 'data' in response and isinstance(response['data'], dict):
data = response['data']
elif 'images' in response and not isinstance(data['images'], list):
_, data = data['images'].popitem()
if 'campaigns' in data:
_, data = data['campaigns'].popitem()
elif 'adsets' in data:
_, data = data['adsets'].popitem()
elif 'ads' in data:
_, data = data['ads'].popitem()

subfields = (
('campaigns', Campaign),
('adsets', AdSet),
('ads', Ad),
('previews', AdPreview),
)
for subfield, _class in subfields:
if subfield not in data:
continue

data[subfield] = [
self.parse_single(
item, override_target_class=_class
) for item in data[subfield]['data']
]

if 'success' in data:
del data['success']

target_class = override_target_class or self._target_class

if self._reuse_object is not None:
self._reuse_object._set_data(data)
return self._reuse_object
elif self._target_class is not None:
return AbstractObject.create_object(self._api, data,
self._target_class)
target_class)
else:
raise FacebookBadObjectError(
'Must specify either target class calling object' +
Expand Down

0 comments on commit 0cff587

Please sign in to comment.