Monday, July 9, 2018

Can Python digest a cube?


Then, I drew the inside of the boa constrictor, so that the grown-ups could see it clearly. They always need to have things explained.
But let's put elephants and boa constrictors aside. The more important question would be -- Can Python digest a cube? Nowadays even kids in elementary schools do python, so I thought it would be useful to show how Python code can call OAC Essbase REST APIs. Let's try to list files under /gallery/Cubes directory in the Essbase catalog.
urllib package provides an easy way to execute HTTP calls and json package provides a parser for json strings. Let's import these two packages into our python interpreter
import urllib
import json

OAC Essbase supports basic authentication, so first we will set up a Basic Authentication handler. This is done by the following three lines:
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, ess_url, ess_user, ess_password)
handler = urllib.request.HTTPBasicAuthHandler(password_mgr)

The REST API to get the file list is GET http://base_url/essbase/rest/v1/files/file_path and this REST call accepts "application/json". Next four lines show how to make the call
opener = urllib.request.build_opener(handler)
opener.addheaders.append(('Accept', 'application/json'))
response = opener.open(ess_url + '/rest/v1/files/gallery/Cubes')
txt = response.read().decode('utf8')

The result is a json string that represents the content of /gallery/Cubes directory. Compare it with the content you see in UI.

{
  "currentFolder" : {
    "name" : "Cubes",
    "fullPath" : "/gallery/Cubes",
    "type" : "folder",
    "permissions" : { }
  },
  "items" : [ {
    "name" : "Application",
    "fullPath" : "/gallery/Cubes/Application",
    "type" : "folder",
    "permissions" : { },
    "links" : [ {
      "rel" : "listFiles",
      "href" : "http://slc13kee:9000/essbase/rest/v1/files/gallery/Cubes/Application",
      "method" : "GET",
      "type" : "application/json"
    } ]
  }, {
    "name" : "Applications",
    "fullPath" : "/gallery/Cubes/Applications",
    "type" : "folder",
    "permissions" : { },
    "links" : [ {
      "rel" : "listFiles",
      "href" : "http://slc13kee:9000/essbase/rest/v1/files/gallery/Cubes/Applications",
      "method" : "GET",
      "type" : "application/json"
    } ]
  }, {
    "name" : "ASO",
    "fullPath" : "/gallery/Cubes/ASO",
    "type" : "folder",
    "permissions" : { },
    "links" : [ {
      "rel" : "listFiles",
      "href" : "http://slc13kee:9000/essbase/rest/v1/files/gallery/Cubes/ASO",
      "method" : "GET",
      "type" : "application/json"
    } ]
  }, {
    "name" : "General",
    "fullPath" : "/gallery/Cubes/General",
    "type" : "folder",
    "permissions" : { },
    "links" : [ {
      "rel" : "listFiles",
      "href" : "http://slc13kee:9000/essbase/rest/v1/files/gallery/Cubes/General",
      "method" : "GET",
      "type" : "application/json"
    } ]
  }, {
    "name" : "LICENSE.txt",
    "fullPath" : "/gallery/Cubes/LICENSE.txt",
    "type" : "txt",
    "modifiedTime" : 1530626314000,
    "sizeInBytes" : 1875,
    "permissions" : { },
    "links" : [ {
      "rel" : "download",
      "href" : "http://slc13kee:9000/essbase/rest/v1/files/gallery/Cubes/LICENSE.txt",
      "method" : "GET",
      "type" : "application/octet-stream"
    } ]
  }, {
    "name" : "Table Format",
    "fullPath" : "/gallery/Cubes/Table Format",
    "type" : "folder",
    "permissions" : { },
    "links" : [ {
      "rel" : "listFiles",
      "href" : "http://slc13kee:9000/essbase/rest/v1/files/gallery/Cubes/Table%20Format",
      "method" : "GET",
      "type" : "application/json"
    } ]
  }, {
    "name" : "Technical",
    "fullPath" : "/gallery/Cubes/Technical",
    "type" : "folder",
    "permissions" : { },
    "links" : [ {
      "rel" : "listFiles",
      "href" : "http://slc13kee:9000/essbase/rest/v1/files/gallery/Cubes/Technical",
      "method" : "GET",
      "type" : "application/json"
    } ]
  }, {
    "name" : "Utility",
    "fullPath" : "/gallery/Cubes/Utility",
    "type" : "folder",
    "permissions" : { },
    "links" : [ {
      "rel" : "listFiles",
      "href" : "http://slc13kee:9000/essbase/rest/v1/files/gallery/Cubes/Utility",
      "method" : "GET",
      "type" : "application/json"
    } ]
  } ]
}
Json string is not the most convenient data structure to work with, but fortunately with json package it takes only one line of code to transform it into a dictionary.
resp = json.loads(txt)

Now let's put it all together. Only 13 lines of code and we are done

import urllib
import json

ess_url = 'http://your_essbase_url/essbase' 
ess_user = 'user_name'
ess_password = 'user_password'
 
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, ess_url, ess_user, ess_password)
handler = urllib.request.HTTPBasicAuthHandler(password_mgr)

opener = urllib.request.build_opener(handler)
opener.addheaders.append(('Accept', 'application/json'))
response = opener.open(ess_url + '/rest/v1/files/gallery/Cubes')
txt = response.read().decode('utf8')

resp = json.loads(txt)


3 comments:

  1. You stole my post. I was about to write about it and the only difference was i was using requests package

    ReplyDelete
  2. Curious what Python version/IDE was used seem to get

    password_mgr = urllib.requests.HTTPPasswordMgrWithDefaultRealm()
    AttributeError: 'module' object has no attribute 'requests'

    ReplyDelete