Google Analytics

Management API - Using Python

This document explains how to access the Management API using the Python programming language and walks through a simple example. For an introduction to purpose of the the Management API and the data it provides, see Getting Started.

  1. Introduction
  2. Before You Begin
  3. Authorizing Requests
  4. Instantiating a New Service Object
  1. Making API Requests & Handling Errors
    1. Accounts
    2. Web Properties
    3. Views (Profiles)
    4. Goals
    5. Advanced Segments
 

Introduction

The Google APIs Client Library for Python simplifies working with the Google Analytics Management API. It provides wrappers for retrieving authorization tokens, a simple interface for issuing API requests, and helpful libraries to parse the API responses into a Python dictionary.

This guide describes how to write a basic Python client application that exercises all the key steps needed to use the Management API:

  1. Retrieving a new OAuth 2.0 authorization token
  2. Instantiating a new authorized service object
  3. Executing API requests to retrieve configuration data
  4. Working with the response
  5. Handling errors

Before You Begin

Before working with the sample code in this guide, you must do the following:

Get The Library – Install the Google APIs Python client library, which provides all the logic and wrappers to work with the API.

Register Your Application – Every request your application sends to the Management API must be authorized by an authenticated user. To authenticate users in this example, you must register your application to use a OAuth 2.0 token for an installed application in the Google Developers Console, as described in Authorization.

After configuring these dependencies, you can run an application that uses the Python client library, such as the sample application in this guide. The rest of this guide walks through each step in the sample application.

Back to Top

Authorizing Requests

Just as you must log in to the Google Analytics interface in order to view your data, your application must also obtain authorization in order to access a user's Analytics data. Version 3.0 of the API supports authorization using OAuth 2.0 tokens.

To set up authorization, you need to register a new project in the Google Developers Console and configure it to use OAuth 2.0 for an installed application. Registration gives you the two things that you need in order to work with the API:

  • a unique clientId
  • a clientSecret

Note: For details about how to authorize OAuth 2.0 requests in other environments, such as server or client side web applications, see Authorizing requests.

When the sample application in this guide runs for the first time, it prompts the user to authorize access to their data by navigating to a URL and approving access. Once the approval is granted, they are given an authorization code. The user must supply this authorization code back to the application, at which time the application uses the code to get an OAuth 2.0 access token and a refresh token.

The application uses the access token to access a user's data from the API. The token is valid for an unspecified period of time. For efficiency, an application should reuse a token as long as possible. When a token becomes invalid, the API returns a 401 status code. The application can then use the refresh token to retrieve a new access token, as this sample code does.

The Python client library simplifies authorization by providing wrappers to handle both the OAuth 2.0 flow as well as the reuse of existing tokens by saving and reading them from disk. The following code handles OAuth 2.0 authorization for installed apps.

from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.file import Storage
from oauth2client.tools import run

FLOW = OAuth2WebServerFlow( client_id='INSERT_YOUR_CLIENT_ID',
    client_secret='INSERT_YOUR_CLIENT_SECRET',
    scope='https://www.googleapis.com/auth/analytics.readonly',
    user_agent='analytics-api-v3-awesomeness')

TOKEN_FILE_NAME = 'analytics.dat'

storage = Storage(TOKEN_FILE_NAME)
credentials = storage.get()
if not credentials or credentials.invalid:
  # Get a new token.
  credentials = run(FLOW, storage)

When executed, the code either prompts the user to grant the application access to their data (after which a new token is stored in TOKEN_FILE_NAME), or else reads an existing token set in the credentials object on file.

After the authentication code executes, the application has an authorization credentials object it can use to instantiate a service object to work with the API.

Instantiating a New Service Object

The Python client library simplifies working with the Management API by providing a service object for issuing requests and parsing responses.

To create this service object, the application first instantiates an httplib2 object. Then it uses the credentials object from the previous authorization step to authorize all of the http requests. Finally, it uses the build method imported from the Python client library to instantiate the service object. It passes the service name, version, and the authorized http object as parameters, as shown in the following sample code:

from apiclient.discovery import build
import httplib2

http = httplib2.Http()
http = credentials.authorize(http)
service = build('analytics', 'v3', http=http)

After the application executes this simple code to instantiate the service object, it can start making authorized requests to the Management API.

Back to Top

Making API Requests & Handling Errors

An application uses the Analytics service object to make all requests to the Management API. The five kinds of request to the API are all pretty similar: for a given authenticated user, each request returns a list of one kind of entity. The list is called a collection and the entity is called a resource.

As explained in Getting Started, the types of entities are organized in a hierarchy: An Account is a top-level entity, each Account can have a collection of Web Properties as children, and so on. The sample application makes API requests on the Analytics service object it instantiated earlier to traverse the hierarchy. For example, the following code calls the API to get a list of a user's accounts.

from apiclient.errors import HttpError
from oauth2client.client import AccessTokenRefreshError

try:

  # Attempt making the request.
  accounts_list = service.management().accounts().list().execute()

except AccessTokenRefreshError:
  print ('The credentials have been revoked or expired, please re-run'
         'the application to re-authorize')

except HttpError, error:
  print ('Arg, there was an API error : %s %s : %s' %
          (error.resp.status, error.resp.reason, error._get_reason()))

If the call succeeds, an object containing a list of all the user's accounts is stored in accounts_list. If the call failed, then an error occurred that the application needs to handle, as the sample code above shows.

Handling errors

The Analytics service object can raise two kinds of exception:

  • For Authorization errors, an oauth2client.client.AccessTokenRefreshError error is raised. In this case, there is a problem with the Authorization token and the applications should redirect the user through the authorization process to get a new token.
  • For Management API errors, an apiclient.errors.HttpError error is raised. In this case, the application us accessing the API incorrectly. You need to stop, look at the error message, and fix the way application is accessing the API.

Every request an application makes to the Management API should include error handling. But to avoid cluttering the examples with error-handling code, the rest of this guide shows only the code for API requests and responses.

Back to Top

Working with Accounts

A Google Analytics Account is a top level entity in the Management API. It has no parent, and it has a collection of Web Property resources as children. To request a list of Analytics accounts to which the user has access, use the Analytics service object instantiated in the example above.

accounts_list = service.management().accounts().list().execute()

The results of the list method are in the accounts_list object. The following code shows how to iterate through them. For a list of all the properties of an Account resource, see Account Collection.

for account in accounts_list.get('items'):
  print 'Account ID      = %s' % account.get('id')
  print 'Kind            = %s' % account.get('kind')
  print 'Self Link       = %s' % account.get('selfLink')
  print 'Account Name    = %s' % account.get('name')
  print 'Created         = %s' % account.get('created')
  print 'Updated         = %s' % account.get('updated')

  child_link = account.get('childLink')
  print 'Child link href = %s' % child_link.get('href')
  print 'Child link type = %s' % child_link.get('type')

The sample application uses the Account ID returned by get('id') as a parameter to subsequent queries shown in upcoming sections.

Back to Top

Working with Web Properties

A Google Analytics Web Property is at the second level in the account hierarchy; each Web Property has a single Account as its parent in the hierarchy. and can have a collection of one or more views (profiles) children.

An application can requests a list of the web properties for one of a user's accounts by using the service object and passing the Account ID in the accountId parameter to the list method. For example, the following code requests a list of all web properties for the account with ID 12345.

webproperties_list =
    service.management().webproperties().list(
        accountId='12345').execute())

The list method for web properties requires an accountId parameter that specifies which account to use when retrieving the list of web properties. To retrieve the web properties for all of the user's accounts, you can use the wildcard ~all as the accountId, as shown in the following code.

webproperties_list =
    service.management().webproperties().list(
        accountId='~all').execute())

The results of the list method are stored in the webproperties_list object. The following code shows how to iterate through them. For a list of all the properties of a Webproperty entity, see Webproperties Collection.

for webproperty in webproperties_list.get('items'):
  print 'Kind               = %s' % webproperty.get('kind')
  print 'Account ID         = %s' % webproperty.get('accountId')
  print 'Web Property ID    = %s' % webproperty.get('id')
  print ('Internal Web Property ID = %s' %
         goal.get('internalWebPropertyId'))

  print 'Website URL        = %s' % webproperty.get('websiteUrl')
  print 'Created            = %s' % webproperty.get('created')
  print 'Updated            = %s' % webproperty.get('updated')

  print 'Self Link          = %s' % webproperty.get('selfLink')

  parent_link = webproperty.get('parentLink')
  print 'Parent link href   = %s' % parent_link.get('href')
  print 'Parent link type   = %s' % parent_link.get('type')

  child_link = webproperty.get('childLink')
  print 'Child link href    = %s' % child_link.get('href')
  print 'Child link type    = %s' % child_link.get('type')

The sample application uses the Web Property ID returned by get('id') as a parameter to subsequent queries in upcoming sections of this guide.

Back to Top

Working with Views (Profiles)

A Google Analytics View (Profile) entity is at the third level in the Account hierarchy. Each View (Profile) has a single Web Property as its parent in the hierarchy and can have a collection of zero or more Goal resources as children.

The View (Profile) entity plays an important role in retrieving report data through the Core Reporting API, because accessing the Data Feed requires a View (Profile) ID as a tableId parameter.

An application requests a list of views (profiles) available to the user by calling the list method for Views (Profiles). This method requires both an accountId and a webPropertyId parameter.

To request views (profiles) for a particular account and web property, you specify each ID, as shown in the following example code.

profiles_list =
    service.management().profiles().list(
        accountId='12345', webPropertyId='UA-12345-1').execute()

To request the views (profiles) for all the web properties of a particular account, you an use the wildcard in place of the webPropertyId. The result of the following code is a list of views (profiles) for all the web properties of the Account with ID 12345.

profiles_list =
    service.management().profiles().list(
        accountId='12345', webPropertyId='~all').execute()

To request all views (profiles) available to the user, you use the ~all wildcard for both ID parameters. The result of the following code is a list of views (profiles) for all the web properties of all the user's Accounts.

  profiles_list =
      service.management().profiles().list(
          accountId='~all', webPropertyId='~all').execute()

Note: In all Management API requests, you cannot specify a particular child ID as a parameter if you used ~all for its parent. For example, the following request is invalid because it passes accountId as the parent of the web property UA-123-1 rather than a specific accountId.

  profiles_list =
      service.management().profiles().list(
          accountId='~all', webPropertyId='UA-123-1').execute()

The results from the list method are stored in the profiles_list object. The following code shows how to iterate through them. For a list of all the properties of a profile entity, see Views (Profiles) Collection.

for profile in profiles_list.get('items'):
  print 'Kind                      = %s' % profile.get('kind')
  print 'Account ID                = %s' % profile.get('accountId')
  print 'Web Property ID           = %s' % profile.get('webPropertyId')
  print 'Internal Web Property ID  = %s' % profile.get('internalWebPropertyId')
  print 'View (Profile) ID         = %s' % profile.get('id')
  print 'View (Profile) Name       = %s' % profile.get('name')

  print 'Currency                  = %s' % profile.get('currency')
  print 'Timezone                  = %s' % profile.get('timezone')
  print 'Default Page              = %s' % profile.get('defaultPage')

  print 'Exclude Query Parameters        = %s' % profile.get('excludeQueryParameters')
  print 'Site Search Category Parameters = %s' % profile.get('siteSearchCategoryParameters')
  print 'Site Search Query Parameters    = %s' % profile.get('siteSearchQueryParameters')

  print 'Created          = %s' % profile.get('created')
  print 'Updated          = %s' % profile.get('updated')

  print 'Self Link        = %s' % profile.get('selfLink')

  parent_link = profile.get('parentLink')
  print 'Parent link href = %s' % parent_link.get('href')
  print 'Parent link type = %s' % parent_link.get('type')

  child_link = profile.get('childLink')
  print 'Child link href  = %s' % child_link.get('href')
  print 'Child link type  = %s' % child_link.get('type')

In the next section, the sample application uses the View (Profile) ID returned by get('id') as a parameter for requesting a collection of Goal resources in the next section. The important use of this ID in a real application is to pass it as the ids parameter to a Data Feed request in the Core Reporting API.

Back to Top

Working with Goals

A Google Analytics Goal is at the fourth and lowest level in the account hierarchy; goals have no child entities. Each Goal resource has a single View (Profile) resource as its parent in the hierarchy. The Goal data provided in the Management API describes how a goal is configured: its name, its value, type, and whether or not it is active.

The sample application requests a list of a user's goals by calling the list method for Goals on the Analytics service object. The method requires an accountId, a webPropertyId, and a profileId as parameters.

To request goals for a single view (profile), you specify the ID of the Account, Web Property, and View (Profile), as in the following code.

goals_list =
    service.management().goals().list(
        accountId='12345', webPropertyId='UA-12345-1', profileId='420').execute()

To request all goals for all views (profiles) for the user, you use the ~all wildcard, as in the following code.

goals_list =
    service.management().goals().list(
        accountId='~all', webPropertyId='~all', profileId='~all').execute()

Note: In all Management API requests, you cannot specify a particular child ID as a parameter if you used ~all for its parent.

For example, the following list request is invalid because it passes the specific profileID 420 but uses the wildcard ~all as the webPropertyId.

goals_list =
    service.management().goals().list(
        accountId='~all', webPropertyId='~all', profileId='420').execute()

The results of the list method for goals are stored in the goals_list object. The following code shows how to iterate through them. For a list of all the properties of a Goal resource, see Goals Collection.

for goal in goals_list.get('items'):
  print 'Goal ID     = %s' % goal.get('id')
  print 'Kind        = %s' % goal.get('kind')
  print 'Self Link   = %s' % goal.get('selfLink')

  print 'Account ID               = %s' % goal.get('accountId')
  print 'Web Property ID          = %s' % goal.get('webPropertyId')
  print 'Internal Web Property ID = %s' % goal.get('internalWebPropertyId')
  print 'View (Profile ID)        = %s' % goal.get('profileId')

  print 'Goal Name   = %s' % goal.get('name')
  print 'Goal Value  = %s' % goal.get('value')
  print 'Goal Active = %s' % goal.get('active')
  print 'Goal Type   = %s' % goal.get('type')

  print 'Created     = %s' % goal.get('created')
  print 'Updated     = %s' % goal.get('updated')

  parent_link = goal.get('parentLink')
  print 'Parent link href = %s' % parent_link.get('href')
  print 'Parent link type = %s' % parent_link.get('type')

  # Print the goal details depending on the type of goal.
  if goal.get('urlDestinationDetails'):
    self.PrintUrlDestinationGoalDetails(goal.get('urlDestinationDetails'))
  elif goal.get('sessionTimeOnSiteDetails'):
    self.PrintSessionTimeOnSiteGoalDetails(goal.get('sessionTimeOnSiteDetails'))
  elif goal.get('sessionNumPagesDetails'):
    self.PrintSessionNumPagesGoalDetails(goal.get('sessionNumPagesDetails'))
  elif goal.get('eventDetails'):
    self.PrintEventGoalDetails(goal.get('eventDetails'))

Back to Top

Goal properties

When a user creates a goal in Analytics, they choose one of four different types, as explained in Setting Up Goals. They are:

  • URL_DESTINATION
  • VISIT_TIME_ON_SITE
  • VISIT_NUM_PAGES
  • EVENT

The different types of goal have different corresponding data. The following sections show code for printing each of the four kinds of goal.

URL_DESTINATION Goal

A URL destination goal is met when a user reaches a single page or group of pages specified in the goal definition. Each URL Destination goal can be configured with a number of steps that lead up to the goal. The Management API returns all configured steps. The following sample code shows how to iterate through them.

def PrintUrlDestinationGoalDetails(goal_details):
  print 'Goal URL            = %s' % goal_details.get('url')
  print 'Case Sensitive      = %s' % goal_details.get('caseSensitive')
  print 'Match Type          = %s' % goal_details.get('matchType')
  print 'First Step Required = %s' % goal_details.get('firstStepRequired')

  print '------ Url Destination Goal Steps -------'
  if goal_details.get('steps'):
    for goal_step in goal_details.get('steps'):
      print 'Step Number  = %s' % goal_step.get('number')
      print 'Step Name    = %s' % goal_step.get('name')
      print 'Step URL     = %s' % goal_step.get('url')
  else:
    print 'No Steps Configured'

VISIT_TIME_ON_SITE Goals

A Time on Site goal specifies the amount of time a user spends on the user's site; it is met when a user spends that total amount of time on the site during their session.

def PrintSessionTimeOnSiteGoalDetails(goal_details):
  print 'Comparison Type  = %s' % goal_details.get('comparisonType')
  print 'comparison Value = %s' % goal_details.get('comparisonValue')

VISIT_NUM_PAGES Goal

A Pages/Session goal specifies a page-session threshold. It is met when the number of pages a user visits during a session reaches the threshold.

def PrintSessionNumPagesGoalDetails(goal_details):
  print 'Comparison Type  = %s' % goal_details.get('comparisonType')
  print 'comparison Value = %s' % goal_details.get('comparisonValue')

EVENT Goal

Event goals can be configured to match multiple conditions, as explained in Setting Up Goals.

The Management API returns all configurations as a list of conditions. The values set in a condition depend on the Goal type property. VALUE goals use the comparisonType and comparisonValue properties, while CATEGORY, ACTION, and LABEL goals use the matchType and expression properties.

def PrintEventGoalDetails(goal_details):
  print 'Use Event Value  = %s' % goal_details.get('useEventValue')

  for event_condition in goal_details.get('eventConditions'):
    event_type = event_condition.get('type')
    print 'Type               = %s' % event_type

    if event_type in ('CATEGORY', 'ACTION', 'LABEL'):
      print 'Match Type       = %s' % event_condition.get('matchType')
      print 'Expression       = %s' % event_condition.get('expression')
    else:  # VALUE type.
      print 'Comparison Type  = %s' % event_condition.get('comparisonType')
      print 'Comparison Value = %s' % event_condition.get('comparisonValue')

The formats and meanings of all the properties of the four kinds of Goal resource are explained in Goals Collection.

Back to Top

Working with Advanced Segments

An advanced segment is a top level entity in the Management API. It has no parent and no children.

Advanced segments are explained in Advanced Segmentation. Google Analytics provides a default set of advanced segments, but users can also create and save their own custom segments through the Analytics web interface. The list method on Segments provides access to both the default and custom segments available to the authenticated user.

The list method on Segments provides access to both the default and custom segments available to the authenticated user. The sample application requests a list of a user's default and custom segments by calling the Segments list method on the Analytics service object by using the following code.

segments_list = service.management().segments().list().execute()

The results of the list method are in the segments_list object. The following code shows how to iterate through the results. For a list of all the properties of a Segment resource, see Segments Collection.

for segment in segments_list.get('items'):
  print 'Segment ID = %s' % segment.get('id')
  print 'Kind       = %s' % segment.get('kind')
  print 'Self Link  = %s' % segment.get('selfLink')
  print 'Name       = %s' % segment.get('name')
  print 'Definition = %s' % segment.get('definition')
  print 'Created    = %s' % segment.get('created')
  print 'Updated    = %s' % segment.get('updated')

Advanced segments are explained in Advanced Segmentation. In a real application, you can use the value returned by get('id') as the segment parameter to the Core Reporting API Data Feed. All negative ID values are default segments while all positive values are custom segments defined for the authenticated user.

Back to Top




Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.