Export PDF

You can use the API to automate the process of exporting report PDFs.

Endpoints used

Supported method:

  • GET: returns a report’s historic runs

Supported methods:

  • GET: returns information about the status of PDF generation
  • POST: starts PDF generation

Supported method:

  • GET: downloads a PDF

How this example works

In this example, the get_report_latest_run_status helper function returns the status of the most recent run and its run token. In the get_report_pdf method, we check the latest run status from the result of said helper function. If the run succeeded, we make a POST request to modeanalytics.com/api/{organization}/reports/{report_token}/exports/runs/{run_token}/pdf to start generating a PDF. We set the generation timeout to be 5 minutes. Once PDF generation starts, the state of the generation changes to enqueued. Once the generation completes, the state is completed. Once the state becomes completed, we make a GET request to modeanalytics.com/api/{organization}/reports/{report_token}/exports/runs/{run_token}/pdf/download to start downloading the PDF. The downloaded PDF will be in the same directory as the .py file.

To try it yourself

  • Download the example code to a .py file
  • Input your API token, API secret, organization name, and other custom information as needed. An API token and secret can be generated here
  • Save the .py file in your desired directory
  • Open the terminal and navigate to that directory
  • Run the command python3 {file_name}.py
  • All of our Python recipes require Python 3
import json
import requests
import cgi, cgitb
import time

from requests.auth import HTTPBasicAuth

host = 'https://modeanalytics.com'
org = 'org_name'
un = 'api_token'
pw = 'api_secret'

def get_report_pdf(report_token):
  latest_report_run = get_report_latest_run_status(report_token)
  status = latest_report_run['status']
  most_recent_report_run_token = latest_report_run['most_recent_report_run_token']

  if status == "succeeded":
    status = ""
    timeout = time.time() + 60*5
    while(status == "" or status == "enqueued"):
      url = '%s/api/%s/reports/%s/exports/runs/%s/pdf' % (host, org, report_token, most_recent_report_run_token)
      payload = {'trk_source':'report'}
      headers = {'Content-Type': 'application/json'}
      r = requests.post(url, json=payload, headers=headers, auth=HTTPBasicAuth(un, pw))
      result = r.json()
      status = result['state']
      if time.time() > timeout:
    if status == "enqueued":
      print ('Download faild :( Please try again.')
    elif status == "completed":
	  url = '%s/api/%s/reports/%s/exports/runs/%s/pdf/download' % (host, org, report_token, most_recent_report_run_token)
	  r = requests.get(url, stream=True, auth=HTTPBasicAuth(un, pw))

	  params = cgi.parse_header(r.headers['Content-Disposition'])[1]
	  file_name = params['filename']

  if r.status_code == 200:
    with open(file_name, 'wb') as f:
      for chunk in r.iter_content(1024):

	return r
    print ('Report\'s latest run failed. Please fix the queries errors before exporting again.')


def get_report_latest_run_status(report_token):
  url = '%s/api/%s/reports/%s/runs' % (host, org, report_token)
  r = requests.get(url, auth=HTTPBasicAuth(un, pw))
  result = r.json()
  most_recent_report_run_token = result['_embedded']['report_runs'][0]['token']
  status = result['_embedded']['report_runs'][0]['state']

  return {'status':status, 'most_recent_report_run_token' : most_recent_report_run_token}

const request = require('request');
const fs = require('fs');

const host = 'https://modeanalytics.com';
const org = 'orgName';
const username = 'apiToken';
const password = 'apiSecret';

const getReportPDF = reportToken => request({
  url: `${host}/api/${org}/reports/${reportToken}/runs`,
  json: true,
  auth: { username, password },
}, (err, res, body) => {
  let {
    token: mostRecentReportRunToken,
  } = body._embedded.report_runs[0];

  if (state === "succeeded") {
    state = "";
    setTimeout(() => {
      const timeout = Date.now() + 60*5; // close the call after 5 min
      setInterval(() => {
        if (state === "" || state === "enqueued") {
            url: `${host}/api/${org}/reports/${reportToken}/exports/runs/${mostRecentReportRunToken}/pdf`,
            method: 'POST',
            auth: { username, password },
            json: true,
            body: { trk_source: 'report' },
          }, (err, res, body) => {
            const fileName = body.filename;
            state = body.state;
            if (state === "enqueued") {
              console.log('Download faild :( Please try again.');
            } else if (state === "completed") {
                url: `${host}/api/${org}/reports/${reportToken}/exports/runs/${mostRecentReportRunToken}/pdf/download`,
                auth: { username, password },
                encoding: null,
              .on('error', err => console.error('Report\'s latest run failed. Please fix the queries errors before exporting again.'))
          if (Date.now() >= timeout) return;
      }, 1000);
    }, 5000);