Inquire Rest API allows you to obtain detailed session data for each session stored in the Log Data Source (LDS). The following code can help you extract session data and save it as a JSON or as a JSON Lines file. It can help you in the following aspects:
- Save historical session data. This can be helpful to keep track of data which gets removed from the LDS due to the established retention time.
- Use other methods than Teneo Query Language (TQL) to analyze your data. With JSON or JSON Lines file you can analyze data using any language that you are most comfortable with, such as Python, R, etc.
Please copy the following Groovy code and save it as ExtractSessionData.groovy or similar names you prefer.
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
class InquireApi {
// Define properties
private static String baseUrl = ""
private static String username = ""
private static String password = ""
private static String lds = ""
private static String accessToken = ""
// Initialization
InquireApi(String baseUrl, String username, String password, String lds){
this.baseUrl = baseUrl
this.username = username
this.password = password
this.lds = lds
}
// Log in Teneo Inquire engine
public static void login() {
def apiUrl = this.baseUrl + "teneo-inquire/rest/auth/login"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.header("Content-type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(new JsonBuilder(["user":this.username,"pass":this.password]).toString()))
.build()
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
if (response.statusCode() == 200) {
println("Log in successfully.")
this.accessToken = response.body()
} else {
throw new Exception("Error in login, error code: " + response.statusCode())
}
}
// Log out from Teneo Inquire engine
public static void logout() {
def apiUrl = this.baseUrl + "teneo-inquire/rest/auth/logout"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.header("Content-type", "application/json")
.header("Authorization", "Bearer "+accessToken)
.method("POST", HttpRequest.BodyPublishers.noBody())
.build()
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
if (response.statusCode() == 200) {
println("Log out successfully.")
} else {
throw new Exception("Error in log out, error code: " + response.statusCode())
}
}
// Run a query via Inquire API (return query ID)
public static String runQuery(String query, int maxResults) {
def apiUrl = this.baseUrl + "teneo-inquire/rest/tql/submit?lds=" + this.lds + "&esPageSize=" + maxResults
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.header("Content-type", "application/x-www-form-urlencoded")
.header("Authorization", "Bearer "+accessToken)
.method("POST", HttpRequest.BodyPublishers.ofString("query="+URLEncoder.encode(query)))
.build()
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
if (response.statusCode() == 200) {
def result = new JsonSlurper().parseText(response.body())
return result.id
} else {
throw new Exception("Error in running query, error code: " + response.statusCode())
}
}
// Get query result by query ID
public static List getQueryResult(String queryId) {
def apiUrl = this.baseUrl + "teneo-inquire/rest/tql/poll?id=" + queryId
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.header("Authorization", "Bearer "+accessToken)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build()
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
if (response.statusCode() == 200) {
def result = new JsonSlurper().parseText(response.body())
return result.result
} else {
throw new Exception("Error in getting query result, error code: " + response.statusCode())
}
}
// Get session data from session ID
public static Map getSessionData(List<String> sessionIds) {
def apiUrl = this.baseUrl + "teneo-inquire/rest/data/" + this.lds + "/session?id=" + sessionIds.join("&id=")
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.header("Authorization", "Bearer "+accessToken)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build()
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
if (response.statusCode() == 200) {
def result = new JsonSlurper().parseText(response.body())
return result
} else {
throw new Exception("Error in getting session data, error code: " + response.statusCode())
}
}
}
// Convert session id list to batches
public static List<String> toBatch(List<String> inputList, int batchSize){
def batchedList = []
for (int i = 0; i < inputList.size(); i+=batchSize){
batchedList << inputList.subList(i,Math.min(inputList.size(),i+batchSize))
}
return batchedList
}
public static void main(String[] args) {
def endpoint = '' // Fill in your endpoint url (begin with "http://query.")
def username = '' // Fill in your username (the same username you use for Teneo Studio)
def password = '' // Fill in your password (the same password you use for Teneo Studio)
def lds = '' // Fill in the LDS name
def outputFormat = "json" // By default we use standard JSON file. You can change it to "jsonl" if you need a json lines file
def query = 'la s.id as sid order by s.beginTime asc' // This is a query to retrieve the list of session IDs ordered by begin time of the session. You can add time restrictions such as 's.beginTime == in {"now-1w/w"}' (extract all data logged during the last calendar week)
def maxResults = 10000 // Maximum of results allowed for single query. Please make sure the number of session you need to extract is lower than the maximum number of results allowed.
def batchSize = 100 // The batch size of session ids to be sent to the method getSessionData. In most of the cases you do not need to change it. If you see error caused by the size of request like error 414 or 431, please choose a smaller batch size.
// Get output file name from the argument or use default file name
def fileName = ''
if(args){
fileName = args[0]
if (fileName.endsWith("jsonl")) outputFormat = "jsonl"
else if (fileName.endsWith("json")) outputFormat = "json"
}
else{
fileName = "SessionData." + outputFormat
}
// Check the extension of the output file
fileName = fileName.endsWith(outputFormat)?fileName:fileName + "." + outputFormat
// Create Inquire API connector instance
def inquireConnector = new InquireApi(endpoint,username,password,lds)
// Log in Inquire engine
inquireConnector.login()
// Run the query and retrieve the list of session IDs
def queryId = inquireConnector.runQuery(query,maxResults)
def results = inquireConnector.getQueryResult(queryId)
// Generate batched session ids
def batchedSessionIds = toBatch(results.sid,batchSize)
// Retrieve session data according to the session IDs
def sessionDatas = []
println("Starting retrieving session data. " + results.size() + " sessions in total.")
for (int i=0; i<batchedSessionIds.size(); i++){
for (sessionData in inquireConnector.getSessionData(batchedSessionIds[i])){
sessionDatas << sessionData
}
// Print progress every batch
println(Math.min((i+1)*batchSize,results.size()) + " sessions have been processed.")
}
// Write the output file
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))
if (outputFormat == "json") {
writer.write(new JsonBuilder(sessionDatas).toString())
} else {
for (sessionData in sessionDatas){
writer.write(new JsonBuilder(sessionData).toString())
writer.write("\n")
}
}
writer.close()
println(outputFormat + " file written successfully: " + fileName)
// Log out from Inquire engine
inquireConnector.logout()
}
Before you run the code, you need to fill in the following information in the main function (obligatory):
-
endpoint: The Inquire backend of your solution. You can find it by opening the Studio and clicking on the About button on the left, copy the URL from Connected to, and replace studio with
query
in the URL.
- username: The same username you use to log in the Teneo Studio
- password: The same password you use to log in the Teneo Studio
- lds : The name of the Log Data Source
And adjust the following variables if needed (optional):
- outputFormat: The output format, should be json (by default) or jsonl. It will be automatically adjusted if you indicate the output file name in the argument.
- query: The query used to extract all session IDs. By default, it doesn’t contain any restriction so it will extract ALL sessions in LDS order by session begin time. You can add a time period or other restrictions to it following TQL syntax.
- maxResults: The maximum number of results, by default set to 10000. Please only change it if you plan to extract data of more than 10000 sessions.
- batchSize: By default, we send an API request with 100 session IDs at one time in order to save time and lower the frequency of API calls. Please do not increase the batch size. If you get an error related to request or header length such as error 414 or 431, please reduce the batch size and try again.
Then run the following command in the Command Prompt in your operating system (with Groovy installed in advance):
groovy ExtractSessionData.groovy yourOutputFile.json
You can omit the argument for file name. In this case, a file named SessionData.json or SessionData.jsonl (depends on the variable outputFormat) will be created in the current folder path.