Skip to content

Commit e0aae96

Browse files
authored
Support for new cards endpoint (#275)
* Adding support to create and read from the new cards endpoint * Include a card create example
1 parent 7241015 commit e0aae96

File tree

4 files changed

+73
-5
lines changed

4 files changed

+73
-5
lines changed

examples/cards.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from twitter_ads.client import Client
2+
from twitter_ads.creative import Card
3+
from twitter_ads.campaign import Tweet
4+
from twitter_ads.restapi import UserIdLookup
5+
6+
7+
CONSUMER_KEY = 'your consumer key'
8+
CONSUMER_SECRET = 'your consumer secret'
9+
ACCESS_TOKEN = 'access token'
10+
ACCESS_TOKEN_SECRET = 'access token secret'
11+
ACCOUNT_ID = 'account id'
12+
13+
# initialize the client
14+
client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
15+
16+
# load the advertiser account instance
17+
account = client.accounts(ACCOUNT_ID)
18+
19+
# create the card
20+
name = 'video website card'
21+
components = [{"type":"MEDIA","media_key":"13_1191948012077092867"},{"type":"DETAILS","title":"Twitter","destination":{"type":"WEBSITE", "url":"http://twitter.com/"}}]
22+
video_website_card = Card.create(account, name=name, components=components)
23+
24+
# get user_id for as_user_id parameter
25+
user_id = UserIdLookup.load(account, screen_name='your_twitter_handle_name').id
26+
27+
# create a tweet using this new card
28+
Tweet.create(account, text='Created from the SDK', as_user_id=user_id, card_uri=video_website_card.card_uri)
29+
# https://twitter.com/apimctestface/status/1372283476615958529

twitter_ads/account.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from twitter_ads.resource import resource_property, Resource
1212
from twitter_ads.creative import (AccountMedia, MediaCreative, ScheduledTweet,
13-
VideoWebsiteCard, PromotedTweet)
13+
Card, VideoWebsiteCard, PromotedTweet)
1414
from twitter_ads.audience import TailoredAudience
1515
from twitter_ads.campaign import (AppList, Campaign, FundingInstrument, LineItem,
1616
PromotableUser, ScheduledPromotedTweet)
@@ -154,6 +154,12 @@ def video_website_cards(self, id=None, **kwargs):
154154
"""
155155
return self._load_resource(VideoWebsiteCard, id, **kwargs)
156156

157+
def cards(self, id=None, **kwargs):
158+
"""
159+
Returns a collection of Cards available to the current account.
160+
"""
161+
return self._load_resource(Card, id, **kwargs)
162+
157163

158164
# account properties
159165
resource_property(Account, 'id', readonly=True)

twitter_ads/creative.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
"""Container for all creative management logic used by the Ads API SDK."""
44

5+
import json
56
from requests.exceptions import HTTPError
67
from twitter_ads import API_VERSION
78
from twitter_ads.cursor import Cursor
@@ -595,3 +596,39 @@ def all(klass, account, **kwargs):
595596
resource = klass.RESOURCE_COLLECTION.format(account_id=account.id)
596597
request = Request(account.client, 'get', resource, params=kwargs)
597598
return Cursor(None, request)
599+
600+
601+
class Card(Resource):
602+
603+
PROPERTIES = {}
604+
605+
RESOURCE_COLLECTION = '/' + API_VERSION + '/accounts/{account_id}/cards'
606+
607+
@classmethod
608+
def create(klass, account, name, components):
609+
method = 'post'
610+
resource = klass.RESOURCE_COLLECTION.format(account_id=account.id)
611+
headers = {'Content-Type': 'application/json'}
612+
payload = {'name': name, 'components': components}
613+
response = Request(
614+
account.client, method, resource,
615+
headers=headers, body=json.dumps(payload)
616+
).perform()
617+
return klass(account).from_response(response.body['data'])
618+
619+
def load(klass):
620+
raise AttributeError("'Card' object has no attribute 'load'")
621+
622+
def reload(klass):
623+
raise AttributeError("'Card' object has no attribute 'reload'")
624+
625+
626+
# card properties
627+
# read-only
628+
resource_property(Card, 'card_uri', readonly=True)
629+
resource_property(Card, 'created_at', readonly=True, transform=TRANSFORM.TIME)
630+
resource_property(Card, 'deleted', readonly=True, transform=TRANSFORM.BOOL)
631+
resource_property(Card, 'updated_at', readonly=True, transform=TRANSFORM.TIME)
632+
# these are writable, but not in the sense that they can be set on an object and then saved
633+
resource_property(Card, 'name', readonly=True)
634+
resource_property(Card, 'components', readonly=True, transform=TRANSFORM.LIST)

twitter_ads/resource.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,6 @@ def to_params(self):
7878

7979
if isinstance(value, datetime):
8080
params[name] = format_time(value)
81-
elif isinstance(value, list):
82-
if not value:
83-
continue
84-
params[name] = ','.join(map(str, value))
8581
elif isinstance(value, bool):
8682
params[name] = str(value).lower()
8783
else:

0 commit comments

Comments
 (0)