Une fois que vous avez identifié ou créé un rapport qui répond à vos besoins, vous pouvez générer les résultats. Les résultats du rapport sont stockés dans des fichiers de rapport, qui peuvent être récupérés et manipulés à l'aide d'un programme. Un fichier est généré lors de l'exécution d'un rapport.
Ce guide explique comment générer par programmation des fichiers de rapport via le service Reports.
Rechercher un rapport
Pour générer un rapport, vous devez connaître son ID. Si vous venez de créer ou de mettre à jour un rapport, cette valeur se trouve dans le champ id
de la ressource de rapport renvoyée. Il est recommandé aux utilisateurs de stocker ces ID renvoyés pour une recherche ultérieure.
Si vous ne connaissez pas l'ID du rapport que vous souhaitez générer, vous pouvez parcourir la liste de tous les rapports disponibles. L'exemple ci-dessous montre comment rechercher un rapport en fonction de critères définis par l'utilisateur:
C#
Report target = null;
ReportList reports;
String nextPageToken = null;
do {
// Create and execute the reports list request.
ReportsResource.ListRequest request = service.Reports.List(profileId);
request.PageToken = nextPageToken;
reports = request.Execute();
foreach (Report report in reports.Items) {
if (IsTargetReport(report)) {
target = report;
break;
}
}
// Update the next page token.
nextPageToken = reports.NextPageToken;
} while (target == null
&& reports.Items.Any()
&& !String.IsNullOrEmpty(nextPageToken));
Java
Report target = null;
ReportList reports;
String nextPageToken = null;
do {
// Create and execute the reports list request.
reports = reporting.reports().list(profileId).setPageToken(nextPageToken).execute();
for (Report report : reports.getItems()) {
if (isTargetReport(report)) {
target = report;
break;
}
}
// Update the next page token.
nextPageToken = reports.getNextPageToken();
} while (target == null
&& !reports.getItems().isEmpty()
&& !Strings.isNullOrEmpty(nextPageToken));
PHP
$target = null;
$response = null;
$pageToken = null;
do {
// Create and execute the report list request.
$response = $this->service->reports->listReports(
$userProfileId,
['pageToken' => $pageToken]
);
foreach ($response->getItems() as $report) {
if ($this->isTargetReport($report)) {
$target = $report;
break;
}
}
$pageToken = $response->getNextPageToken();
} while (empty($target) && !empty($response->getItems()) && !empty($pageToken));
Python
target = None
# Construct the request.
request = service.reports().list(profileId=profile_id)
while True:
response = request.execute()
for report in response['items']:
if is_target_report(report):
target = report
break
if not target and response['items'] and response['nextPageToken']:
request = service.reports().list_next(request, response)
else:
break
Ruby
page_token = nil
target = nil
loop do
result = service.list_reports(profile_id, page_token: page_token)
result.items.each do |report|
if target_report?(report)
target = report
break
end
end
page_token = (result.next_page_token if target.nil? && result.items.any?)
break if page_token.to_s.empty?
end
Consultez la documentation de référence pour connaître les paramètres facultatifs que vous pouvez spécifier pour contrôler le mode de tri et de tri de la liste des rapports renvoyés. Il est particulièrement utile de contrôler le tri et le classement de cette liste pour trouver les rapports modifiés récemment.
Générer un rapport
Une fois que vous avez trouvé un rapport approprié, vous pouvez le générer et en générer un nouveau à l'aide du service Rapport. Les rapports peuvent être générés de manière synchrone ou asynchrone (par défaut), en fonction de leur complexité et du temps nécessaire au traitement. Pour en savoir plus sur les rapports synchrones et asynchrones, consultez le guide sur les rapports synchrones.
Pour générer un rapport, vous appelez la méthode run du service Report, comme dans l'exemple ci-dessous:
C#
// Run the report.
File file = service.Reports.Run(profileId, reportId).Execute();
Java
// Run the report.
File file = reporting.reports().run(profileId, reportId).execute();
PHP
// Run the report.
$file = $this->service->reports->run($userProfileId, $reportId);
Python
# Run the report.
report_file = service.reports().run(
profileId=profile_id, reportId=report_id).execute()
Ruby
# Run the report.
report_file = service.run_report(profile_id, report_id)
La réponse à cette requête est une ressource Files. S'il s'agit d'une requête d'exécution synchrone réussie, tous les champs de la ressource renvoyée sont renseignés, et le fichier est prêt à être téléchargé. Cependant, comme il s'agit d'une requête d'exécution asynchrone, certains champs clés seront manquants et le fichier status
sera défini sur PROCESSING
, car le rapport n'est pas encore terminé.
Quand un rapport est-il terminé ?
Lorsque vous exécutez un rapport de manière asynchrone, un fichier d'espace réservé est généré immédiatement, et le rapport est placé dans une file d'attente pour être traité. L'espace réservé contient deux informations clés qui vous aideront à déterminer quand le rapport est terminé:
- Un champ
id
, qui peut être utilisé pour référencer ce fichier dans les requêtes ultérieures - Un champ
status
, qui représente l'état actuel de l'exécution du rapport.
Pour déterminer la fin d'un rapport, vous devez consulter régulièrement l'élément status
du fichier, comme dans l'exemple ci-dessous:
C#
// Wait for the report file to finish processing.
// An exponential backoff policy is used to limit retries and conserve quota.
int sleep = 0;
int startTime = GetCurrentTimeInSeconds();
do {
File file = service.Files.Get(reportId, fileId).Execute();
if ("REPORT_AVAILABLE".Equals(file.Status)) {
Console.WriteLine("File status is {0}, ready to download.", file.Status);
return;
} else if (!"PROCESSING".Equals(file.Status)) {
Console.WriteLine("File status is {0}, processing failed.", file.Status);
return;
} else if (GetCurrentTimeInSeconds() - startTime > MAX_RETRY_ELAPSED_TIME) {
Console.WriteLine("File processing deadline exceeded.");
return;
}
sleep = GetNextSleepInterval(sleep);
Console.WriteLine("File status is {0}, sleeping for {1} seconds.", file.Status, sleep);
Thread.Sleep(sleep * 1000);
} while (true);
Java
BackOff backOff =
new ExponentialBackOff.Builder()
.setInitialIntervalMillis(10 * 1000) // 10 second initial retry
.setMaxIntervalMillis(10 * 60 * 1000) // 10 minute maximum retry
.setMaxElapsedTimeMillis(60 * 60 * 1000) // 1 hour total retry
.build();
do {
File file = reporting.files().get(reportId, fileId).execute();
if ("REPORT_AVAILABLE".equals(file.getStatus())) {
// File has finished processing.
System.out.printf("File status is %s, ready to download.%n", file.getStatus());
return file;
} else if (!"PROCESSING".equals(file.getStatus())) {
// File failed to process.
System.out.printf("File status is %s, processing failed.", file.getStatus());
return null;
}
// The file hasn't finished processing yet, wait before checking again.
long retryInterval = backOff.nextBackOffMillis();
if (retryInterval == BackOff.STOP) {
System.out.println("File processing deadline exceeded.%n");
return null;
}
System.out.printf("File status is %s, sleeping for %dms.%n", file.getStatus(), retryInterval);
Thread.sleep(retryInterval);
} while (true);
PHP
// Wait for the report file to finish processing.
// An exponential backoff policy is used to limit retries and conserve
// quota.
$sleep = 0;
$startTime = time();
do {
$file = $this->service->files->get($reportId, $fileId);
if ($file->getStatus() === 'REPORT_AVAILABLE') {
printf('File status is %s, ready to download<br>', $file->getStatus());
return $file;
} elseif ($file->getStatus() !== 'PROCESSING') {
printf('File status is %s, processing failed<br>', $file->getStatus());
return null;
} elseif (time() - $startTime > self::MAX_RETRY_ELAPSED_TIME) {
printf('File processing deadline exceeded<br>');
return null;
}
$sleep = $this->getNextSleepInterval($sleep);
printf(
'File status is %s, sleeping for %d seconds<br>',
$file->getStatus(),
$sleep
);
$this->sleep($sleep);
} while (true);
Python
# Wait for the report file to finish processing.
# An exponential backoff strategy is used to conserve request quota.
sleep = 0
start_time = time.time()
while True:
report_file = service.files().get(
reportId=report_id, fileId=file_id).execute()
status = report_file['status']
if status == 'REPORT_AVAILABLE':
print 'File status is %s, ready to download.' % status
return
elif status != 'PROCESSING':
print 'File status is %s, processing failed.' % status
return
elif time.time() - start_time > MAX_RETRY_ELAPSED_TIME:
print 'File processing deadline exceeded.'
return
sleep = next_sleep_interval(sleep)
print 'File status is %s, sleeping for %d seconds.' % (status, sleep)
time.sleep(sleep)
Ruby
# Wait for the report file to finish processing.
# An exponential backoff strategy is used to conserve request quota.
interval = 0
start_time = Time.now
loop do
report_file = service.get_file(report_id, file_id)
status = report_file.status
if status == 'REPORT_AVAILABLE'
puts format('File status is %s, ready to download.', status)
break
elsif status != 'PROCESSING'
puts format('File status is %s, processing failed.', status)
break
elsif Time.now - start_time > MAX_RETRY_ELAPSED_TIME
puts 'File processing deadline exceeded.'
break
end
interval = next_sleep_interval(interval)
puts format('File status is %s, sleeping for %d seconds.', status,
interval)
sleep(interval)
end
Lorsque status
passe à REPORT_AVAILABLE
, le fichier est prêt à être téléchargé. Comme indiqué dans l'exemple ci-dessus, il est vivement recommandé d'appliquer une stratégie d'intervalle exponentiel entre les tentatives lors de cette opération pour optimiser l'utilisation des quotas de requêtes.