Getting Data In

Generate PDF from View in REST API

kknopp
Path Finder

I am using Splunk 6.1.1 and currently have a form that takes an integer input (foo) and timerange. The URL for this view after entering the values is https://splunk/app/app_name/view_name?earliest=-30d&latest=now&form.foo=1#. I then generate a PDF from this page. Thing is, I need this form for about 650 instances of foo, and I'd like to run it once a month.

I can't schedule the view since it requires input, and I refuse to create 650 instance of the form without input. My hope is to create a python or ruby script that calls this view with the required input, generates a PDF from the output, and gives me the document metadata so I can store elsewhere. Is this a thing? Looking through the API docs, I see lots for scheduled searches, but this isn't a scheduled search. Any assistance would be much appreciated.

1 Solution

cwue
Engager

The /services/pdfgen/render/ endpoint takes a view [as answered here: https://answers.splunk.com/answers/223655/can-i-export-pdf-via-rest.html], but luckily also a input-dashboard-xml input, which accepts xml-dashboards - as long as all tokens/variables are resolved (!).

To generate a ton of different reports based on the same view/dashboard but different search parameters I wrote a python script.

Using this script all you have to do is
- save the dasboard code as .xml-file
- figure out for which report you want to replace which tokens and have a list of those tokens for every report.
- hand over a JSON List with tokens and their respective values
{"tokenlist":[{'token':'$example$' 'value':'value for individual search'}, {'token':'$example2$' 'value':'searchstring'}]
- run the script which will send the compatible dashboard code to the API and download the resulting pdf report

So my generateReport(tokenlist) function looks like this:
(Disclaimer: this is simplified to get the concept across- I stripped error detection for invalid reports, logging, metadata creation and the like - which is crucial if you plan on automatically mailing those reports)

# import requests

with open('dashboardFile.xml','rb') as XMLfile:
    XMLDashboard =XMLfile.read().replace('\n', '')
    XMLDashboard = XMLDashboard.replace('<', '%26lt%3B')  # otherwise the API will complain

# Replace all tokens in the XMLCode
for t in tokenlist:
    XMLDashboard = XMLDashboard.replace(t['token'], t['value'])

# Send XML code to endpoint, answer should be a pdf file
r = requests.get('https://splunkhost:8089/services/pdfgen/render', auth=(splunkuser, splunkpass), params={'input-dashboard-xml':XMLDashboard,'paper-size':'a4-landscape'})

if r.status_code == 200:
    with open('report_file.pdf', 'wb') as pdffile:
        pdffile.write(r.content)

View solution in original post

Iriseng94
Explorer

HI ,

Understand that this rest api able to generate a pdf report , I am not sure where should i locate the script ? What if i want to schedule the export of pdf like daily monthly or weekly ? Should i do a scheduling of report from splunk and action behind is to run a scripts ?

Any detailed steps for newbie ?

Thanks in advance .

0 Karma

cwue
Engager

The /services/pdfgen/render/ endpoint takes a view [as answered here: https://answers.splunk.com/answers/223655/can-i-export-pdf-via-rest.html], but luckily also a input-dashboard-xml input, which accepts xml-dashboards - as long as all tokens/variables are resolved (!).

To generate a ton of different reports based on the same view/dashboard but different search parameters I wrote a python script.

Using this script all you have to do is
- save the dasboard code as .xml-file
- figure out for which report you want to replace which tokens and have a list of those tokens for every report.
- hand over a JSON List with tokens and their respective values
{"tokenlist":[{'token':'$example$' 'value':'value for individual search'}, {'token':'$example2$' 'value':'searchstring'}]
- run the script which will send the compatible dashboard code to the API and download the resulting pdf report

So my generateReport(tokenlist) function looks like this:
(Disclaimer: this is simplified to get the concept across- I stripped error detection for invalid reports, logging, metadata creation and the like - which is crucial if you plan on automatically mailing those reports)

# import requests

with open('dashboardFile.xml','rb') as XMLfile:
    XMLDashboard =XMLfile.read().replace('\n', '')
    XMLDashboard = XMLDashboard.replace('<', '%26lt%3B')  # otherwise the API will complain

# Replace all tokens in the XMLCode
for t in tokenlist:
    XMLDashboard = XMLDashboard.replace(t['token'], t['value'])

# Send XML code to endpoint, answer should be a pdf file
r = requests.get('https://splunkhost:8089/services/pdfgen/render', auth=(splunkuser, splunkpass), params={'input-dashboard-xml':XMLDashboard,'paper-size':'a4-landscape'})

if r.status_code == 200:
    with open('report_file.pdf', 'wb') as pdffile:
        pdffile.write(r.content)

clamarkv
Explorer

this thread was very helpful in figuring out how to do this, however i did have some problems with the gt (>) and lt(<) operators in my searches. 

to work around this i wrapped them in CDATA tags: 

status<![CDATA[&gt;]]>199 AND status<![CDATA[&lt;]]>300

 

if anyone else is interested, this is my "final" script: 

import requests
import json
import os
from logzero import setup_logger

logger = setup_logger(name="logger", level=20)

splunk_endpoint = os.environ["SPLUNK_ENDPOINT"]
splunk_username = os.environ["SPLUNK_USERNAME"]
splunk_password = os.environ["SPLUNK_PASSWORD"]

with open("dashboard.xml", encoding="utf-8") as xml_file:
    xml_dashboard = xml_file.read()

with open("client_list.json", encoding="utf-8") as json_file:
    client_list = json.loads(json_file.read())

for client in client_list:

    logger.info(f"generating dashboard pdf for {client['name']} [{client['id']}]")

    # replace tokens in dashboard
    this_xml_dashboard = xml_dashboard.replace("--CLIENT--NAME--", client["name"])
    this_xml_dashboard = xml_dashboard.replace("--CLIENT--ID--", client["id"])

    # send xml dashboard to render endpoint
    render_url = f"{splunk_endpoint}/services/pdfgen/render"
    render_response = requests.post(
        render_url,
        auth=(splunk_username, splunk_password),
        params={
            "input-dashboard-xml": this_xml_dashboard.encode(),
            "paper-size": "a4-landscape",
        }
    )

    logger.info(f"render_response: {render_response.status_code}")

    # render endpoint returns a pdf
    if render_response.status_code == 200:
        outfile = (f"./output/dashboard-{client['name'].replace(' ', '_').lower()}.pdf")
        with open(outfile, "wb") as pdffile:
            pdffile.write(render_response.content)
        logger.info(f"wrote {filename} [{render_response.headers['Content-Length']} bytes]")

 

hope this helps.

0 Karma

conikhil
New Member

Does this work for dynamic token like eval, condition, init Because tokens seems to be static replacement and must be passed/replaced before sending to api?

0 Karma

Iriseng94
Explorer

HI ,

Understand that this rest api able to generate a pdf report , I am not sure where should i locate the script ? What if i want to schedule the export of pdf like daily monthly or weekly ? Should i do a scheduling of report from splunk and action behind is to run a scripts ?

Any detailed steps for newbie ?

Thanks in advance .

0 Karma

conikhil
New Member

Does this work for dynamic token like eval, condition, init Because tokens seems to be static replacement and must be passed/replaced before sending to api?

0 Karma

rblack88
New Member

Thanks cwue! In case anyone else gets errors saying that it couldn't find the end of a start tag, adding XMLDashboard=XMLDashboard.replace(' ', '%20') should work!

0 Karma

curtin1061
New Member

Hello,
Does anyone have the full script/xml files needed ... the reference link above is no longer valid.

I'd love to see the python code, I'm not sure where I find the 'dashboardFile.xml' or what this file should look like.

Python and curl examples appreciated.
Craig

0 Karma

cwue
Engager

Hi curtin1061,

it's been a while but I just checked our git and this is the relevant code of my program to download the dashboard as xml.
SplunkUsername, DashboardName, AppName and SessionKey are variables.

import io, requests, json
endpoint = 'https://splunkhost:8089/servicesNS/' + SplunkUsername + '/' + AppName + '/data/ui/views/' + DashboardName
    r = requests.get(endpoint, headers={'Authorization': 'Splunk ' + SessionKey}, params={'output_mode': 'json'}, verify=False)
    dashboardcode = r.json()['entry'][0]['content']['eai:data']

    with io.open('dashboard.xml', 'w', encoding='utf8') as f:
        f.write(dashboardcode)
    print("Saved dashboard.xml")
0 Karma

curtin1061
New Member

Hi cwue,
Thanks for this ... is this your internal git repo? or any chance its public?
I'm a splunk newbie just hacking my way through automating some dashboards. I've done python for a long time (and love it). Any pointers towards python/splunk snipets/code appreciated.
Regards,
Craig

0 Karma

rblack88
New Member

I have not contributed to this repo in several months, but this might help you. https://github.com/BryceKopan/SlackSplunkBot/blob/master/src/RESTSplunkMethods.py

0 Karma

anwarmian
Communicator

This works great. Thanks a lot, cwue. Those who don't have access to "requests" library can use curl command like the following:

import subprocess
file_out = "/home/splunk/pdf_dashboards/yourpdfile.pdf"

subprocess.call(["curl","-G", "-sku", "your_user_name:your_password","-k", Url, "--data-urlencode", "input-dashboard-xml=" + XMLDashboard,"-d","namespace=yourAppName", "-d","paper-size=a4-landscape"], stdout=file_out)

if you are using "--data-urlencode" then you don't have to use the following two lines:
XMLDashboard=XMLfile.read().replace('\n', '')
XMLDashboard = XMLDashboard.replace('<', '%26lt%3B') # otherwise the API will complain

Good Luck and Thanks to cwue once again.

surekhasplunk
Communicator

Hi @anwarmian and @cwue,

By using this approach doesn it resolve the problems with pdf renderinng.
Does it retain the same color codes which are used in the dashbaord
Does it retain the same spacing and panels for page as that of the dashboard ?

0 Karma

anwarmian
Communicator

Were any of you successful in creating a pdf in linux using REST API and emailing to Windows box and check if the pdf show properly? When I created a pdf using the above method in Linux (using python) it looks great in linux but after sending it to Windows via email Windows displays the pdf with blank pages.

0 Karma

JohnRiddoch
Explorer

Thanks both for this help - however, if you want to do it from a shell script, this works:
- save dashboard as "mydash.xml" with appropriate parameters/timeline set
- run this curl command:
- curl -G -sku admin:${mypass} "https://localhost:8089/services/pdfgen/render" --data-urlencode "input-dashboard-xml=$(cat mydash.xml)" -d namespace=search -d paper-size=a4-landscape > mydash.pdf

0 Karma

martin_mueller
SplunkTrust
SplunkTrust

There is a /services/pdfgen/render endpoint, but it doesn't appear to be documented. You might be able to reverse-engineer how to call it from $SPLUNK_HOME/share/splunk/search_mrsparkle/exposed/js/util/pdf_utils.js#downloadReportFromXML(), that's what gets called underneath when you click the Export PDF button.

kknopp
Path Finder

interesting. I'll give it a shot, and let you know what I find. Thank you Martin.

0 Karma
Get Updates on the Splunk Community!

Sending Metrics to Splunk Enterprise With the OpenTelemetry Collector

This blog post is part of an ongoing series on OpenTelemetry. The OpenTelemetry project is the second largest ...

What's New in Splunk Cloud Platform 9.0.2208?!

Howdy!  We are happy to share the newest updates in Splunk Cloud Platform 9.0.2208! Analysts can benefit ...

Want a chance to win $500 to the Splunk shop? Take our IT Incident Management Survey!

  Top Trends & Best Practices in Incident ManagementSplunk is partnering up with Constellation Research to ...