OBIEE/BIP Web Services with Python

1,074 views
Skip to first unread message

mhathi

unread,
Mar 26, 2015, 2:46:48 PM3/26/15
to obiee-enterpri...@googlegroups.com
I am trying to write a command-line utility to run BI Publisher reports (BI Publisher is deployed as part of OBIEE, not standalone). Knowing neither Python nor Java, is a distinct disadvantage but googling landed me to Robin's blog post http://www.rittmanmead.com/2014/01/exploring-obiee-web-services-through-python/

Thought I can "leverage" :) this for BI Publisher. Seems straight forward enough until I ran into "how do you pass multiple parameters for the report to the ReportRequest object".

I would appreciate anyone (perhaps rmoff himself) filling in this gap.

Thanks,

Manish

-------------Here's what I have so far -----------------
# RNM 20140124
#
# --------------------
# Required
from suds.client import Client
client = Client(sec)

# Print all methods and services
#print str(client);

#---

print "Reached after Client"
#------------
# Logon
sessionid = client.service['SecurityService'].login('weblogic','Password01')

print "Reached after sessionid"
print "--------------- "

# Print all methods and services
print str(sessionid);



rep_req = rep_svc.factory.create('ReportRequest')

#print str(rep_req)

rep_req.reportAbsolutePath = '/Published Reports/My Report Name.xdo'

rep_req.reportOutputPath = '/home/oracle/test_output.pdf'

print "Printing rep_req object"
print "--------------- "
print str(rep_req)

p_params = rep_svc.factory.create('ParamNameValues')

print "Printing p_params object"
print "--------------- "
print str(p_params)

At this point, I am stuck...how to pass
p_param1 = Value1
p_param2 = Value2
p_date_param = DateValue

Girish

unread,
Mar 26, 2015, 3:51:22 PM3/26/15
to obiee-enterpri...@googlegroups.com
Hi Manish

I'm no python developer but I had a quick look at the WSDL for you.


Param names in BIP can be multi valued and have a pretty complex structure(see ParamNameValue Type in the WSDL type definition below).


So, In its simplest form, I reckon the XML structure send in the request body needs to look like this

<parameterNameValues>
<item>
<name>PARAM 1</name>
<values>
<item>VALUE 1</item>
</values>
</item>
</parameterNameValues>


So extrapolating this to your python code,  you would need to build an object array of items(one per param) and attach it to the p_params variable you already have.




Inline image 1






As an alternative to this, if you don't mind using RESTful services, I have a working library of all OBIEE and BIP web services implemented as RESTful API using Node.js

I use that library of RESTful services whenever I need to quickly build a UI for administrative automation or Regression testing.

You could just use the curl command to talk to REST API as they are very lightweight unlike SOAP.




Kind Rgds

Girish





--
--
You received this message because you are subscribed to the Google
Groups "OBIEE Enterprise Methodology Group" group.
To post to this group, send email to
obiee-enterpri...@googlegroups.com
To unsubscribe from this group, send email to
obiee-enterprise-met...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/obiee-enterprise-methodology?hl=en
 
All content to the OBIEE EMG lies under the Creative Commons Attribution 3.0 Unported License (http://creativecommons.org/licenses/by/3.0/). Any content sourced must be attributed back to the OBIEE EMG with a link to the Google Group (http://groups.google.com/group/obiee-enterprise-methodology).

---
You received this message because you are subscribed to the Google Groups "OBIEE Enterprise Methodology Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to obiee-enterprise-met...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Regards,
Girish Lakshmanan

mhathi

unread,
Mar 26, 2015, 4:49:40 PM3/26/15
to obiee-enterpri...@googlegroups.com
Girish,

That is precisely where I am stuck. How to further assign the name/value pairs to the p_params (ParamNameValues) object.

I would definitely appreciate if you an share how you use your library using curl. The use-case that I am going for is very simple. I need a way to launch BIP reports from the command line similar to how Oracle Reports Server has the rwclient.sh utility. This way we can use this utility from cron and/or after/before custom data processing routines etc.

Thanks,

Manish

Girish

unread,
Mar 26, 2015, 8:18:27 PM3/26/15
to obiee-enterpri...@googlegroups.com
Okay, you've made me spend an hour and a half learning python today! :)
Here's the code that you're looking for. I've tested it and it works perfectly fine. Please note the "DeleteEmptyTags" plugin that I've added to remove empty tags from the SUDS generated XML before it is sent to BIP. I had to do this because BIP didn't like the way SUDS handles non-mandatory elements.

About my node.js RESTful implementation project, I'm going to put it on github so you can pick it up from there soon. Will send out a link once its there.


Rgds
Girish



#!/usr/bin/python
# -*- coding: utf-8 -*-

###################################################################################
from suds.client import Client
import logging
from suds.plugin import MessagePlugin
import re

logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)


###############Custom Plugin to delete empty tags as BIP doesn't seem to like em

class DeleteEmptyTags(MessagePlugin):

    def clear_empty_tags(self, tags):
        for tag in tags:
            children = tag.getChildren()[:]
            if children:
                self.clear_empty_tags(children)
            if re.match(r'^<[^>]+?/>$', tag.plain()):
                tag.parent.remove(tag)

    def marshalled(self, context):
        self.clear_empty_tags(context.envelope.getChildren()[:])


rep_client = \
           , plugins=[DeleteEmptyTags()])

rep_req = rep_client.factory.create('ReportRequest')

rep_req.reportAbsolutePath = \
    '/05. Published Reporting/b. Features/Cascading Parameters/Cascading Optional Parameters.xdo'

rep_req.reportOutputPath = '/home/oracle/outputFile_param.pdf'
rep_req.attributeFormat = 'pdf'
rep_req.attributeTemplate = 'Simple'
rep_req.attributeLocale = 'en-US'

p_params = rep_client.factory.create('ParamNameValues')
p_params.listOfParamNameValues = \
    rep_client.factory.create('ArrayOfParamNameValue')

###############Param 1

p_params.listOfParamNameValues.item.append(rep_client.factory.create('ParamNameValue'))
p_params.listOfParamNameValues.item[0].name = 'P_STATE'

p_paramOneValuesArray = rep_client.factory.create('ArrayOfString')
p_params.listOfParamNameValues.item[0].values = p_paramOneValuesArray

###########Param 1 - value

p_params.listOfParamNameValues.item[0].values.item = 'WI'

#############Param 2

p_params.listOfParamNameValues.item.append(rep_client.factory.create('ParamNameValue'))
p_params.listOfParamNameValues.item[1].name = 'P_CITY'

p_paramOneValuesArray = rep_client.factory.create('ArrayOfString')
p_params.listOfParamNameValues.item[1].values = p_paramOneValuesArray

#############Param 2 - value

p_params.listOfParamNameValues.item[1].values.item = 'Beloit'
rep_req.parameterNameValues = p_params

# Call service

reportReturn = rep_client.service['ReportService'].runReport(rep_req,'weblogic', 'Admin123')



Kind Rgds
Girish

Robin Moffatt

unread,
Mar 26, 2015, 9:01:59 PM3/26/15
to obiee-enterpri...@googlegroups.com
Restful library sounds great, looking forward to seeing it on github :)

Robin

mhathi

unread,
Mar 26, 2015, 9:16:18 PM3/26/15
to obiee-enterpri...@googlegroups.com
Girish,

Many thanks for look into this. I stared...and stared...but still the syntax just didn't come to me.
I tried out the code in our environment and offcourse it WORKS!

Thanks to #RMOFF for pointing the way and you, Girish for closing the loop on this...I guess I will have to learn Python, seems like fun.

Manish
Reply all
Reply to author
Forward
0 new messages