Service-now is a IT service management software that hosts a wide ranging list of reports from different modules of IT services that are organized into tables. ServiceNow publishes its underlying table structures and associated data that can be pulled via SOAP query. This can be achieved through any scripting language. Although, python is my default goto scripting language, the soap client in python are not very well maintained. The most pythonic of those is the SUDS which does not seem to work well with service now api. While it is pretty slick and easy to get the basic data output using python/suds, as you move to more complex queries python fails. This is a known issue.
https://fedorahosted.org/suds/ticket/330
http://lists.fedoraproject.org/pipermail/suds/2011-October/001526.html
http://stackoverflow.com/questions/11850275/parameters-with-leading-underscores-in-python-suds
The __limit and encoded query does not seem to have the desired effect on the output as SUDS never passes these. So after few trials I ended up using Perl for the data pull and calling Perl from my Django framework. This worked like a charm. So here goes a snippet that can be used to get multiple records from an incident with max limit 10000 records and pulling single records from incident.
#!/usr/bin/perl -w use SOAP::Lite; # basic auth sub SOAP::Transport::HTTP::Client::get_basic_credentials { return 'user' => 'password'; } # specify the endpoint to connect. This is the first incident that pulls say two values field1, field2 and field3 is used as a filter for records. my $soap1 = SOAP::Lite -> proxy('https://instance.service-now.com/incident1.do?displayvalue=all&SOAP'); my $method1 = SOAP::Data->name("getRecords")-> attr({xmlns => "http://www.service-now.com/"}); my @params1 = ( SOAP::Data->name(field3=> "Your Value") ); push(@params1, SOAP::Data->name(__limit => "10000") ); my $som1 = $soap1->call($method1 => @params1); my @serverData1 = @{$som1->body->{getRecordsResponse}->{getRecordsResult}}; foreach my $serverRec (@serverData1) { $f1 = $serverRec->{field1}; $f2 = $serverRec->{field2}; print $f1,',',$f2,"\n"; } #incident 2 match field4 and then retrieve field5 and 6 for single record my $soap2 = SOAP::Lite -> proxy('https://instance.service-now.com/incident2.do?displayvalue=all&SOAP'); my @params2 = ( SOAP::Data->name(field4 => "Your Value") ); push(@params2, SOAP::Data->name(__limit => "1") ); $f5 = $soap2->call($method1 => @params2)->body->{getRecordsResponse}->{getRecordsResult}->{field5} || "None"; $f6 = $soap2->call($method1 => @params2)->body->{getRecordsResponse}->{getRecordsResult}->{field6} || "None"; print $f5,',',$f6,"\n";
And then from python function we can easily call this perl script:
import subprocess ret = subprocess.call(["perl","/path/name/only/servicenow.pl"])