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 offline queue, the repeat requests are executed.
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 properly parsing the UTF-8 encoded strings both in 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'
# Reports service address used to send JSON requests (case-sensitive)
ReportsURL = 'https://api.direct.yandex.com/json/v5/reports'
# OAuth token of the agency representative who is sending the requests.
token = 'TOKEN'
# --- Preparing the request to the AgencyClients service ---
# Creating HTTP headers for the request
headers = {
# OAuth token. The word “Bearer” is mandatory
"Authorization": "Bearer " + token,
# Language of responses
"Accept-Language": "ru"
}
AgencyClientsBody = {
"method": "get",
"params": {
"SelectionCriteria": {
"Archived": "NO" # Only get active clients
},
"FieldNames": ["Login"],
"Page": {
"Limit": 10000, # Get no more than 10,000 clients in the server response
"Offset": 0
}
}
}
# --- Executing requests to the AgencyClients service ---
# If the response doesn't contain a LimitedBy parameter, it indicates
# that all clients were retrieved
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 body
The report contains statistics on impressions, clicks, and expenses 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"
}
}
# Generating 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"
# --- Sending 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 an HTTP code of 200 is returned, the report contents is added to the output data
# If HTTP code 201 or 202 is returned, send repeat requests
while True:
try:
req = requests.post(ReportsURL, requestBody, headers=headers)
req.encoding = 'utf-8' # Force the response to be interpreted as UTF-8
if req.status_code == 400:
print("Invalid request parameters, or the report 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".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 offline queue".format(str(Client)))
retryIn = int(req.headers.get("retryIn", 60))
print("Request will be resent in {} seconds".format(retryIn))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
sleep(retryIn)
elif req.status_code == 202:
print("Generating the report in offline mode".format(str(Client)))
retryIn = int(req.headers.get("retryIn", 60))
print("Request will be resent in {} seconds".format(retryIn))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
sleep(retryIn)
elif req.status_code == 500:
print("Error occurred when 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 generation 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
# Handling errors when unable to connect to the Yandex Direct API server
except ConnectionError:
# In this case, we recommend repeating the request later
print("Error connecting to the API server")
# Forced exit from the loop
break
# If any other error occurred
except:
# In this case, we recommend analyzing the application's actions
print("Unexpected error.")
# Forced exit from the loop
break
print("Reports for all accounts have been created")
# Creating and writing the file
filename = "AccountsPerfomanceReport_{}.csv".format(str(time()))
resultfile = open(filename, 'w+')
resultfile.write(resultcsv)
resultfile.close()
print("Results are saved to file {}".format(filename))