Get statistics for agency clients
Python version 2 or 3 using JSON with the Requests library
This example shows how to use the AgencyClients.get method to get a list of agency clients and then execute requests to the Reports service to get statistics for advertiser accounts for the past day. The mode for generating the report is selected automatically. If the report is added to the queue in offline mode, repeated requests are made.
To use the example, specify the OAuth access token that you received for the agency representative in the input data.
# -*- coding: utf-8 -*-
import requests
from requests.exceptions import ConnectionError
from time import sleep
import json
from datetime import date, timedelta
from time import time
# Method for correctly parsing UTF-8 encoded strings for both Python 3 and Python 2
import sys
if sys.version_info < (3,):
def u(x):
try:
return x.encode("utf8")
except UnicodeDecodeError:
return x
else:
def u(x):
if isinstance(x, bytes):
return x.decode('utf8')
else:
return x
# --- Input data ---
# Address of the AgencyClients service for sending JSON requests (case-sensitive)
AgencyClientsURL = 'https://api.direct.yandex.com/json/v5/agencyclients'
# Address of the Reports service for sending JSON requests (case-sensitive)
ReportsURL = 'https://api.direct.yandex.com/json/v5/reports'
# OAuth token of the agency representative that requests will be made on behalf of
token = 'TOKEN'
# --- Preparing the request to the AgencyClients service ---
# Creating HTTP request headers
headers = {
# OAuth token. The word Bearer must be used
"Authorization": "Bearer " + token,
# Language for response messages
"Accept-Language": "ru"
}
AgencyClientsBody = {
"method": "get",
"params": {
"SelectionCriteria": {
"Archived": "NO" # Only get active clients
},
"FieldNames": ["Login"],
"Page": {
"Limit": 10000, # Get a maximum of 10000 clients in the server response
"Offset": 0
}
}
}
# --- Executing requests to the AgencyClients service ---
# If the LimitedBy parameter is not in the response, it means
# that all clients were received
HasAllClientLoginsReceived = False
ClientList = []
while not HasAllClientLoginsReceived:
ClientsResult = requests.post(AgencyClientsURL, json.dumps(AgencyClientsBody), headers=headers).json()
for Client in ClientsResult['result']['Clients']:
ClientList.append(Client["Login"])
if ClientsResult['result'].get("LimitedBy", False):
AgencyClientsBody['Page']['Offset'] = ClientsResult['result']["LimitedBy"]
else:
HasAllClientLoginsReceived = True
# --- Preparing the request to the Reports service ---
# Creating the request message body
# The report contains statistics on clicks, impressions, and expenditures for all the client's campaigns
body = {
"params": {
"SelectionCriteria": {},
"FieldNames": [
"Impressions",
"Clicks",
"Cost"
],
"ReportName": u("ACCOUNT_PERFORMANCE"),
"ReportType": "ACCOUNT_PERFORMANCE_REPORT",
"DateRangeType": "AUTO",
"Format": "TSV",
"IncludeVAT": "NO",
"IncludeDiscount": "NO"
}
}
# Creating output data
resultcsv = "Login;Impressions;Clicks;Costs\n"
# Additional HTTP headers for requesting reports
headers['skipReportHeader'] = "true"
headers['skipColumnHeader'] = "true"
headers['skipReportSummary'] = "true"
headers['returnMoneyInMicros'] = "false"
# --- Executing requests to the Reports service ---
for Client in ClientList:
# Adding the "Client-Login" HTTP header
headers['Client-Login'] = Client
# Encoding the request message body as JSON
requestBody = json.dumps(body, indent=4)
# Starting the request execution loop
# If HTTP response code 200 is returned, the report data is added to the output data
# If HTTP response code 201 or 202 is returned, repeated requests are made
while True:
try:
req = requests.post(ReportsURL, requestBody, headers=headers)
req.encoding = 'utf-8' # Mandatory response processing in UTF-8
if req.status_code == 400:
print("Invalid request parameters, or the request queue is full")
print("RequestId: {}".format(req.headers.get("RequestId", False)))
print("JSON code for the request: {}".format(u(body)))
print("JSON code for the server response: \n{}".format(u(req.json())))
break
elif req.status_code == 200:
print("Report for account {} created successfully".format(str(Client)))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
if req.text != "":
tempresult = req.text.split('\t')
resultcsv += "{};{};{};{}\n".format(Client, tempresult[0], tempresult[1], str(tempresult[2]).replace('.', ','))
else:
resultcsv += "{};0;0;0\n".format(Client)
break
elif req.status_code == 201:
print("Report for account {} added to the queue in offline mode".format(str(Client)))
retryIn = int(req.headers.get("retryIn", 60))
print("Resend the request in {} seconds".format(retryIn))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
sleep(retryIn)
elif req.status_code == 202:
print("Report will be generated in offline mode".format(str(Client)))
retryIn = int(req.headers.get("retryIn", 60))
print("Repeat the request in {} seconds".format(retryIn))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
sleep(retryIn)
elif req.status_code == 500:
print("Error generating the report. Please repeat the request again later.")
print("RequestId: {}".format(req.headers.get("RequestId", False)))
print "JSON code for the server response: \n{}".format(u(req.json())))
break
elif req.status_code == 502:
print("Exceeded the server limit on report creation time.")
print(
"Please try changing the request parameters: reduce the time period and the amount of data requested.")
print("JSON code for the request: {}".format(body))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
print("JSON code for the server response: \n{}".format(u(req.json())))
break
else:
print("Unexpected error")
print("RequestId: {}".format(req.headers.get("RequestId", False)))
print("JSON code for the request: {}".format(body))
print("JSON code for the server response: \n{}".format(u(req.json())))
break
# Error handling if the connection with the Yandex Direct API server could not be established
except ConnectionError:
# In this case, we recommend repeating the request again later
print("Error connecting to the Yandex Direct API server")
# Forced exit from loop
break
# If any other error occurred
except:
# In this case, we recommend analyzing the application's actions
print("Unexpected error")
# Forced exit from loop
break
print("Finished creating reports for accounts")
# Creating and saving the file
filename = "AccountsPerfomanceReport_{}.csv".format (str(time()))
resultfile = open(filename, 'w+')
resultfile. write(resultcsv)
resultfile.close()
print("Results are saved in the file {}".format(filename))