gaapi4py
Google Analytics Reporting API v4 for Python 3
Prerequisites
To use this library, you need to have a project in Google Cloud Platform and a service account key that has access to Google Analytics account you want to get data from.
Quick Start
from gaapi4py import GAClient
# if GOOGLE_APPLICATION_CREDENTIALS is set:
c = GAClient()
# or you may specify keyfile path:
c = GAClient(json_keyfile="path/to/keyfile.json")
request_body = {
'view_id': '123456789',
'start_date': '2019-01-01',
'end_date': '2019-01-31',
'dimensions': {
'ga:sourceMedium',
'ga:date'
},
'metrics': {
'ga:sessions'
},
'filter': 'ga:sourceMedium==google / organic' # optional filter clause
}
response = c.get_all_data(request_body)
response['info'] # sampling and "golden" metadata
response['data'] # Pandas dataframe that contains data from GA
If you want to make many requests to a speficic view or with specific dateranges, you can set date ranges for all future requests:
# Pass arguments to class init
c = GAClient(view_id="123456789", start_date="2019-09-01", end_date="2019-09-07")
# or use methods to overwrite viewID or dateranges
c.set_view_id('123456789')
c.set_dateranges('2019-01-01', '2019-01-31')
request_body_1 = {
'dimensions': {
'ga:sourceMedium',
'ga:date'
},
'metrics': {
'ga:sessions'
}
}
request_body_2 = {
'dimensions': {
'ga:deviceCategory',
'ga:date'
},
'metrics': {
'ga:sessions'
}
}
response_1 = c.get_all_data(request_body_1)
response_2 = c.get_all_data(request_body_2)
Avoid sampling by taking data day-by-day
Important! Google Analytics reporting API has a limit of maximum 100 requests per 100 seconds. If you want to iterate over large period of days, you might consider adding
time.sleep(1)at the end of the loop to avoid reaching this limit.
from datetime import date, timedelta
from time import sleep
import pandas as pd
from gaapi4py import GAClient
c = GAClient(view_id='123456789')
start_date = date(2019,7,1)
end_date = date(2019,7,14)
df_list = []
iter_date = start_date
while iter_date <= end_date:
c.set_dateranges(iter_date, iter_date)
response = c.get_all_data({
'dimensions': {
'ga:sourceMedium',
'ga:deviceCategory'
},
'metrics': {
'ga:sessions'
}
})
df = response['data']
df['date'] = iter_date
df_list.append(response['data'])
iter_date = iter_date + timedelta(days=1)
time.sleep(1)
all_data = pd.concat(df_list, ignore_index=True)
Avoid "maximum 7 dimensions" restriction
If you store sessionId and/or hitId as custom dimensions (Example implementation on Simo Ahava's blog), you can circumvent restriction on maximum number of dimensions and metrics in one report. Example below:
If sampling starts to appear, try to break the set of dimensions into smaller parts and run queries on them.
one_day = date(2019,7,1)
c.set_dateranges(one_day, one_day)
SESSION_ID_CD_INDEX = '2'
HIT_ID_CD_INDEX = '5'
session_id = 'dimension' + SESSION_ID_CD_INDEX
hit_id = 'dimension' + HIT_ID_CD_INDEX
#Get session scope data
response_1 = c.get_all_data({
'dimensions': {
'ga:' + session_id,
'ga:sourceMedium',
'ga:campaign',
'ga:keyword',
'ga:adContent',
'ga:userType',
'ga:deviceCategory'
},
'metrics': {
'ga:sessions'
}
})
response2 = c.get_all_data({
'dimensions': {
'ga:' + session_id,
'ga:landingPagePath',
'ga:secondPagePath',
'ga:exitPagePath',
'ga:pageDepth',
'ga:daysSinceLastSession',
'ga:sessionCount'
},
'metrics': {
'ga:hits',
'ga:totalEvents',
'ga:bounces',
'ga:sessionDuration'
}
})
all_data = response_1['data'].merge(response2['data'], on=session_id, how='left')
all_data.rename(index=str, columns={
session_id: 'session_id'
}, inplace=True)
all_data.head()
# Get hit scope data
hits_response_1 = c.get_all_data({
'dimensions': {
'ga:' + session_id,
'ga:' + hit_id,
'ga:pagePath',
'ga:previousPagePath',
'ga:dateHourMinute'
},
'metrics': {
'ga:hits',
'ga:totalEvents',
'ga:pageviews'
}
})
hits_response_2 = c.get_all_data({
'dimensions': {
'ga:' + session_id,
'ga:' + hit_id,
'ga:eventCategory',
'ga:eventAction',
'ga:eventLabel'
},
'metrics': {
'ga:totalEvents'
}
})
all_hits_data = hits_response_1['data'].merge(hits_response_2['data'],
on=[session_id, hit_id],
how='left')
all_hits_data.rename(index=str, columns={
session_id: 'session_id',
hit_id: 'hit_id'
}, inplace=True)
all_hits_data.head()
Metadata
Release files for gaapi4py 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| gaapi4py-1.2.0.tar.gz | 5.4 kB | Without provenance | Details for gaapi4py-1.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| gaapi4py-1.2.0-py3-none-any.whl | Python 3 | none | any | Details for gaapi4py-1.2.0-py3-none-any.whl |
Total release size: 11.7 kB
Release files / gaapi4py-1.2.0.tar.gz
| Download URL | gaapi4py-1.2.0.tar.gz |
|---|---|
| Size | 5.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8b6b28584fed1f14a8de5fe24d2444a9d70bea19b4ab781dfbe1b31afbaf047c
|
|
BLAKE2b-256 checksum How to use checksums |
c978eb5bd058aa3f2b03f5dd068efaf504e29217e7772a7b7f0beae35b7dac57
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.14.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.35.0 CPython/3.7.4
|
Release files / gaapi4py-1.2.0-py3-none-any.whl
| Download URL | gaapi4py-1.2.0-py3-none-any.whl |
|---|---|
| Size | 6.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ac5beacc396267462fbc1f264ff04a82db635cdf93552f9570afbfe3d8b0a578
|
|
BLAKE2b-256 checksum How to use checksums |
aa9b7e550f4b38562df683ad3471b0bb0aa269da7be74603215e73c6d95e0b08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.14.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.35.0 CPython/3.7.4
|
Security for gaapi4py 1.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.