Skip to content

Commit 0cff587

Browse files
aluminiumgeekfacebook-github-bot
authored andcommitted
Parse nested objects (#666)
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
1 parent 3d68190 commit 0cff587

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

facebook_business/adobjects/objectparser.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
)
1010
from facebook_business.adobjects.abstractobject import AbstractObject
1111

12+
1213
class ObjectParser:
1314
"""
1415
Parser for API response
@@ -39,30 +40,48 @@ def __init__(
3940
self._custom_parse_method = custom_parse_method
4041
self._api = api
4142

42-
def parse_single(self, response):
43+
def parse_single(self, response, override_target_class=None):
4344
if self._custom_parse_method is not None:
4445
return self._custom_parse_method(response, self._api)
4546

47+
from .ad import Ad
48+
from .adpreview import AdPreview
49+
from .adset import AdSet
50+
from .campaign import Campaign
51+
4652
data = response
4753
if 'data' in response and isinstance(response['data'], dict):
4854
data = response['data']
4955
elif 'images' in response and not isinstance(data['images'], list):
5056
_, data = data['images'].popitem()
51-
if 'campaigns' in data:
52-
_, data = data['campaigns'].popitem()
53-
elif 'adsets' in data:
54-
_, data = data['adsets'].popitem()
55-
elif 'ads' in data:
56-
_, data = data['ads'].popitem()
57+
58+
subfields = (
59+
('campaigns', Campaign),
60+
('adsets', AdSet),
61+
('ads', Ad),
62+
('previews', AdPreview),
63+
)
64+
for subfield, _class in subfields:
65+
if subfield not in data:
66+
continue
67+
68+
data[subfield] = [
69+
self.parse_single(
70+
item, override_target_class=_class
71+
) for item in data[subfield]['data']
72+
]
73+
5774
if 'success' in data:
5875
del data['success']
5976

77+
target_class = override_target_class or self._target_class
78+
6079
if self._reuse_object is not None:
6180
self._reuse_object._set_data(data)
6281
return self._reuse_object
6382
elif self._target_class is not None:
6483
return AbstractObject.create_object(self._api, data,
65-
self._target_class)
84+
target_class)
6685
else:
6786
raise FacebookBadObjectError(
6887
'Must specify either target class calling object' +

0 commit comments

Comments
 (0)