-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Alexander Schaefer
committed
Mar 1, 2017
0 parents
commit 04fa509
Showing
12 changed files
with
533 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*.egg-info/ | ||
__pycache__ | ||
.idea | ||
venv/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (c) 2017 Mara contributors | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# BingAds Performance Downloader | ||
|
||
A Python script for downloading performance data from the [BingAds API version 9](https://msdn.microsoft.com/en-us/library/bing-ads-overview(v=msads.100).aspx) to local files. The code is largely based on [Bing Ads Python SDK](https://github.com/BingAds/BingAds-Python-SDK). | ||
|
||
|
||
## Resulting data | ||
**BingAds Performance Downloader** gives measures such as impressions, clicks and cost. The script creates one csv file per day in a specified time range: | ||
|
||
/tmp/bingads/2016/05/02/bing/download.csv | ||
/tmp/bingads/2016/05/03/bing/download.csv | ||
|
||
|
||
Each line contains one ad for one day: | ||
|
||
GregorianDate | 2/12/2016 | ||
AccountId | 17837800573 | ||
AccountName | Online Veiling Gent | ||
CampaignId | 254776453 | ||
CampaignName | Veiling Gent | ||
AdGroupId | 3508678047 | ||
AdGroupName | BE_NL_GEN_Auction_City_{e} | ||
AdId | 9011292478 | ||
Keyword | Veiling | ||
KeywordId | 2271053633 | ||
Device type | Tablet | ||
BiddedMatchType | Phrase | ||
Clicks | 0 | ||
Impressions | 5 | ||
Ctr | 0.00 | ||
AverageCpc | 0.00 | ||
Spend | 0.00 | ||
QualityScore | 8 | ||
Conversions | 0 | ||
Revenue | 0 | ||
Network | Bing and Yahoo! search | ||
|
||
|
||
## Getting Started | ||
|
||
|
||
### Installation | ||
|
||
The Google AdWords Performance Downloader requires: | ||
|
||
Python (>= 3.5) | ||
bingads (>=10.4.11) | ||
click (>=6.0) | ||
|
||
The easiest way to install google-adwords-downloader is using pip | ||
|
||
pip install git+https://github.com/mara/bingads-performance-downloader.git | ||
|
||
If you want to install it in a virtual environment: | ||
|
||
$ git clone [email protected]:mara/bingads-performance-downloader.git bingads_downloader | ||
$ cd bingads_downloader | ||
$ python3 -m venv venv | ||
$ venv/bin/pip install . | ||
|
||
### Set up your OAuth2 credentials | ||
|
||
Getting access to the Bing Ads Account: | ||
|
||
Ask your SEM manager to invite you to the Bing Ads Account of the company. The role should be Super Admin. Once you receive the confirmation e-mail | ||
(may take up to 2 hours), you should click on the link and create a Microsoft account. | ||
|
||
Getting **developer token**: | ||
Go to this page https://developers.bingads.microsoft.com/Account, you will find your developer-token. You have to be logged in with your Microsoft account. | ||
|
||
Getting **oauth client id** and **oauth client secret** : | ||
Go to this page https://apps.dev.microsoft.com/. You have to be logged in with your Microsoft account. | ||
|
||
![](docs/Register-App-for-BingAds.png) | ||
|
||
Follow these steps: | ||
|
||
Copy the Application Id, it will be the 'oauth-client-id' () | ||
Copy now the field 'Password/Public key' as 'oauth-client-secret' () | ||
Copy now the redirect URI as 'oauth-client-redirect-uri' () | ||
|
||
|
||
In order to access the BingAds API you have to obtain the OAuth2 credentials from BingAds. | ||
|
||
$ refresh-bingsads-api-oauth2-token \ | ||
--developer_token ABCDEFEGHIJKL \ | ||
--oauth2_client_id 123456789 \ | ||
--oauth2_client_secret aBcDeFg | ||
|
||
This will open a webbrowser to allow the OAuth2 credentials to access the API on your behalf. | ||
![](docs/oauth1.png) | ||
![](docs/oauth2.png) | ||
|
||
Copy the url from the browser as instructed in the commandline. Copy and paste it into the command line where you are running | ||
`bingads-downloader-refresh-oauth2-token` and press enter. | ||
|
||
![](docs/oauth3.png) | ||
|
||
The script should complete and display an offline **refresh token** on the command line. Keep this refresh token for the download step. | ||
|
||
## Usage | ||
|
||
To run the BingAds Performance Downloader call `download-bingsads-performance-data` with its config: | ||
|
||
$ download-bingsads-performance-data \ | ||
--developer_token ABCDEFEGHIJKL \ | ||
--oauth2_client_id 123456789 \ | ||
--oauth2_client_secret aBcDeFg \ | ||
--oauth2_refresh_token MCQL58pByMOdq*sU7 \ | ||
--data_dir /tmp/bingads | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from bingads_downloader import cli,config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
"""Command line interface for adwords downloader""" | ||
|
||
import click | ||
from bingads_downloader import downloader,config | ||
from functools import partial | ||
|
||
|
||
def config_option(config_function): | ||
"""Helper decorator that turns an option function into a cli option""" | ||
|
||
return lambda function: \ | ||
click.option('--' + config_function.__name__, | ||
help=config_function.__doc__ + '. Example: "' + config_function() + '"') \ | ||
(function) | ||
|
||
|
||
def apply_options(kwargs): | ||
"""Applies passed cli parameters to config.py""" | ||
for key, value in kwargs.items(): | ||
if value: setattr(config, key, partial(lambda v: v, value)) | ||
|
||
|
||
@click.command() | ||
@config_option(config.developer_token) | ||
@config_option(config.oauth2_client_id) | ||
@config_option(config.oauth2_client_secret) | ||
def refresh_oauth2_token(**kwargs): | ||
""" | ||
Creates a new OAuth2 token. | ||
When options are not specified, then the defaults from config.py are used. | ||
""" | ||
apply_options(kwargs) | ||
downloader.refresh_oauth_token() | ||
|
||
|
||
@click.command() | ||
@config_option(config.developer_token) | ||
@config_option(config.oauth2_client_id) | ||
@config_option(config.oauth2_client_secret) | ||
@config_option(config.oauth2_refresh_token) | ||
@config_option(config.data_dir) | ||
@config_option(config.first_date) | ||
def download_data(**kwargs): | ||
""" | ||
Downloads data. | ||
When options are not specified, then the defaults from config.py are used. | ||
""" | ||
apply_options(kwargs) | ||
downloader.download_data() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
""" | ||
Configures access to BingAds API and where to store results | ||
""" | ||
|
||
|
||
def data_dir() -> str: | ||
"""The directory where result data is written to""" | ||
return '/tmp/bingads/' | ||
|
||
|
||
def data_file() -> str: | ||
"""The name of the file the result is written to""" | ||
return 'download.csv.gz' | ||
|
||
|
||
def first_date() -> str: | ||
"""The first day from which on data will be downloaded""" | ||
return '2015-01-01' | ||
|
||
def developer_token() -> str: | ||
"""The developer token that is used to access the BingAds API""" | ||
return '012A3B3C4D001234' | ||
|
||
|
||
def environment() -> str: | ||
"""The deployment environment""" | ||
return 'production' | ||
|
||
|
||
def oauth2_client_id() -> str: | ||
"""The Oauth client id obtained from the BingAds developer center""" | ||
return 'a411bc41-12d4-1234-b123-ef120120g387' | ||
|
||
|
||
def oauth2_client_state() -> str: | ||
"""non guessable client state""" | ||
return '123456' | ||
|
||
|
||
def oauth2_client_secret() -> str: | ||
"""The Oauth client secret obtained from the BingAds developer center""" | ||
return 'a1B2Cde1Fi9g2hIjKLMno5p' | ||
|
||
|
||
def oauth2_refresh_token() -> str: | ||
"""The Oauth refresh token returned from the adwords-downloader-refresh-oauth2-token script""" | ||
return 'ABCdeFgHi!hTXYUDAhSRFZtc2b9n1YyZBDc5BBx9ckPit0EVkMJYgMhlz!aeVbqiFMdbwe69QZVKOIpd2Ns8MHrPU1haST2svtx0zOcdhUQe7Sdnl1AgBVe21xm4dTH9CdG9GIPAZlGH!QZQTP97wsb0ROvn2y71b*VBodw9wjiS0GIWyr8jcsQoYUPUSsP*ST*gRnPtM4Sst0XmEswNhk15OI1gL9OLCYwDl89*mSQUJkuV11vgkV9kZy3spqTEK0toBkgYInLf5EBCxUaZkKVDqUpv*xRCqrU3Ae0wyZFDJwq7DjmUQig7pKofqumVwZ3EqYA0U732g2Dlcf8u8LjM$' | ||
|
||
|
||
def timeout() -> int: | ||
# The maximum amount of time (in milliseconds) that you want to wait for the report download. | ||
return 3600000 |
Oops, something went wrong.