Skip to content

Commit d100db5

Browse files
authored
Merge pull request #1 from pixability/feature/upgrade_tw_api
Feature/upgrade tw api
2 parents 829c125 + 194fb14 commit d100db5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1316
-365
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,7 @@ target/
6161

6262
# Virtualenv
6363
sdk/
64+
65+
# IDE files
66+
.project
67+
.pydevproject

.pullapprove.yml

Lines changed: 0 additions & 12 deletions
This file was deleted.

.travis.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ matrix:
1010
include:
1111
- python: 2.7
1212
script: python setup.py flake8 && python setup.py test
13-
- python: 3.2
14-
script: python setup.py test
1513
- python: 3.3
1614
script: python setup.py test
1715
- python: 3.4
1816
script: python setup.py test
17+
- python: 3.5
18+
script: python setup.py test
1919
- python: pypy
2020
script: python setup.py flake8 && python setup.py test
21+
- python: pypy3
22+
script: pip install setuptools_scm && python setup.py test

README.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Quick Start
1616
1717
from twitter_ads.client import Client
1818
from twitter_ads.campaign import Campaign
19+
from twitter_ads.enum import ENTITY_STATUS
1920
2021
CONSUMER_KEY = 'your consumer key'
2122
CONSUMER_SECRET = 'your consumer secret'
@@ -33,7 +34,7 @@ Quick Start
3334
# load and update a specific campaign
3435
campaign = account.campaigns().next()
3536
campaign.name = 'updated campaign name'
36-
campaign.paused = True
37+
campaign.entity_status = ENTITY_STATUS.PAUSED
3738
campaign.save()
3839
3940
# iterate through campaigns
@@ -62,13 +63,13 @@ This project is designed to work with Python 2.7 or greater. While it
6263
may work on other version of Python, below are the platform and runtime
6364
versions we officially support and regularly test against.
6465

65-
+------------+----------------------+
66-
| Platform | Versions |
67-
+============+======================+
68-
| CPython | 2.7, 3.2, 3.3, 3.4 |
69-
+------------+----------------------+
70-
| PyPy | 2.x, 4.x |
71-
+------------+----------------------+
66+
+------------+-------------------------+
67+
| Platform | Versions |
68+
+============+=========================+
69+
| CPython | 2.7, 3.3, 3.4, 3.5 |
70+
+------------+-------------------------+
71+
| PyPy | 2.x, 4.x |
72+
+------------+-------------------------+
7273

7374
All releases adhere to strict `semantic versioning`_. For Example,
7475
major.minor.patch-pre (aka. stick.carrot.oops-peek).

docs/source/index.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Quick Start
3030
3131
from twitter_ads.client import Client
3232
from twitter_ads.campaign import Campaign
33+
from twitter_ads.enum import ENTITY_STATUS
3334
3435
# initialize the client
3536
client = Client(CONSUMER_KEY,
@@ -43,7 +44,7 @@ Quick Start
4344
# load and update a specific campaign
4445
campaign = list(account.campaigns())[0]
4546
campaign.name = 'updated campaign name'
46-
campaign.paused = True
47+
campaign.entity_status = ENTITY_STATUS.PAUSED
4748
campaign.save()
4849
4950
# iterate through campaigns
@@ -70,13 +71,13 @@ This project is designed to work with Python 2.7 or greater. While it
7071
may work on other version of Python, below are the platform and runtime
7172
versions we officially support and regularly test against.
7273

73-
+------------+----------------------+
74-
| Platform | Versions |
75-
+============+======================+
76-
| CPython | 2.7, 3.2, 3.3, 3.4 |
77-
+------------+----------------------+
78-
| PyPy | 2.x, 4.x |
79-
+------------+----------------------+
74+
+------------+-------------------------+
75+
| Platform | Versions |
76+
+============+=========================+
77+
| CPython | 2.7, 3.3, 3.4, 3.5 |
78+
+------------+-------------------------+
79+
| PyPy | 2.x, 4.x |
80+
+------------+-------------------------+
8081

8182
All releases adhere to strict `semantic versioning`_. For Example,
8283
major.minor.patch-pre (aka. stick.carrot.oops-peek).

examples/account_media.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright (C) 2015-2016 Twitter, Inc.
2+
# Note: All account_media/media_creatives must be uploaded via the media-upload endpoints
3+
# See: https://dev.twitter.com/rest/media/uploading-media
4+
5+
from twitter_ads.client import Client
6+
from twitter_ads.http import Request
7+
from twitter_ads.enums import CREATIVE_TYPE
8+
from twitter_ads.creative import AccountMedia, MediaCreative
9+
10+
CONSUMER_KEY = 'your consumer key'
11+
CONSUMER_SECRET = 'your consumer secret'
12+
ACCESS_TOKEN = 'access token'
13+
ACCESS_TOKEN_SECRET = 'access token secret'
14+
ACCOUNT_ID = 'account id'
15+
16+
# initialize the client
17+
client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
18+
19+
# load the advertiser account instance
20+
account = client.accounts(ACCOUNT_ID)
21+
22+
# grab the first line_item on the account
23+
line_item_id = account.line_items().first.id
24+
25+
# retrive the `id` of the media creative associated with a line item
26+
print account.media_creatives().first.id
27+
28+
# retrieve the `id` of the first account media associated with the account
29+
account_media_id = account.account_media().first.id
30+
31+
# create a new account media
32+
account_media = AccountMedia(account)
33+
account_media.media_id = 'your-media-id'
34+
# OR account_media.video_id OR account_media.vast_url
35+
# see the media_upload.py example for more details
36+
account_media.creative_type = CREATIVE_TYPE.BANNER
37+
account_media.save()
38+
39+
40+
#create a new media creative
41+
media_creative = MediaCreative(account)
42+
media_creative.line_item_id = line_item_id
43+
media_creative.account_media_id = account_media_id
44+
media_creative.landing_url = "https://my-landing-url"
45+
media_creative.save()
46+
47+
# delete the media creative
48+
media_creative.delete()

examples/analytics.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
# https://dev.twitter.com/ads/analytics/metrics-and-segmentation
88
# https://dev.twitter.com/ads/analytics/metrics-derived
99

10+
import time
11+
1012
from twitter_ads.client import Client
1113
from twitter_ads.campaign import LineItem
1214
from twitter_ads.enum import METRIC_GROUP
@@ -36,3 +38,17 @@
3638
# fetching stats for multiple line items
3739
ids = map(lambda x: x.id, line_items)
3840
LineItem.all_stats(account, ids, metric_groups)
41+
42+
# fetching async stats on the instance
43+
queued_job = LineItem.queue_async_stats_job(account, ids, metric_groups)
44+
45+
# get the job_id:
46+
job_id = queued_job['id']
47+
48+
# let the job complete
49+
seconds = 15
50+
time.sleep(seconds)
51+
52+
async_stats_job_result = LineItem.async_stats_job_result(account, job_id)
53+
54+
async_data = LineItem.async_stats_job_data(account, async_stats_job_result['url'])

examples/batch_request.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from datetime import datetime
2+
3+
from twitter_ads.client import Client
4+
from twitter_ads.campaign import Campaign, LineItem, TargetingCriteria
5+
from twitter_ads.enum import ENTITY_STATUS, OBJECTIVE, PLACEMENT, PRODUCT
6+
7+
CONSUMER_KEY = 'your consumer key'
8+
CONSUMER_SECRET = 'your consumer secret'
9+
ACCESS_TOKEN = 'user access token'
10+
ACCESS_TOKEN_SECRET = 'user access token secret'
11+
ADS_ACCOUNT = 'ads account id'
12+
13+
# initialize the twitter ads api client
14+
client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
15+
16+
# load up the account instance
17+
account = client.accounts(ADS_ACCOUNT)
18+
19+
# create two campaigns
20+
campaign_1 = Campaign(account)
21+
campaign_1.funding_instrument_id = account.funding_instruments().next().id
22+
campaign_1.daily_budget_amount_local_micro = 1000000
23+
campaign_1.name = 'my first campaign'
24+
campaign_1.entity_status = ENTITY_STATUS.PAUSED
25+
campaign_1.start_time = datetime.utcnow()
26+
27+
campaign_2 = Campaign(account)
28+
campaign_2.funding_instrument_id = account.funding_instruments().next().id
29+
campaign_2.daily_budget_amount_local_micro = 2000000
30+
campaign_2.name = 'my second campaign'
31+
campaign_2.entity_status = ENTITY_STATUS.PAUSED
32+
campaign_2.start_time = datetime.utcnow()
33+
34+
campaigns_list = [campaign_1, campaign_2]
35+
Campaign.batch_save(account, campaigns_list)
36+
37+
# modify the created campaigns
38+
campaign_1.name = 'my modified first campaign'
39+
campaign_2.name = 'my modified second campaign'
40+
41+
Campaign.batch_save(account, campaigns_list)
42+
43+
# create line items for campaign_1
44+
line_item_1 = LineItem(account)
45+
line_item_1.campaign_id = campaign_1.id
46+
line_item_1.name = 'my first ad'
47+
line_item_1.product_type = PRODUCT.PROMOTED_TWEETS
48+
line_item_1.placements = [PLACEMENT.ALL_ON_TWITTER]
49+
line_item_1.objective = OBJECTIVE.TWEET_ENGAGEMENTS
50+
line_item_1.bid_amount_local_micro = 10000
51+
line_item_1.entity_status = ENTITY_STATUS.PAUSED
52+
53+
line_item_2 = LineItem(account)
54+
line_item_2.campaign_id = campaign_1.id
55+
line_item_2.name = 'my second ad'
56+
line_item_2.product_type = PRODUCT.PROMOTED_TWEETS
57+
line_item_2.placements = [PLACEMENT.ALL_ON_TWITTER]
58+
line_item_2.objective = OBJECTIVE.TWEET_ENGAGEMENTS
59+
line_item_2.bid_amount_local_micro = 20000
60+
line_item_2.entity_status = ENTITY_STATUS.PAUSED
61+
62+
line_items_list = [line_item_1, line_item_2]
63+
LineItem.batch_save(account, line_items_list)
64+
65+
# create targeting criteria for line_item_1
66+
targeting_criterion_1 = TargetingCriteria(account)
67+
targeting_criterion_1.line_item_id = line_item_1.id
68+
targeting_criterion_1.targeting_type = 'LOCATION'
69+
targeting_criterion_1.targeting_value = '00a8b25e420adc94'
70+
71+
targeting_criterion_2 = TargetingCriteria(account)
72+
targeting_criterion_2.line_item_id = line_item_1.id
73+
targeting_criterion_2.targeting_type = 'PHRASE_KEYWORD'
74+
targeting_criterion_2.targeting_value = 'righteous dude'
75+
76+
targeting_criteria_list = [targeting_criterion_1, targeting_criterion_2]
77+
TargetingCriteria.batch_save(account, targeting_criteria_list)
78+
79+
targeting_criterion_1.to_delete = True
80+
targeting_criterion_2.to_delete = True
81+
82+
TargetingCriteria.batch_save(account, targeting_criteria_list)
83+
84+
line_item_1.to_delete = True
85+
line_item_2.to_delete = True
86+
87+
LineItem.batch_save(account, line_items_list)
88+
89+
campaign_1.to_delete = True
90+
campaign_2.to_delete = True
91+
92+
Campaign.batch_save(account, campaigns_list)

examples/batch_tc_from_file.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import json
2+
3+
from twitter_ads.campaign import TargetingCriteria
4+
from twitter_ads.client import Client
5+
6+
CONSUMER_KEY = ""
7+
CONSUMER_SECRET = ""
8+
ACCESS_TOKEN = ""
9+
ACCESS_TOKEN_SECRET = ""
10+
ADS_ACCOUNT = ""
11+
12+
# initialize the twitter ads api client
13+
client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
14+
15+
# load up the account instance
16+
account = client.accounts(ADS_ACCOUNT)
17+
18+
# load file
19+
# assumes targeting.json is structured as follows
20+
"""
21+
[
22+
{
23+
"operation_type":"Create",
24+
"params":{
25+
"line_item_id":"1a2bc",
26+
"targeting_value":"digital",
27+
"operator_type":"EQ",
28+
"targeting_type":"BROAD_KEYWORD"
29+
}
30+
},
31+
{
32+
"operation_type":"Create",
33+
"params":{
34+
"line_item_id":"1a2bc",
35+
"targeting_value":"analog",
36+
"operator_type":"NE",
37+
"targeting_type":"BROAD_KEYWORD"
38+
}
39+
}
40+
]
41+
"""
42+
with open('targeting.json', 'r') as f:
43+
targeting_data = json.load(f)
44+
45+
targeting = []
46+
for obj in targeting_data:
47+
tc = TargetingCriteria(account)
48+
tc.line_item_id = obj['params']['line_item_id']
49+
tc.operator_type = obj['params']['operator_type']
50+
tc.targeting_type = obj['params']['targeting_type']
51+
tc.targeting_value = obj['params']['targeting_value']
52+
targeting.append(tc)
53+
54+
TargetingCriteria.batch_save(account, targeting)

examples/manual_request.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@
4242

4343
# execute requests and iterate cursor until exhausted
4444
for obj in cursor:
45-
print(object['name'])
45+
print(obj['name'])

examples/promoted_tweet.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
line_item = account.line_items(None, campaign_ids=campaign.id).next()
2020

2121
# create request for a simple nullcasted tweet
22-
tweet1 = Tweet.create(account, 'There can be only one...')
22+
tweet1 = Tweet.create(account, text='There can be only one...')
2323

2424
# promote the tweet using our line item
2525
promoted_tweet = PromotedTweet(account)
@@ -29,8 +29,8 @@
2929

3030
# create request for a nullcasted tweet with a website card
3131
website_card = WebsiteCard.all(account).next()
32-
status = "Fine. There can be two. {card_url}".format(card_url=website_card.preview_url)
33-
tweet2 = Tweet.create(account, status)
32+
text = "Fine. There can be two. {card_url}".format(card_url=website_card.preview_url)
33+
tweet2 = Tweet.create(account, text)
3434

3535
# promote the tweet using our line item
3636
promoted_tweet = PromotedTweet(account)

examples/quick_start.py

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

33
from twitter_ads.client import Client
44
from twitter_ads.campaign import Campaign, LineItem, TargetingCriteria
5-
from twitter_ads.enum import PRODUCT, PLACEMENT, OBJECTIVE
5+
from twitter_ads.enum import ENTITY_STATUS, OBJECTIVE, PLACEMENT, PRODUCT
66

77
CONSUMER_KEY = 'your consumer key'
88
CONSUMER_SECRET = 'your consumer secret'
@@ -21,7 +21,7 @@
2121
campaign.funding_instrument_id = account.funding_instruments().next().id
2222
campaign.daily_budget_amount_local_micro = 1000000
2323
campaign.name = 'my first campaign'
24-
campaign.paused = True
24+
campaign.entity_status = ENTITY_STATUS.PAUSED
2525
campaign.start_time = datetime.utcnow()
2626
campaign.save()
2727

@@ -33,7 +33,7 @@
3333
line_item.placements = [PLACEMENT.ALL_ON_TWITTER]
3434
line_item.objective = OBJECTIVE.TWEET_ENGAGEMENTS
3535
line_item.bid_amount_local_micro = 10000
36-
line_item.paused = True
36+
line_item.entity_status = ENTITY_STATUS.PAUSED
3737
line_item.save()
3838

3939
# add targeting criteria

0 commit comments

Comments
 (0)