Starting with the release of Strategy ONE (March 2024), dossiers are also known as dashboards.
The Python code below does just that. The result of the search is saved as a JSON file. This file can be later imported back into Strategy dossier. Object names placed in a column can act as hyperlinks to relevant certified dossiers. You can also use the results to build custom HTML or JavaScript interfaces that will be presented to the end users.
This code can be used to search not only for certified dossiers, but for all dossiers. You can also use it to find other objects in the project like cubes or metrics. You should check EnumDSSXMLObjectTypes table for the codes of each object type.
There are several parameters at your disposal like:
- object type
- certified flag
- root folder
- whether to include ancestors (folder structure)
Note - 'requests' and 'pandas' are Python libraries that you need to install in your Python environment (pip install requests)
Note - I've added color formatting in the code below (http://hilite.me/). Code copied from here might not work due to indentation issues. In that case, use attached file with sample code.
Example of a dossier based on the output JSON file:

# Strategy JSON DATA PUSH API
# Getting information about Metadata objects - by Robert Prochowicz
# Tested with MSTR 2019 update 1 / 2019-07-19
import requests
import pandas as pd
import csv
### Parameters ###
api_login = 'mstr'
api_password = 'xxxx'
login_mode = 1 #1-standard, 16-LDAP
project_id = 'B7CA92F04B9FAE8D941C3E9B7E0CD754'
base_url = 'http://warw7243.corp.Strategy.com:8080/MicroStrategyLibrary/api/'
root_folder = ''
type_object = 55 #55 is document/dossier ; 3 is report/cube
certifiedStatus = 'CERTIFIED_ONLY' #CERTIFIED_ONLY , ALL
get_ancestors = 'true'
limit_search = -1
#### FUNCTIONS ###
def login(base_url,api_login,api_password,login_mode):
print("Getting token...")
data_get = {'username': api_login,
'password': api_password,
'loginMode': login_mode}
r = requests.post(base_url + 'auth/login', data=data_get)
if r.ok:
authToken = r.headers['X-MSTR-AuthToken']
cookies = dict(r.cookies)
print("Token: " + authToken)
return authToken, cookies
else:
print("HTTP %i - %s, Message %s" % (r.status_code, r.reason, r.text))
def set_headers(authToken,project_id):
headers = {'X-MSTR-AuthToken':authToken,
'Content-Type':'application/json',
'Accept':'application/json',
'X-MSTR-ProjectID':project_id}
return headers
def quickSearch(base_url, auth_token, cookies, project_id, root_folder, type_object, certifiedStatus, get_ancestors, limit_search):
headers = set_headers(auth_token,project_id)
search_url = (base_url + "searches/results?" + "root=" + root_folder + "&type=" + str(type_object)
+ "&getAncestors=" + get_ancestors + "&limit=" + str(limit_search) +
"&certifiedStatus=" + certifiedStatus)
print("Quick Search...")
r = requests.get(search_url, headers=headers, cookies=cookies)
if r.ok:
print("Error: " + str(r.raise_for_status()) + " || HTTP Status Code: " + str(r.status_code))
print("Total Items: " + str(r.json()['totalItems']))
return r.json()
else:
print("HTTP %i - %s, Message %s" % (r.status_code, r.reason, r.text))
def main():
authToken, cookies = login(base_url,api_login,api_password,login_mode)
#### Quick Search
search_result = quickSearch(base_url, authToken, cookies, project_id, root_folder, type_object, certifiedStatus, get_ancestors, limit_search)
list_search = search_result['result'] # cutting out unnecessary level of data
# Adding path info
for row in list_search:
path=''
if 'ancestors' in row: # necessary if you set get_ancestors parameter to false
for i in range(len(row['ancestors'])):
path= path+' > '+(row['ancestors'][i]['name'])
else:
path="___NO PATH"
row['path'] = path[3:]
# Generating JSON files
df = pd.DataFrame(list_search)
df.to_json(r'certified_table.json', orient='table') # this returns multiple tables (more relational structure)
df.to_json(r'certified_records.json', orient='records') #this returns a single table
### Main program
main()