diff --git a/examples/audience_summary.py b/examples/audience_estimate.py similarity index 85% rename from examples/audience_summary.py rename to examples/audience_estimate.py index 5f0bdcd..110fe4e 100644 --- a/examples/audience_summary.py +++ b/examples/audience_estimate.py @@ -1,5 +1,5 @@ from twitter_ads.client import Client -from twitter_ads.targeting import AudienceSummary +from twitter_ads.targeting import AudienceEstimate CONSUMER_KEY = 'your consumer key' CONSUMER_SECRET = 'your consumer secret' @@ -35,6 +35,6 @@ ] } -audience_summary = AudienceSummary.load(account=account, params=params) +audience_estimate = AudienceEstimate.load(account=account, params=params) -print (audience_summary.audience_size) +print (audience_estimate.audience_size) diff --git a/tests/fixtures/accounts_all.json b/tests/fixtures/accounts_all.json index d265699..7ab5ba1 100644 --- a/tests/fixtures/accounts_all.json +++ b/tests/fixtures/accounts_all.json @@ -9,7 +9,6 @@ "timezone_switch_at": "2014-11-17T08:00:00Z", "id": "2iqph", "created_at": "2015-03-04T10:50:42Z", - "salt": "5ab2pizq7qxjjqrx3z67f4wbko61o7xs", "updated_at": "2015-04-11T05:20:08Z", "approval_status": "ACCEPTED", "deleted": false @@ -20,7 +19,6 @@ "timezone_switch_at": "2014-11-17T08:00:00Z", "id": "pz6ec", "created_at": "2015-05-29T00:52:16Z", - "salt": "39ku32xvhdt0jax8thps2c70e2fv3yok", "updated_at": "2015-05-29T00:52:16Z", "approval_status": "ACCEPTED", "deleted": false @@ -31,7 +29,6 @@ "timezone_switch_at": "2014-11-17T08:00:00Z", "id": "j9ozo", "created_at": "2015-05-01T12:08:10Z", - "salt": "winwfne3y6oyikl4tm84bj9r50waxj37", "updated_at": "2015-05-01T12:08:10Z", "approval_status": "ACCEPTED", "deleted": false @@ -42,7 +39,6 @@ "timezone_switch_at": "2014-11-17T08:00:00Z", "id": "9ttgd", "created_at": "2015-06-24T18:51:20Z", - "salt": "tj9hmt5xylm5zztrq05w7hwh4mkpkg5r", "updated_at": "2015-06-26T06:13:24Z", "approval_status": "ACCEPTED", "deleted": false @@ -53,7 +49,6 @@ "timezone_switch_at": "2013-05-22T07:00:00Z", "id": "47d0v", "created_at": "2015-05-28T05:42:03Z", - "salt": "1ms1mq1nww7zl7169865gwqt89s9127m", "updated_at": "2015-05-28T05:42:03Z", "approval_status": "ACCEPTED", "deleted": false diff --git a/tests/fixtures/audience_summary.json b/tests/fixtures/audience_estimate.json similarity index 100% rename from tests/fixtures/audience_summary.json rename to tests/fixtures/audience_estimate.json diff --git a/tests/fixtures/line_items_all.json b/tests/fixtures/line_items_all.json index 24bf7d3..a886d6c 100644 --- a/tests/fixtures/line_items_all.json +++ b/tests/fixtures/line_items_all.json @@ -13,7 +13,6 @@ "ALL_ON_TWITTER" ], "bid_amount_local_micro": 2000000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -39,7 +38,6 @@ "ALL_ON_TWITTER" ], "bid_amount_local_micro": 2000000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -65,7 +63,6 @@ "TWITTER_SEARCH" ], "bid_amount_local_micro": 100000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -91,7 +88,6 @@ "TWITTER_SEARCH" ], "bid_amount_local_micro": 500000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -117,7 +113,6 @@ "TWITTER_TIMELINE" ], "bid_amount_local_micro": 50000000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -143,7 +138,6 @@ "TWITTER_TIMELINE" ], "bid_amount_local_micro": 50000000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -169,7 +163,6 @@ "TWITTER_SEARCH" ], "bid_amount_local_micro": 50000000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -195,7 +188,6 @@ "TWITTER_TIMELINE" ], "bid_amount_local_micro": 500000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -221,7 +213,6 @@ "TWITTER_SEARCH" ], "bid_amount_local_micro": 50000000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", @@ -247,7 +238,6 @@ "TWITTER_TIMELINE" ], "bid_amount_local_micro": 2009999, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", diff --git a/tests/fixtures/line_items_load.json b/tests/fixtures/line_items_load.json index 7af7320..b5607d3 100644 --- a/tests/fixtures/line_items_load.json +++ b/tests/fixtures/line_items_load.json @@ -8,7 +8,6 @@ "ALL_ON_TWITTER" ], "bid_amount_local_micro": 2000000, - "automatically_select_bid": false, "advertiser_domain": null, "primary_web_event_tag": null, "pay_by": "ENGAGEMENT", diff --git a/tests/test_audience_summary.py b/tests/test_audience_summary.py index 20bfa67..995564d 100644 --- a/tests/test_audience_summary.py +++ b/tests/test_audience_summary.py @@ -5,7 +5,7 @@ from twitter_ads.account import Account from twitter_ads.client import Client -from twitter_ads.targeting import AudienceSummary +from twitter_ads.targeting import AudienceEstimate from twitter_ads import API_VERSION @@ -17,8 +17,8 @@ def test_audience_summary(): content_type='application/json') responses.add(responses.POST, - with_resource('/' + API_VERSION + '/accounts/2iqph/audience_summary'), - body=with_fixture('audience_summary'), + with_resource('/' + API_VERSION + '/accounts/2iqph/audience_estimate'), + body=with_fixture('audience_estimate'), content_type='application/json') client = Client( @@ -51,7 +51,7 @@ def test_audience_summary(): ] } - audience_summary = AudienceSummary.load( + audience_summary = AudienceEstimate.load( account=account, params=params ) diff --git a/twitter_ads/__init__.py b/twitter_ads/__init__.py index bd1a77f..4931818 100644 --- a/twitter_ads/__init__.py +++ b/twitter_ads/__init__.py @@ -1,7 +1,8 @@ # Copyright (C) 2015 Twitter, Inc. -VERSION = (9, 0, 1) -API_VERSION = '9' + +VERSION = (10, 0, 0) +API_VERSION = '10' from twitter_ads.utils import get_version diff --git a/twitter_ads/account.py b/twitter_ads/account.py index 88cc2a4..c7c87a8 100644 --- a/twitter_ads/account.py +++ b/twitter_ads/account.py @@ -13,7 +13,7 @@ Card, VideoWebsiteCard, PromotedTweet) from twitter_ads.audience import CustomAudience from twitter_ads.campaign import (AppList, Campaign, FundingInstrument, LineItem, - PromotableUser, ScheduledPromotedTweet) + PromotableUser, TrackingTags, ScheduledPromotedTweet) class Account(Resource): @@ -148,6 +148,12 @@ def scheduled_promoted_tweets(self, id=None, **kwargs): """ return self._load_resource(ScheduledPromotedTweet, id, **kwargs) + def tracking_tags(self, id=None, **kwargs): + """ + Returns a collection of Tracking Tags available to the current account. + """ + return self._load_resource(TrackingTags, id, **kwargs) + def video_website_cards(self, id=None, **kwargs): """ Returns a collection of video website cards available to the current account. @@ -164,7 +170,6 @@ def cards(self, id=None, **kwargs): # account properties resource_property(Account, 'id', readonly=True) resource_property(Account, 'name', readonly=True) -resource_property(Account, 'salt', readonly=True) resource_property(Account, 'timezone', readonly=True) resource_property(Account, 'approval_status', readonly=True) resource_property(Account, 'deleted', readonly=True, transform=TRANSFORM.BOOL) diff --git a/twitter_ads/campaign.py b/twitter_ads/campaign.py index fbf2717..d5e6ec1 100644 --- a/twitter_ads/campaign.py +++ b/twitter_ads/campaign.py @@ -141,7 +141,6 @@ def tv_shows(klass, account, **kwargs): resource_property(TargetingCriteria, 'operator_type') resource_property(TargetingCriteria, 'targeting_type') resource_property(TargetingCriteria, 'targeting_value') -resource_property(TargetingCriteria, 'custom_audience_expansion') # sdk-only resource_property(TargetingCriteria, 'to_delete', transform=TRANSFORM.BOOL) @@ -267,13 +266,6 @@ def targeting_criteria(self, id=None, **kwargs): return TargetingCriteria.load(self.account, id, **kwargs) def save(self): - # automatically_select_bid and bid_type are exclusive parameters - if self.automatically_select_bid and self.bid_type: - if self.bid_type == 'AUTO': - self.bid_type = None - self.automatically_select_bid = True - else: - self.automatically_select_bid = None super(LineItem, self).save() @@ -289,7 +281,6 @@ def save(self): # writable resource_property(LineItem, 'advertiser_domain') resource_property(LineItem, 'advertiser_user_id') -resource_property(LineItem, 'automatically_select_bid', transform=TRANSFORM.BOOL) resource_property(LineItem, 'bid_amount_local_micro') resource_property(LineItem, 'bid_strategy') resource_property(LineItem, 'campaign_id') @@ -360,6 +351,26 @@ class ScheduledPromotedTweet(Resource, Persistence): resource_property(ScheduledPromotedTweet, 'scheduled_tweet_id') +class TrackingTags(Resource, Persistence): + + PROPERTIES = {} + + RESOURCE_COLLECTION = '/' + API_VERSION + '/accounts/{account_id}/tracking_tags' + RESOURCE = '/' + API_VERSION + '/accounts/{account_id}/tracking_tags/{id}' + + +# tracking tags properties +# read-only +resource_property(TrackingTags, 'created_at', readonly=True, transform=TRANSFORM.TIME) +resource_property(TrackingTags, 'id', readonly=True) +resource_property(TrackingTags, 'deleted', readonly=True, transform=TRANSFORM.BOOL) +resource_property(TrackingTags, 'updated_at', readonly=True, transform=TRANSFORM.TIME) +# writable +resource_property(TrackingTags, 'line_item_id') +resource_property(TrackingTags, 'tracking_tag_type') +resource_property(TrackingTags, 'tracking_tag_url') + + class Tweet(object): TWEET_CREATE = '/' + API_VERSION + '/accounts/{account_id}/tweet' diff --git a/twitter_ads/creative.py b/twitter_ads/creative.py index ac2a36a..ab150f0 100644 --- a/twitter_ads/creative.py +++ b/twitter_ads/creative.py @@ -209,10 +209,8 @@ class ImageAppDownloadCard(Resource, Persistence): # writable resource_property(ImageAppDownloadCard, 'country_code') resource_property(ImageAppDownloadCard, 'app_cta') -resource_property(ImageAppDownloadCard, 'iphone_app_id') -resource_property(ImageAppDownloadCard, 'iphone_deep_link') -resource_property(ImageAppDownloadCard, 'ipad_app_id') -resource_property(ImageAppDownloadCard, 'ipad_deep_link') +resource_property(ImageAppDownloadCard, 'ios_app_store_identifier') +resource_property(ImageAppDownloadCard, 'ios_deep_link') resource_property(ImageAppDownloadCard, 'googleplay_app_id') resource_property(ImageAppDownloadCard, 'googleplay_deep_link') resource_property(ImageAppDownloadCard, 'name') @@ -242,10 +240,8 @@ class VideoAppDownloadCard(Resource, Persistence): resource_property(VideoAppDownloadCard, 'country_code') resource_property(VideoAppDownloadCard, 'app_cta') resource_property(VideoAppDownloadCard, 'poster_media_key') -resource_property(VideoAppDownloadCard, 'ipad_app_id') -resource_property(VideoAppDownloadCard, 'ipad_deep_link') -resource_property(VideoAppDownloadCard, 'iphone_app_id') -resource_property(VideoAppDownloadCard, 'iphone_deep_link') +resource_property(VideoAppDownloadCard, 'ios_app_store_identifier') +resource_property(VideoAppDownloadCard, 'ios_deep_link') resource_property(VideoAppDownloadCard, 'googleplay_app_id') resource_property(VideoAppDownloadCard, 'googleplay_deep_link') resource_property(VideoAppDownloadCard, 'name') @@ -530,10 +526,8 @@ def reload(self): resource_property(CardsFetch, 'image', readonly=True) resource_property(CardsFetch, 'image_display_height', readonly=True) resource_property(CardsFetch, 'image_display_width', readonly=True) -resource_property(CardsFetch, 'ipad_app_id', readonly=True) -resource_property(CardsFetch, 'ipad_deep_link', readonly=True) -resource_property(CardsFetch, 'iphone_app_id', readonly=True) -resource_property(CardsFetch, 'iphone_deep_link', readonly=True) +resource_property(CardsFetch, 'ios_app_store_identifier', readonly=True) +resource_property(CardsFetch, 'ios_deep_link', readonly=True) resource_property(CardsFetch, 'name', readonly=True) resource_property(CardsFetch, 'recipient_user_id', readonly=True) resource_property(CardsFetch, 'second_choice', readonly=True) @@ -626,6 +620,7 @@ def reload(klass): # card properties # read-only resource_property(Card, 'card_uri', readonly=True) +resource_property(Card, 'card_type', readonly=True) resource_property(Card, 'created_at', readonly=True, transform=TRANSFORM.TIME) resource_property(Card, 'deleted', readonly=True, transform=TRANSFORM.BOOL) resource_property(Card, 'updated_at', readonly=True, transform=TRANSFORM.TIME) diff --git a/twitter_ads/targeting.py b/twitter_ads/targeting.py index b185ba0..8253f1c 100644 --- a/twitter_ads/targeting.py +++ b/twitter_ads/targeting.py @@ -9,10 +9,10 @@ import json -class AudienceSummary(Resource, Persistence): +class AudienceEstimate(Resource, Persistence): PROPERTIES = {} - RESOURCE = '/' + API_VERSION + '/accounts/{account_id}/audience_summary' + RESOURCE = '/' + API_VERSION + '/accounts/{account_id}/audience_estimate' @classmethod @FlattenParams @@ -27,4 +27,4 @@ def load(klass, account, params): return klass(account).from_response(response.body['data']) -resource_property(AudienceSummary, 'audience_size') +resource_property(AudienceEstimate, 'audience_size')