Hello!
Thanks for the reply and sorry for the wait. I've been trying to use the undocumented API you told me about, but I still have some problems that I don't know how to resolve.
This is my code for authenticating to the API:
import requests
from requests.exceptions import RequestException
def authenticate(base_url, namespace, username, password):
try:
session = requests.Session()
auth_payload = {
"parameters": [
{"name": "CAMNamespace", "value": namespace},
{"name": "CAMUsername", "value": username},
{"name": "CAMPassword", "value": password},
{"name": "h_CAM_action", "value": "logonAs"}
]
}
get_url = f"{base_url}/bi/"
get_response = session.get(get_url)
get_response.raise_for_status()
xsrf_token = get_response.cookies.get('XSRF-TOKEN')
print(f"XSRF-TOKEN: {xsrf_token}")
post_url = f"{base_url}/bi/v1/login"
post_response = session.post(post_url, json=auth_payload, headers={'X-XSRF-TOKEN': xsrf_token})
post_response.raise_for_status()
# Extract cookies
cam_passport = post_response.cookies.get('cam_passport')
usersessionid = post_response.cookies.get('usersessionid')
print(f"cam_passport: {cam_passport}")
print(f"usersessionid: {usersessionid}")
pCookies = {
"XSRF-TOKEN": xsrf_token,
"cam_passport": cam_passport,
"usersessionid": usersessionid
}
headers = {
"accept": "application/json,text/javascript,*/*;q=0.01",
"accept-language": "en-US,en;q=0.9",
"x-xsrf-token": xsrf_token,
"cam_passport": cam_passport,
"usersessionid": usersessionid
}
return session, headers, pCookies
except RequestException as e:
raise ValueError(f"Failed to authenticate: {e}")
It retrieves the XSRF-TOKEN
, cam_passport
, and usersessionid
successfully, but I can't get to use the API when I make a request to http://server:port/bi/v1/expressbus/content-manager
. I get a 500 error.
This is the code I used when making HTTP calls:
def perform_request(session, method, url, headers, cookies, params=None, data=None):
try:
print(f"Request URL: {url}")
print(f"Request Headers: {headers}")
print(f"Request Params: {params}")
print(f"Request Data: {data}")
print(f"Request Cookies: {cookies}")
if method == 'GET':
response = session.get(url, headers=headers, params=params, cookies=cookies)
elif method == 'POST':
response = session.post(url, headers=headers, params=params, json=data, cookies=cookies)
elif method == 'PUT':
response = session.put(url, headers=headers, params=params, json=data, cookies=cookies)
elif method == 'DELETE':
response = session.delete(url, headers=headers, params=params, cookies=cookies)
else:
raise ValueError(f"Unsupported HTTP method: {method}")
response.raise_for_status()
return response
except RequestException as e:
print(f"Failed to execute request: {e}")
return None
If I am doing something wrong, please let me know. Thank you!
------------------------------
Guillem Labòria Soto
------------------------------
Original Message:
Sent: Sun March 17, 2024 07:04 AM
From: Paul Mendelson
Subject: Handling Large Number of Groups in REST API Requests on Cognos Analytics with Watson 11.2.0
In the response from the session API you should get an XSRF token and a cam_passport.
this is from my python script:
# Make the POST request
post_response = requests.post(login_url, json=request_body, headers=headers, cookies=get_response.cookies)
# Check the response
if post_response.status_code == 200:
cam_passport = post_response.cookies.get('cam_passport', '')
usersessionid = post_response.cookies.get('cam_passport', '')
print("xsrf: ", xsrf_token)
print("cam passport: ", usersessionid)
pcookies = {
"XSRF-TOKEN":xsrf_token,
"cam_passport": cam_passport,
"usersessionid":usersessionid
}
headers = {
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-language": "en-US,en;q=0.9",
"x-xsrf-token": xsrf_token,
"cam_passport": cam_passport,
"usersessionid":usersessionid
}
return {"response":post_response.json(),"headers":headers,"cookies":pcookies,"api_url":api_url}
and in the module for actually fetching the data:
async def get_items_in_stages(url, headers, cookies, options={}, batch_size=100, next_run_callback=lambda x: None, final_callback=lambda x: None):
skip_objects = 0
all_records = []
async def fetch_and_process():
nonlocal skip_objects, all_records
# Modify options with batch_size and skip_objects
new_options = {**options, 'maxObjects': batch_size, 'skipObjects': skip_objects}
new_url = f"{url}&{urlencode({'options': str(new_options)})}"
# Fetch data
data = await get_items(new_url, headers, cookies)
------------------------------
Paul Mendelson
Original Message:
Sent: Tue March 12, 2024 07:05 AM
From: Guillem Labòria Soto
Subject: Handling Large Number of Groups in REST API Requests on Cognos Analytics with Watson 11.2.0
I've been trying to do what you told me but I've found some problems with it.
How do you authenticate using this API? With the REST API, it is easy with the request PUT and adding to the base url "/session" and the credentials in the body json, but I couldn't find out how to authenticate with this API.
------------------------------
Guillem Labòria Soto
Original Message:
Sent: Tue March 12, 2024 03:38 AM
From: Paul Mendelson
Subject: Handling Large Number of Groups in REST API Requests on Cognos Analytics with Watson 11.2.0
It took me a long time to figure this one out. If you're willing to use some undocumented APIs, you can use the expressbus/content-manager API. This lets you search by searchpath, and is the base of many of my tools.
Take a look at this example.
http://server/bi/v1/expressbus/content-manager?searchPath=//role|//group&properties=defaultName,id,searchPath,parent,ancestors,creationTime,modificationTime,type,defaultDescription,owner,members,userProfileSettings&options={maxObjects:100,skipObjects:100}
- http://server/bi/ - gateway
- v1/expressbus/content-manager - API
- ?searchPath=//role|//group - Searchpath.
If you want to look in a specific folder you can do //folder[@name="folder name"]//role or storeId("i1234")//role searchpath is essentially an xpath expression, so folder//role will recursively pull every role under the folder. If you want only the children of the folder you'd do folder/role the pipe (|) is an OR clause. storeId("i1234")//role|storeId("i1234")//group means it will pull all of the roles and groups under the i1234 object. - &properties=defaultName,id,searchPath,parent,ancestors,creationTime,modificationTime,type,defaultDescription,owner,members,userProfileSettings
This refers to the individual fields available the type.
Available fields are:
- _meta
- ancestors
- camIdentity
- creationTime
- defaultDescription
- defaultName
- defaultScreenTip
- description
- disabled
- displaySequence
- distributionMembers
- extensions
- governors
- hasChildren
- hidden
- iconURI
- id
- members
- modificationTime
- name
- options
- owner
- parent
- permissions
- position
- profileRank
- routingHints
- screenTip
- searchPath
- searchPathForURL
- securityMembers
- shown
- tenantID
- type
- usage
- userProfileSettings
- version
- viewed
- &options={maxObjects:100,skipObjects:100}
There are more options, but these are the ones that are most applicable to what you're asking. maxObjects:100,skipObjects:100 means this will return the second group of 100 roles and groups.
Out of curiosity, what are you trying to accomplish? If this is something that more people might need I can add it to my tools.
------------------------------
Paul Mendelson
Original Message:
Sent: Fri March 08, 2024 05:18 AM
From: Guillem Labòria Soto
Subject: Handling Large Number of Groups in REST API Requests on Cognos Analytics with Watson 11.2.0
Hello!
I've been working with the REST API on Cognos Analytics 11.2.0 to retrieve groups from a specific folder. While the API call succeeds, it seems to cap the response at 100 groups, which is problematic when dealing with folders that contain more.
In version 12.0.0, the pagination is manageable with the 'page' query parameter. However, this parameter doesn't appear to exist in 11.2.0. I've reviewed the documentation but couldn't find a clear method for pagination in this version.
On the 11.2.0 (The version I'm currently using), this param doesn't exists.
------------------------------
Guillem Labòria Soto
------------------------------