OTT Unified Measurement - Conversions

API updates and articles

#/venv/bin/python3
import http.client, json, csv, re
import sys, subprocess, requests
import pandas as pd
from pandas import json_normalize
import time
 

# Replace placeholder values with your API credentials
client_id = 'YOUR_CLIENT_ID'
client_secret = 'YOUR_CLIENT_SECRET'
grant_type = 'client_credentials'

def get_token():
    conn = http.client.HTTPSConnection("api.ispot.tv")
    payload = "client_id={CLIENT_ID}&client_secret={SECRET}&grant_type={GRANT_TYPE}".format(CLIENT_ID=client_id, SECRET=client_secret, GRANT_TYPE=grant_type)
    headers = {'content-type': "application/x-www-form-urlencoded"}
    conn.request("POST", "/v4/oauth2/token", payload, headers)
    res = conn.getresponse()
    token_raw = res.read()
    data_parsed = json.loads(token_raw.decode("utf-8"))
    access_token = data_parsed['access_token']
    conn.close()
    return (access_token)

print('Authenticating...')
access_token = str(get_token())

conn = http.client.HTTPSConnection("api.ispot.tv")
payload = ""
headers = {'Authorization': "Bearer {TOKEN}".format(TOKEN=access_token),
}

### Filters and stuff ### start_date = '2021-03-14'
end_date = '2021-04-20'
page_size = '10000'
attribution_window = '14d'
site_id = 'TC-####-#'
brand_id = '#####'

## choose_id is the filter to loop through, it should be the lesser number of values compared to group_by
choose_id = 'publishers' # placements, creatives, campaigns, publishers
group_by = 'PL'              # P (Publisher), PL (Placement ID), CR (Creative ID), C (Campaign), SO (Source)

filter1 = 'page[number]=1&page[size]={PAGE_SIZE}&filter[start_date]={START_DATE}&filter[end_date]={END_DATE}&filter[brand]={BRAND}'.format(PAGE_SIZE=page_size, START_DATE=start_date, END_DATE=end_date, BRAND=brand_id)

if choose_id == 'placements':
    disp_name = 'placement'
    filter2 = '{FILTER}&filter[conversion_site_id]={SITE_ID}&filter[attribution_window]={WINDOW}&filter[group_by]={GROUP_BY}&filter[client_placement_id]='.format(FILTER=filter1, SITE_ID=site_id, WINDOW=attribution_window, GROUP_BY=group_by)
    api_request = 'https://api.ispot.tv/v4/client/ott/{ID}?{FILTERS}'.format(ID=choose_id, FILTERS=filter1)
elif choose_id == 'creatives':
    disp_name = 'creative'
    filter2 = '{FILTER}&filter[conversion_site_id]={SITE_ID}&filter[attribution_window]={WINDOW}&filter[group_by]={GROUP_BY}&filter[client_creative_id]='.format(FILTER=filter1, SITE_ID=site_id, WINDOW=attribution_window, GROUP_BY=group_by)
    api_request = 'https://api.ispot.tv/v4/client/ott/{ID}?{FILTERS}'.format(ID=choose_id, FILTERS=filter1)
elif choose_id == 'publishers':
    disp_name = 'publisher'
    filter2 = '{FILTER}&filter[conversion_site_id]={SITE_ID}&filter[attribution_window]={WINDOW}&filter[group_by]={GROUP_BY}&filter[publisher_id]='.format(FILTER=filter1, SITE_ID=site_id, WINDOW=attribution_window, GROUP_BY=group_by)
    api_request = 'https://api.ispot.tv/v4/publishers/extended?{FILTERS}'.format(FILTERS=filter1)
else:
    pass

print('\r\nCollecting {TYPE} IDs...'.format(TYPE=disp_name))
conn.request("GET", api_request, payload, headers, )
res = conn.getresponse()
request_id = res.headers.get('X-Request-ID')
request_datetime = res.headers.get('Date')
print('\r\nRequest ID: {REQUEST_ID}\r\nDatetime: {REQUEST_DATETIME}\r\nStatus: {STATUS}'.format(REQUEST_ID=request_id,REQUEST_DATETIME=request_datetime,STATUS=res.status))
final = res.read()
jsonResponse = json.loads(final.decode('utf-8'))
response_data = jsonResponse.get('data')
loop_ids = ','.join(['{ID}'.format(ID=response_data[i]['id']) for i in range(len(response_data)) if response_data[i]['id']])
loop_ids = loop_ids.split(',')
display_ids = ','.join(['{ID}'.format(ID=response_data[i]['name']) for i in range(len(response_data)) if response_data[i]['name']])
display_ids = display_ids.split(',')

print('\r\nCollecting Conversion Types...')
conn.request("GET", "/v4/metrics/conversions/{SITE_ID}/types?filter[start_date]={START}&filter[end_date]={END}".format(SITE_ID=site_id, START=start_date, END=end_date), payload, headers, )
res = conn.getresponse()
final = res.read()
jsonResponse = json.loads(final.decode('utf-8'))

try:
    jsontypes = jsonResponse.get('data')
    items = len(jsontypes)
    p = 0
    for i in range(items):
        app = jsontypes[i]['application_type']
        ctype = jsontypes[i]['name']

        for lid, did in zip(loop_ids, display_ids):
            time.sleep(3)
            conv_api_request = "https://api.ispot.tv/v4/metrics/conversions/{SITE_ID}/ott?{FILTERS}{LOOP_ID}&filter[conversion_application]={APP}&filter[conversion_type]={TYPE}&metrics[include_audience]=0&filter[airing_type]=N,R&filter[national_only]=1&sort=-impressions_ott".format(SITE_ID=site_id, FILTERS=filter2, LOOP_ID=lid, APP=app, TYPE=ctype)
            # print(conv_api_request)
            conn.request("GET", conv_api_request, payload, headers, )
            res = conn.getresponse()
            final = res.read()
            jsonResponse = json.loads(final.decode('utf-8'))
            print('Status: {STATUS} Running for {DISP} {ID} & Conversion Type: {APP} {TYPE}'.format(STATUS=res.status, DISP=disp_name, ID=did, APP=app, TYPE=ctype))

            jsonResponse = jsonResponse['data']
            json_norm = json_normalize(jsonResponse, sep='_')
            json_norm.insert(0,'ispot_{ID}_id'.format(ID=disp_name),lid)
            json_norm.insert(1,'client_{ID}_id'.format(ID=disp_name),did)
            json_norm.insert(2,'app_type',app)
            json_norm.insert(3,'conversion_type',ctype)
            json_norm.insert(4,'attribution_window',attribution_window)
            json_norm.insert(5,'start_date',start_date)
            json_norm.insert(6,'end_date',end_date)
            if p == 0:
                json_norm.to_csv('ott_output_{ID}.csv'.format(ID=choose_id), mode='w', sep=',', header=True, index=False)
                p += 1
            else:
                json_norm.to_csv('ott_output_{ID}.csv'.format(ID=choose_id), mode='a', sep=',', header=False, index=False)

    print('\r\n Finished! \r\n')

except Exception as err:
    print(err)