Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added documentation for exporting saved Metric Explorer charts with the XDMoD API #1907

Open
wants to merge 15 commits into
base: xdmod11.0
Choose a base branch
from

Conversation

aestoltm
Copy link
Contributor

@aestoltm aestoltm commented Aug 22, 2024

Description

This documentation contains a Python script that uses the XDMoD API to authenticate with a local XDMoD account for the given credentials and site URL. Then the script will export the saved Metric Explorer charts into the current working directory. This documentation also describes how to edit certain parts of the script and where to find more information about the request schema for the request that exports the images.

Motivation and Context

We received a ticket asking about using the XDMoD API to export saved images for an Open XDMoD - Open OnDemand integration. This documentation will be used with the response and for future tickets that refer to issues about exporting images with the XDMoD API.

Tests performed

Tested script locally.

Checklist:

  • The pull request description is suitable for a Changelog entry
  • The milestone is set correctly on the pull request
  • The appropriate labels have been added to the pull request

@aestoltm aestoltm added the documentation Documentation updates label Aug 22, 2024
@aestoltm aestoltm self-assigned this Aug 22, 2024
if 'config' in chart:
chart_json = json.loads(chart['config'])
for attribute in chart_json:
if (isinstance(chart_json[attribute], dict)):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest the chart_json[attribute] is stored in a variable for clarity/readability because of how often it is referenced here.


username = os.getenv('XDMOD_USERNAME')
password = os.getenv('XDMOD_PASSWORD')
site_address = ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super minor, but I would suggest making this clearer that the site_address should be filled in. Either a note in the the top comment or site_address = "<XDMOD_URL_HERE>". I assume most people will copy-paste this script without reading it and then encounter an issue when this isn't populated.

Copy link
Contributor

@ryanrath ryanrath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just need to add that the user needs to also pip install requests and it'll be good to go.

ryanrath
ryanrath previously approved these changes Aug 23, 2024
@@ -0,0 +1,82 @@
You can use the XDMoD API to image export your saved metric explorer charts. A local XDMoD account is **required** to authenticate through the API.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can use the XDMoD API to image export your saved metric explorer charts. A local XDMoD account is **required** to authenticate through the API.
You can use the XDMoD REST API to export your saved Metric Explorer charts as images.

SSO can also be used for authenticating through the REST API. The local account is required to run the Python script, though. I moved this line into another suggestion below.

docs/howto.md Outdated
@@ -8,3 +8,4 @@ The Open XDMoD HOWTOs are "how to" documents on specific subjects.
- [Change Metric Explorer Colors](howto-colors.html)
- [Enable Node Utilization Statistics](howto-node-utilization.html)
- [Reconstruct Slurm Accounting Logs](howto-reconstruct-slurm.html)
- [Export Saved Metric Explorer Charts Through the XDMOD API](howto-api-image-export.md)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- [Export Saved Metric Explorer Charts Through the XDMOD API](howto-api-image-export.md)
- [Export Saved Metric Explorer Charts Through the REST API](howto-api-image-export.md)

Comment on lines 45 to 47
'Token': auth_response['results']['token'],
'Authorization': auth_response['results']['token'],
'Content-Type': 'application/x-www-form-urlencoded'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'Token': auth_response['results']['token'],
'Authorization': auth_response['results']['token'],
'Content-Type': 'application/x-www-form-urlencoded'
'Token': auth_response['results']['token'],
'Authorization': auth_response['results']['token'],
'Content-Type': 'application/x-www-form-urlencoded'

For consistent indentation style.

f.write(chart_response.content)
```

The default image format is `svg`, but `png` and `pdf` formats are also supported. Refer to the XDMoD [Metric Explorer Tab Controller API](rest.html#tag/Metric-Explorer/paths/~1controllers~1metric_explorer.php/post) `get_data` operation for more information on the request body schema.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this above the code so all the documentation is above the code.

Comment on lines 72 to 73
chart_json['width'] = 916
chart_json['height'] = 484
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make these numbers global constants.

Comment on lines 27 to 32
load_dotenv()

username = os.getenv('XDMOD_USERNAME')
password = os.getenv('XDMOD_PASSWORD')
site_address = "<XDMOD_URL_HERE>"
image_format = "svg"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
load_dotenv()
username = os.getenv('XDMOD_USERNAME')
password = os.getenv('XDMOD_PASSWORD')
site_address = "<XDMOD_URL_HERE>"
image_format = "svg"
site_address = ""
image_format = "svg"
load_dotenv()
username = os.getenv('XDMOD_USERNAME')
password = os.getenv('XDMOD_PASSWORD')

I would suggest keeping the value of site_address blank so people don't think they're supposed to put the URL in between the angle brackets and so that they don't think they should replace the other all caps strings nearby with their usernames and passwords. I'd also suggest grouping the global constants together and moving them to the top so all the things the user would want to edit are in one place near the top.

Comment on lines 3 to 17
The following Python script will export your saved metric explorer charts. The `dotenv` and `requests` libraries are used when authenticating through the XDMoD API. You can install these libraries through:

```shell
pip install python-dotenv
pip install requests
```

Before running the script,

1. Install the required dependencies listed above.
1. Create a `.env` file with your local XDMoD account credentials in the same directory as the script.
1. Update `site_address` within the script with site address associated with your XDMoD instance.
1. Confirm the `image_format` within the script.

The script will export your saved metric explorer charts to the current working directory. **\*Note:** Replace `<XDMOD_URL_HERE>` with your site address.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following Python script will export your saved metric explorer charts. The `dotenv` and `requests` libraries are used when authenticating through the XDMoD API. You can install these libraries through:
```shell
pip install python-dotenv
pip install requests
```
Before running the script,
1. Install the required dependencies listed above.
1. Create a `.env` file with your local XDMoD account credentials in the same directory as the script.
1. Update `site_address` within the script with site address associated with your XDMoD instance.
1. Confirm the `image_format` within the script.
The script will export your saved metric explorer charts to the current working directory. **\*Note:** Replace `<XDMOD_URL_HERE>` with your site address.
The following Python script will export your saved Metric Explorer charts. An XDMoD username and password is required to run the script.
Before running the script,
1. Install the required `python-dotenv` and `requests` dependencies.
1. Create a `.env` file in the same directory as the script that contains the following contents, replacing `<username>` with your XDMoD username and `<password>` with your XDMoD password — make sure to secure this file with read-only access.
```
XDMOD_USERNAME=<username>
XDMOD_PASSWORD=<password>
```
1. Update the value of `site_address` within the script with the URL associated with your XDMoD portal.
1. Confirm the `image_format` within the script.

I would also suggest making the path where the images are written a global constant.

docs/howto-api-image-export.md Show resolved Hide resolved
@aestoltm
Copy link
Contributor Author

aestoltm commented Sep 5, 2024

@aaronweeden Updated per your feedback. You can now export either a single chart or all your saved charts to a specified path.

@@ -0,0 +1,93 @@
The following Python script will export your saved Metric Explorer charts. An XDMoD username and password is required to run the script.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following Python script will export your saved Metric Explorer charts. An XDMoD username and password is required to run the script.
The following Python script can be used to export your saved Metric Explorer charts to image files using the XDMoD REST API. An XDMoD username and password are required to run the script.

@@ -0,0 +1,93 @@
The following Python script will export your saved Metric Explorer charts. An XDMoD username and password is required to run the script.
Before running the script,
1. Install the required `python-dotenv` and `requests` dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Install the required `python-dotenv` and `requests` dependencies.
1. Install the required `python-dotenv` and `requests` Python dependencies (e.g., using `pip`).

Comment on lines 9 to 13
1. Update the value of `site_address` within the script with the URL associated with your XDMoD portal.
1. Update the value of `export_path` within the script with the desired path to export the images.
1. Confirm the `image_format` within the script.

The default image format is `svg`, but `png` and `pdf` formats are also supported. Refer to the XDMoD [Metric Explorer Tab Controller API](rest.html#tag/Metric-Explorer/paths/~1controllers~1metric_explorer.php/post) `get_data` operation for more information on the request body schema.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Update the value of `site_address` within the script with the URL associated with your XDMoD portal.
1. Update the value of `export_path` within the script with the desired path to export the images.
1. Confirm the `image_format` within the script.
The default image format is `svg`, but `png` and `pdf` formats are also supported. Refer to the XDMoD [Metric Explorer Tab Controller API](rest.html#tag/Metric-Explorer/paths/~1controllers~1metric_explorer.php/post) `get_data` operation for more information on the request body schema.
1. Update the value of `site_address` at the top of the script with the URL associated with your XDMoD portal.
1. Update the value of `export_path` at the top of the script with the desired directory path where the images will be written.
1. Confirm the desired values for `image_format`, `width`, and `height` at the top of the script. The default image format is `svg`, but `png` and `pdf` formats are also supported.
By default, the script will download all of your saved Metric Explorer charts. You can have it instead download a single chart by providing the `-n` or `--name` option followed by the name of the saved chart.
Refer to the XDMoD [Metric Explorer Tab Controller REST API](rest.html#tag/Metric-Explorer/paths/~1controllers~1metric_explorer.php/post) `get_data` operation for more information on the REST request body schema.

password = os.getenv('XDMOD_PASSWORD')

parser = argparse.ArgumentParser(description='Export XDMoD saved Metric Explorer charts with the REST API.')
parser.add_argument('-n', '--name',type=str, default='', help='Specify the chart name of a saved chart to export.')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
parser.add_argument('-n', '--name',type=str, default='', help='Specify the chart name of a saved chart to export.')
parser.add_argument('-n', '--name', help='Specify the chart name of a saved chart to export.')

The type will already be string, and None will be the default. For simplicity, I'd stick with these.

import json
import urllib
import argparse
from dotenv import load_dotenv
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from dotenv import load_dotenv
from dotenv import load_dotenv
import sys

Comment on lines 58 to 59
print('Specified chart not found.')
exit()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print('Specified chart not found.')
exit()
print('Specified chart not found.', file=sys.stderr)
sys.exit(1)

saved_charts = session.get(f'{site_address}/rest/v1/metrics/explorer/queries', headers=header)
saved_charts_data = saved_charts.json()

if args.name != '' and not any(chart_obj['name'] == args.name for chart_obj in saved_charts_data['data']):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if args.name != '' and not any(chart_obj['name'] == args.name for chart_obj in saved_charts_data['data']):
if args.name is not None and not any(chart_obj['name'] == args.name for chart_obj in saved_charts_data['data']):

print('Specified chart not found.')
exit()

for idx, chart in enumerate(saved_charts_data['data']):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for idx, chart in enumerate(saved_charts_data['data']):
for idx, chart in enumerate(saved_charts_data['data']):
if args.name is not None and args.name != chart['name']:
continue

and then you don't need to wrap the writing in an if/else or needlessly fetch each chart that isn't going to be written.

image_format = 'svg'
image_width = 916
image_height = 484

Copy link
Contributor

@aaronweeden aaronweeden Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if site_address == '':
print('Please edit the script to specify a site_address.', file=sys.stderr)
sys.exit(1)

Comment on lines 86 to 92
if args.name != '' and args.name == chart['name']:
with open(export_path + chart_name, "wb") as f:
f.write(chart_response.content)
exit()
else:
with open(export_path + chart_name, "wb") as f:
f.write(chart_response.content)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if args.name != '' and args.name == chart['name']:
with open(export_path + chart_name, "wb") as f:
f.write(chart_response.content)
exit()
else:
with open(export_path + chart_name, "wb") as f:
f.write(chart_response.content)
with open(export_path + chart_name, "wb") as f:
f.write(chart_response.content)

See suggestion above with continue.

@jpwhite4 jpwhite4 added this to the 11.0.0 milestone Sep 10, 2024
@aestoltm aestoltm modified the milestones: 11.0.0, 11.0.1, 11.0.2 Oct 2, 2024
@aestoltm aestoltm changed the base branch from main to xdmod11.0 November 22, 2024 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Documentation updates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants