Added new functions to Twitter Ads API, together with integration tests for them.
This commit is contained in:
parent
4b83630850
commit
1b4aba0b3a
2 changed files with 78 additions and 19 deletions
|
|
@ -1,4 +1,7 @@
|
||||||
|
import base64
|
||||||
import datetime
|
import datetime
|
||||||
|
import cStringIO
|
||||||
|
import urllib
|
||||||
from twython import Twython, TwythonError, TwythonAuthError
|
from twython import Twython, TwythonError, TwythonAuthError
|
||||||
|
|
||||||
from .config import (
|
from .config import (
|
||||||
|
|
@ -21,8 +24,16 @@ class TwythonEndpointsTestCase(unittest.TestCase):
|
||||||
'paused': True
|
'paused': True
|
||||||
}
|
}
|
||||||
|
|
||||||
def setUp(self):
|
TEST_WEBSITE_CLICKS_LINE_ITEM = {
|
||||||
|
'bid_type': 'MAX',
|
||||||
|
'bid_amount_local_micro': 2000000,
|
||||||
|
'product_type': 'PROMOTED_TWEETS',
|
||||||
|
'placements': 'ALL_ON_TWITTER',
|
||||||
|
'objective': 'WEBSITE_CLICKS',
|
||||||
|
'paused': True
|
||||||
|
}
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
client_args = {
|
client_args = {
|
||||||
'headers': {
|
'headers': {
|
||||||
'User-Agent': '__twython__ Test'
|
'User-Agent': '__twython__ Test'
|
||||||
|
|
@ -37,8 +48,8 @@ class TwythonEndpointsTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
|
|
||||||
self.api = TwythonAds(app_key, app_secret,
|
self.api = TwythonAds(app_key, app_secret,
|
||||||
oauth_token, oauth_token_secret,
|
oauth_token, oauth_token_secret,
|
||||||
client_args=client_args)
|
client_args=client_args)
|
||||||
|
|
||||||
self.oauth2_api = Twython(app_key, access_token=access_token,
|
self.oauth2_api = Twython(app_key, access_token=access_token,
|
||||||
client_args=oauth2_client_args)
|
client_args=oauth2_client_args)
|
||||||
|
|
@ -72,34 +83,69 @@ class TwythonEndpointsTestCase(unittest.TestCase):
|
||||||
iab_categories = self.api.get_iab_categories()
|
iab_categories = self.api.get_iab_categories()
|
||||||
self.assertTrue(len(iab_categories) > 0)
|
self.assertTrue(len(iab_categories) > 0)
|
||||||
|
|
||||||
|
def test_get_available_platforms(self):
|
||||||
|
available_platforms = self.api.get_available_platforms()
|
||||||
|
self.assertTrue(len(available_platforms) > 0)
|
||||||
|
|
||||||
def test_get_campaigns(self):
|
def test_get_campaigns(self):
|
||||||
campaigns = self.api.get_campaigns(test_account_id)
|
campaigns = self.api.get_campaigns(test_account_id)
|
||||||
self.assertTrue(len(campaigns) > 0)
|
self.assertTrue(len(campaigns) > 0)
|
||||||
|
|
||||||
def test_create_and_delete_campaign(self):
|
def test_create_and_delete_campaign(self):
|
||||||
|
campaign_id = self._create_test_campaign()
|
||||||
|
campaign_check = self.api.get_campaign(test_account_id, campaign_id)
|
||||||
|
self.assertEqual(campaign_check['id'], campaign_id)
|
||||||
|
self._delete_test_campaign(campaign_id)
|
||||||
|
|
||||||
|
def _create_test_campaign(self):
|
||||||
campaign = self.api.create_campaign(test_account_id, **self.TEST_CAMPAIGN)
|
campaign = self.api.create_campaign(test_account_id, **self.TEST_CAMPAIGN)
|
||||||
campaign_id = campaign['id']
|
campaign_id = campaign['id']
|
||||||
self.assertEqual(campaign['account_id'], test_account_id)
|
self.assertEqual(campaign['account_id'], test_account_id)
|
||||||
self.assertIsNotNone(campaign_id)
|
self.assertIsNotNone(campaign_id)
|
||||||
campaign_check = self.api.get_campaign(test_account_id, campaign_id)
|
return campaign_id
|
||||||
self.assertEqual(campaign_check['id'], campaign_id)
|
|
||||||
|
def _delete_test_campaign(self, campaign_id):
|
||||||
is_deleted = self.api.delete_campaign(test_account_id, campaign_id)
|
is_deleted = self.api.delete_campaign(test_account_id, campaign_id)
|
||||||
self.assertTrue(is_deleted)
|
self.assertTrue(is_deleted)
|
||||||
|
|
||||||
def test_create_line_item(self):
|
def test_create_line_item(self):
|
||||||
campaign = self.api.create_campaign(test_account_id, **self.TEST_CAMPAIGN)
|
campaign_id = self._create_test_campaign()
|
||||||
campaign_id = campaign['id']
|
response = self.api.create_line_item(test_account_id, campaign_id, **self.TEST_WEBSITE_CLICKS_LINE_ITEM)
|
||||||
self.assertEqual(campaign['account_id'], test_account_id)
|
|
||||||
website_clicks_line_item = {
|
|
||||||
'bid_type': 'MAX',
|
|
||||||
'bid_amount_local_micro': 2000000,
|
|
||||||
'product_type': 'PROMOTED_TWEETS',
|
|
||||||
'placements': 'ALL_ON_TWITTER',
|
|
||||||
'objective': 'WEBSITE_CLICKS',
|
|
||||||
'paused': True
|
|
||||||
}
|
|
||||||
response = self.api.create_line_item(test_account_id, campaign_id, **website_clicks_line_item)
|
|
||||||
self.assertEqual(response['account_id'], test_account_id)
|
self.assertEqual(response['account_id'], test_account_id)
|
||||||
self.assertEqual(response['campaign_id'], campaign_id)
|
self.assertEqual(response['campaign_id'], campaign_id)
|
||||||
campaign_check = self.api.get_campaign(test_account_id, campaign_id)
|
self._delete_test_campaign(campaign_id)
|
||||||
self.assertTrue(True)
|
|
||||||
|
def test_upload_image(self):
|
||||||
|
response = self._upload_test_image()
|
||||||
|
self.assertIsNotNone(response['media_id'])
|
||||||
|
|
||||||
|
def _upload_test_image(self):
|
||||||
|
image_file = urllib.urlopen('https://upload.wikimedia.org/wikipedia/commons/d/db/Patern_test.jpg').read()
|
||||||
|
image_file_encoded = base64.b64encode(image_file)
|
||||||
|
upload_data = {
|
||||||
|
'media_data': image_file_encoded
|
||||||
|
# the line below will have to be provided once we start uploading photos on behalf of advertisers
|
||||||
|
# 'additional_owners': ''
|
||||||
|
}
|
||||||
|
response = self.api.upload_image(**upload_data)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def test_create_cards_website(self):
|
||||||
|
# campaign = self.api.create_campaign(test_account_id, **self.TEST_CAMPAIGN)
|
||||||
|
# campaign_id = campaign['id']
|
||||||
|
# self.assertEqual(campaign['account_id'], test_account_id)
|
||||||
|
# line_item = self.api.create_line_item(test_account_id, campaign_id, **self.TEST_WEBSITE_CLICKS_LINE_ITEM)
|
||||||
|
# self.assertEqual(line_item['account_id'], test_account_id)
|
||||||
|
# self.assertEqual(line_item['campaign_id'], campaign_id)
|
||||||
|
uploaded_image = self._upload_test_image()
|
||||||
|
test_website_card = {
|
||||||
|
'name': 'Zemanta Partnered with AdsNative for Programmatic Native Supply',
|
||||||
|
'website_title': 'Zemanta Partnered with AdsNative for Programmatic Native Supply',
|
||||||
|
'website_url': 'http://r1.zemanta.com/r/u1tllsoizjls/facebook/1009/92325/',
|
||||||
|
'website_cta': 'READ_MORE',
|
||||||
|
'image_media_id': uploaded_image['media_id_string']
|
||||||
|
}
|
||||||
|
response = self.api.create_website_card(test_account_id, **test_website_card)
|
||||||
|
self.assertEqual(response['account_id'], test_account_id)
|
||||||
|
# is_deleted = self.api.delete_campaign(test_account_id, campaign_id)
|
||||||
|
# self.assertTrue(is_deleted)
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,10 @@ class EndpointsAdsMixin(object):
|
||||||
response = self.get('iab_categories', params=params)
|
response = self.get('iab_categories', params=params)
|
||||||
return response['data']
|
return response['data']
|
||||||
|
|
||||||
|
def get_available_platforms(self, **params):
|
||||||
|
response = self.get('targeting_criteria/platforms')
|
||||||
|
return response['data']
|
||||||
|
|
||||||
def get_campaigns(self, account_id, **params):
|
def get_campaigns(self, account_id, **params):
|
||||||
response = self.get('accounts/%s/campaigns' % account_id, params=params)
|
response = self.get('accounts/%s/campaigns' % account_id, params=params)
|
||||||
return response['data']
|
return response['data']
|
||||||
|
|
@ -69,3 +73,12 @@ class EndpointsAdsMixin(object):
|
||||||
params_extended['campaign_id'] = campaign_id
|
params_extended['campaign_id'] = campaign_id
|
||||||
response = self.post('accounts/%s/line_items' % account_id, params=params_extended)
|
response = self.post('accounts/%s/line_items' % account_id, params=params_extended)
|
||||||
return response['data']
|
return response['data']
|
||||||
|
|
||||||
|
def create_website_card(self, account_id, **params):
|
||||||
|
# TODO: handle the case where name, website_title, website_url are too long!
|
||||||
|
response = self.post('accounts/%s/cards/website' % account_id, params=params)
|
||||||
|
return response['data']
|
||||||
|
|
||||||
|
def upload_image(self, **params):
|
||||||
|
response = self.post('https://upload.twitter.com/1.1/media/upload.json', params=params)
|
||||||
|
return response
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue