Skip to main content

Embedding PyDynamicReporting into applications

| 08.08.2023

Ansys Dynamic Reporting or ADR (formerly known as Nexus) is an Ansys technology designed to provide interactive and dynamic reports that can be embedded in any application. The pydynamicreporting library (part of the pyansys project) has been designed to allow for easy access and control over the application. This quick guide provides a set of steps to easily embed ADR into your application, allowing you to quickly add a powerful and modern looking report capability to your application.

Note: ADR does not require any license.

Note2: pydynamicreporting is an officially released pyansys package. To install it, simply type:

pip install ansys-dynamicreporting-core

 

A few words on ADR

Before describing how to embed ADR into your application, a few words on how it works. The application allows the user to push data for the report into a database. The data can be of any format, but natively ADR supports images (png or tiff), animations (mp4 files), 3D scenes (avz, stl, ply, scdoc, csf), tables, strings or trees (in from of python dictionaries). Each item can be associated with one or more tags to make the organization inside the database cleaner. The user can then define one (or more) report templates to apply against the items in the database. This will result in a report that can be embedded via iframe or a url into any application. Please note that these templates allow also for some (limited) post-post-processing of the data. For example, tables from multiple simulations can be combined and filtered, reduction operations can be performed and so on.

Detailed information about ADR can be found here.

 

How to embed ADR

The first step is to start the ADR service. This can be done with the following lines:

import ansys.dynamicreporting.core as adr 

# Set the path to your local Ansys installation. If there is no Ansys installation, set this to ‘docker’ and an ADR docker image will automatically be installed on your machine 
ansys_loc = r"C:\Program Files\ANSYS Inc\v232" 

# You need to set the path to folder where to store the ADR database. 
db_dir = r"C:\tmp\new_database" 

# Set the port for the ADR service. You can either hard-code it, or use the following method to automatically detect an open port 
adr_port = adr.utils.report_utils.find_unused_ports(count=1, start=8000)[0] 

# Create an ADR service object 
adr_service = adr.Service(ansys_installation=ansys_loc, db_directory=db_dir, port=adr_port) 

# Start the service. If db_dir is empty or does not exist, set create_db to True. If it is an old ADR database, set it to False. 
session_guid = adr_service.start(create_db=True) 

Next step is to have you application send items into the database. Remember to tag each item so that it can easily be retrieved from the database, and so that the data can be organized in the report templates.

# Create text item 
my_text = adr_service.create_item(obj_name='Text') 
my_text.item_text = "<h1>Simple Title</h1>Abc..." 
my_text.set_tags(“section=intro”) 
# Create table item 
import numpy as np 
my_table = adr_service.create_item(obj_name='Table') 
my_table.table_dict["rowlbls"] = ["Row 1", "Row 2"] 
my_table.item_table = np.array([["1", "2", "3", "4", "5"],["1", "4", "9", "16", "25"]], dtype="|S20") 
my_table.set_tags(“section=plots”) 
# Create image item 
img = adr_service.create_item(obj_name='Image') 
# Can be a png image of the binary corresponding to it 
img.item_image = r'C:\tmp\test_image.png' 
img.set_tags(“section=intro”) 

# Create 3D scene item 
scene = adr_service.create_item(obj_name='Scene') 
scene.item_scene = r'C:\tmp\test_scene.avz' 
scene.set_tags(“section=3Dscene”) 

You can control how each item will be rendered in the report by setting properties on it. For example, you can control the table to be visualized as a plot instead:

my_table.plot = 'line' 
# Set X axis and axis formatting 
my_table.xaxis = 'Row 1' 
my_table.format = 'floatdot1' 

Now it is time to create a report template. The current version of pydynamicreporting does not provide this functionality directly, but you can use ADR low level python API to access it. Details can be found here and here.

server = adr_service.serverobj 
template_1=server.create_template(name="My Report", parent=None, report_type="Layout:basic") 
template_1.params='{"HTML": "<h1>My Report</h1>"}' 

server.put_objects(template_1) 
template_6=server.create_template(name="ToC", parent=template_1, report_type="Layout:toc") 
template_6.params='{"TOCitems": 1, "HTML": "<h1>Table of Contents</h1>"}' 
template_6.set_filter("A|i_name|eq|__NonexistantName__;") 

server.put_objects(template_6) 
server.put_objects(template_1) 
template_0=server.create_template(name="Introduction", parent=template_1, report_type="Layout:panel") 
template_0.params='{"properties": {"TOCItem": "1"}, "HTML": "<h2>Introduction</h2>"}' 
template_0.set_filter("A|i_tags|cont|intro;") 

server.put_objects(template_0) 
server.put_objects(template_1) 
template_4=server.create_template(name="text", parent=template_0, report_type="Layout:basic") 
template_4.params='{"properties": {"TOCItem": "0"}}' 
template_4.set_filter("A|i_type|cont|html,string;") 

server.put_objects(template_4) 
server.put_objects(template_0) 
server.put_objects(template_1) 
template_5=server.create_template(name="image", parent=template_0, report_type="Layout:basic") 
template_5.params='{"properties": {"TOCItem": "0"}}' 
template_5.set_filter("A|i_type|cont|image;") 

server.put_objects(template_5) 
server.put_objects(template_0) 
server.put_objects(template_1) 
template_2=server.create_template(name="3D scene", parent=template_1, report_type="Layout:panel") 
template_2.params='{"properties": {"TOCItem": "1"}, "HTML": "<h2>3D Scene</h2>\\nAVZ representation of the model"}' 
template_2.set_filter("A|i_tags|cont|scene;") 

server.put_objects(template_2) 
server.put_objects(template_1) 
template_3=server.create_template(name="Plot", parent=template_1, report_type="Layout:panel") 
template_3.params='{"properties": {"TOCItem": "1"}, "HTML": "<h2>Values</h2>\\nA plot"}' 
template_3.set_filter("A|i_tags|cont|plots;") 

server.put_objects(template_3) 
server.put_objects(template_1) 

Once the report template has been defined, every time it is called it will be applied against the items in the database, generating the report on the fly.

To embed the report into you application, simply get either the url or the iframe from the report object:

# get the object corresponding to the ‘My Report’ report 
report_by_name = adr_service.get_report(report_name='My Report') 
report_url = report_by_name.get_url() 
report_iframe = report_by_name.get_iframe() 

You can paste the url into a web browser to visualize the live report.

At last, when quitting the application, make sure to stop the ADR service:

adr_service.stop() 

You can find at the end of this article a zipped file containing the files and the script to reproduce the steps described. Remember to change the path for file locations, database directory and the local Ansys installation to match the values on your machine before running the script.