From bda64d9e64679e8956a4576aba53c5b3971537b4 Mon Sep 17 00:00:00 2001 From: Juan Shishido Date: Mon, 26 Feb 2018 16:21:30 -0800 Subject: [PATCH 1/4] Media Library --- twitter_ads/creative.py | 31 +++++++++++++++++++++++++++++++ twitter_ads/enum.py | 13 +++++++++++++ 2 files changed, 44 insertions(+) diff --git a/twitter_ads/creative.py b/twitter_ads/creative.py index 363447d..1bdb7dd 100644 --- a/twitter_ads/creative.py +++ b/twitter_ads/creative.py @@ -387,3 +387,34 @@ def preview(self): resource_property(ScheduledTweet, 'nullcast', transform=TRANSFORM.BOOL) resource_property(ScheduledTweet, 'scheduled_at', transform=TRANSFORM.TIME) resource_property(ScheduledTweet, 'text') + + +class MediaLibrary(Resource, Persistence): + + PROPERTIES = {} + + RESOURCE_COLLECTION = '/' + API_VERSION + '/accounts/{account_id}/media_library' + RESOURCE = '/' + API_VERSION + '/accounts/{account_id}/media_library/{id}' + + +# media library properties +# read-only +resource_property(MediaLibrary, 'aspect_ratio', readonly=True) +resource_property(MediaLibrary, 'created_at', readonly=True, transform=TRANSFORM.TIME) +resource_property(MediaLibrary, 'deleted', readonly=True, transform=TRANSFORM.BOOL) +resource_property(MediaLibrary, 'duration', readonly=True) +resource_property(MediaLibrary, 'media_status', readonly=True) +resource_property(MediaLibrary, 'media_type', readonly=True) +resource_property(MediaLibrary, 'media_url', readonly=True) +resource_property(MediaLibrary, 'tweeted', readonly=True, transform=TRANSFORM.BOOL) +resource_property(MediaLibrary, 'updated_at', readonly=True, transform=TRANSFORM.TIME) +# writable +resource_property(MediaLibrary, 'media_category') +resource_property(MediaLibrary, 'media_id') +resource_property(MediaLibrary, 'media_key') +resource_property(MediaLibrary, 'description') +resource_property(MediaLibrary, 'file_name') +resource_property(MediaLibrary, 'name') +resource_property(MediaLibrary, 'poster_image_media_id') +resource_property(MediaLibrary, 'poster_image_media_key') +resource_property(MediaLibrary, 'title') diff --git a/twitter_ads/enum.py b/twitter_ads/enum.py index f7af5ed..f75c641 100644 --- a/twitter_ads/enum.py +++ b/twitter_ads/enum.py @@ -100,6 +100,19 @@ def enum(**enums): TOTAL='TOTAL' ) +MEDIA_CATEGORY = enum( + AMPLIFY_VIDEO='AMPLIFY_VIDEO', + TWEET_GIF='TWEET_GIF', + TWEET_IMAGE='TWEET_IMAGE', + TWEET_VIDEO='TWEET_VIDEO' +) + +MEDIA_TYPE = enum( + GIF='GIF', + IMAGE='IMAGE', + VIDEO='VIDEO' +) + METRIC_GROUP = enum( ENGAGEMENT='ENGAGEMENT', WEB_CONVERSION='WEB_CONVERSION', From 87c79e78423a06c68f7650835753f8ed9e610838 Mon Sep 17 00:00:00 2001 From: Juan Shishido Date: Mon, 26 Feb 2018 22:53:27 -0800 Subject: [PATCH 2/4] override methods to use media_key --- twitter_ads/creative.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/twitter_ads/creative.py b/twitter_ads/creative.py index 1bdb7dd..b18ea30 100644 --- a/twitter_ads/creative.py +++ b/twitter_ads/creative.py @@ -396,6 +396,34 @@ class MediaLibrary(Resource, Persistence): RESOURCE_COLLECTION = '/' + API_VERSION + '/accounts/{account_id}/media_library' RESOURCE = '/' + API_VERSION + '/accounts/{account_id}/media_library/{id}' + def reload(self, **kwargs): + if not self.media_key: + return self + + resource = self.RESOURCE.format(account_id=self.account.id, id=self.media_key) + response = Request(self.account.client, 'get', resource, params=kwargs).perform() + + return self.from_response(response.body['data']) + + def save(self): + if self.media_key: + method = 'put' + resource = self.RESOURCE.format(account_id=self.account.id, id=self.media_key) + else: + method = 'post' + resource = self.RESOURCE_COLLECTION.format(account_id=self.account.id) + + response = Request( + self.account.client, method, + resource, params=self.to_params()).perform() + + return self.from_response(response.body['data']) + + def delete(self): + resource = self.RESOURCE.format(account_id=self.account.id, id=self.media_key) + response = Request(self.account.client, 'delete', resource).perform() + self.from_response(response.body['data']) + # media library properties # read-only From f2281e970f4023d7d498da0b31011e2eac5266da Mon Sep 17 00:00:00 2001 From: Juan Shishido Date: Mon, 26 Feb 2018 22:56:11 -0800 Subject: [PATCH 3/4] Media Library example --- examples/media_library.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 examples/media_library.py diff --git a/examples/media_library.py b/examples/media_library.py new file mode 100644 index 0000000..2d78fbc --- /dev/null +++ b/examples/media_library.py @@ -0,0 +1,32 @@ +from twitter_ads.client import Client +from twitter_ads.creative import MediaLibrary +from twitter_ads.enum import MEDIA_CATEGORY +from twitter_ads.http import Request + + +CONSUMER_KEY = '' +CONSUMER_SECRET = '' +ACCESS_TOKEN = '' +ACCESS_TOKEN_SECRET = '' +ACCOUNT_ID = '' + +# initialize the client +client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) + +# load the advertiser account instance +account = client.accounts(ACCOUNT_ID) + +# upload an image to POST media/upload +resource = '/1.1/media/upload.json' +domain = 'https://upload.twitter.com' +files = {'media': (None, open('/path/to/file.jpg', 'rb'))} +response = Request(client, 'post', resource, files=files, domain=domain).perform() +media_id = response.body['media_id'] + +# add to media library +media_library = MediaLibrary(account) +media_library.name = 'name' +media_library.file_name = 'name.jpeg' +media_library.media_id = media_id +media_library.media_category = MEDIA_CATEGORY.TWEET_IMAGE +media_library.save() From 325dbe26512250243b4474548e0b90764dccc369 Mon Sep 17 00:00:00 2001 From: Juan Shishido Date: Thu, 1 Mar 2018 08:51:12 -0800 Subject: [PATCH 4/4] transform duration to int --- twitter_ads/creative.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twitter_ads/creative.py b/twitter_ads/creative.py index b18ea30..310cdde 100644 --- a/twitter_ads/creative.py +++ b/twitter_ads/creative.py @@ -430,7 +430,7 @@ def delete(self): resource_property(MediaLibrary, 'aspect_ratio', readonly=True) resource_property(MediaLibrary, 'created_at', readonly=True, transform=TRANSFORM.TIME) resource_property(MediaLibrary, 'deleted', readonly=True, transform=TRANSFORM.BOOL) -resource_property(MediaLibrary, 'duration', readonly=True) +resource_property(MediaLibrary, 'duration', readonly=True, transform=TRANSFORM.INT) resource_property(MediaLibrary, 'media_status', readonly=True) resource_property(MediaLibrary, 'media_type', readonly=True) resource_property(MediaLibrary, 'media_url', readonly=True)