Creating a DfpClient with a Service Account in Python

828 Views Asked by At

I use the google DFP api to collect some statistics on ads clicked on our website. The
code is written in Python. Currently, I am trying to upgrade the code to use oAuth 2.
Since, the code runs automatically everyday without any user involvement, I created a
service account under my google project and added the account to the DoubleClick for
Publishers network of our company. Based on the sample codes on the web, I wrote this:

import httplib2  
from oauth2client.client import SignedJwtAssertionCredentials
from apiclient.discovery import build  
from googleads.dfp import DfpClient

GOOGLE_DFP_SCOPE="https://www.googleapis.com/auth/dfp"  
API_VERSION="v201411"  
KEY_FILE="*******.p12"  
ACCT_EMAIL="************************@developer.gserviceaccount.com"  
NETWORK_CODE="**********"
with open(KEY_FILE) as config_file:
    my_private_key = config_file.read()  
credentials = SignedJwtAssertionCredentials(service_account_name=ACCT_EMAIL, private_key=my_private_key,scope=GOOGLE_DFP_SCOPE)  
http = httplib2.Http()
http_auth = credentials.authorize(http)  
dfp_client = build(serviceName='dfp',version=API_VERSION,http=http_auth)

This code does not seem to be correct, because the network_code has not been passed anywhere in the code. In addition, it fails with the following message:

apiclient.errors.UnknownApiNameOrVersion: name: dfp version: v201411.

Also, the line below:

dfp_client = DfpClient.LoadFromStorage()

does not work for my case, because, this is based on googleads.yaml which seems to be formatted only for web-app accounts with client secret, not P12 private key.

Any advice? Thanks.

2

There are 2 best solutions below

2
On

You are correct. You have to pass the network code when you create a dfp client. And version is not necessary. Try the following code to create the client in python.

import os

from googleads import oauth2
from googleads import dfp

def get_dfp_client():
    application_name = "Your application name" # from google developer console. eg: Web Client
    network_code = ********
    private_key_password = 'notasecret'
    key_file = os.path.join('path/to/p12file')
    service_account_email = '****@***.iam.gserviceaccount.com'
    # create oath2 client(google login)
    oauth2_client = oauth2.GoogleServiceAccountClient(
      oauth2.GetAPIScope('dfp'), service_account_email, key_file)

    dfp_client = dfp.DfpClient(oauth2_client, application_name, network_code)
    return dfp_client

client = get_dfp_client()

Reference

Please comment if you need more clarification.

Update

googleads renamed module dfp to ad_manager, docs here – Gocht

0
On

Apiclient.discovery uses a default route to check the services. But I did not find a service for DoubleClick for publishers.

I use this code to use API with Oauth2. Using Flask

import json
import requests
import flask

from googleads import dfp
from googleads import oauth2

app = flask.Flask(__name__)

CLIENT_ID = ''
CLIENT_SECRET = ''  # Read from a file or environmental variable in a real app
SCOPE = 'https://www.googleapis.com/auth/dfp'
REDIRECT_URI = ''
APPLICATION_NAME = 'DFP API SERVICE'
NETWORK_CODE = ''


@app.route('/')
def index():

    if 'credentials' not in flask.session:
        return flask.redirect(flask.url_for('oauth2callback'))
    credentials = json.loads(flask.session['credentials'])
    if credentials['expires_in'] <= 0:
       return flask.redirect(flask.url_for('oauth2callback'))
    else:
        try:
            refresh_token = credentials['refresh_token']
            oauth2_client = oauth2.GoogleRefreshTokenClient(CLIENT_ID, CLIENT_SECRET, refresh_token)
            dfp_client = dfp.DfpClient(oauth2_client, APPLICATION_NAME, NETWORK_CODE)
            user_service = dfp_client.GetService('UserService', version='v201508')
            user = user_service.getCurrentUser()
            return flask.render_template('index.html', name=user['name'])
        except:
            flask.session.pop('credentials', None)
            return flask.redirect(flask.url_for('oauth2callback'))

@app.route('/oauth2callback')
def oauth2callback():
    if 'code' not in flask.request.args:
        auth_uri = ('https://accounts.google.com/o/oauth2/auth?response_type=code'
                '&access_type=offline&client_id={}&redirect_uri={}&scope={}&').format(CLIENT_ID, REDIRECT_URI, SCOPE)
        return flask.redirect(auth_uri)
    else:
        auth_code = flask.request.args.get('code')
        data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}
        r = requests.post('https://www.googleapis.com/oauth2/v3/token', data=data)
        flask.session['credentials'] = r.text
        return flask.redirect(flask.url_for('index'))

if __name__ == '__main__':
    import uuid
    app.secret_key = str(uuid.uuid4())
    app.debug = False
    app.run()

I hope this help you