| WebService-iThenticate documentation | Contained in the WebService-iThenticate distribution. |
WebService::iThenticate::Client - a client class to access the iThenticate service
# construct a new client
$client = WebService::iThenticate::Client->new({
username => $username,
password => $password,
url => 'https://api.ithenticate.com:443/rpc', # default https://test.api.ithenticate.com:443/rpc
});
# authenticate the client, returns an WebService::iThenticate::Response object
$response = $client->login;
# access the session id from the response object
$sid = $response->sid;
# submit a document
$response = $client->add_document({
title => 'Moby Dick',
author_first => 'Herman',
author_last => 'Melville',
filename => 'moby_dick.doc',
folder => 72, # folder id
submit_to => 1, # 1 => 'Generate Report Only'
upload => `cat moby_dick.doc`, # binary content of document
# the client module will base64 and chunk it
});
# get the newly created document id
$document_id = $response->id;
$document = $response->document;
# get the document parts (note use of hash reference instead of object method)
$parts = $document->{parts};
This module provides a client library interface to the iThenticate API web services. It encapsulates different transport engines to provide a set of methods through which the user can access the iThenticate API programmatically.
See the iThenticate API reference web page at http://www.ithenticate.com/faq.html for more details.
# construct a new client
$client = WebService::iThenticate::Client->new({
username => $username,
password => $password,
host => 'api.ithenticate.com', # default test.api.ithenticate.com
path => 'rpc', # default rpc
port => 3000, # default 3000
});
Returns an WebService::iThenticate::Response object
# pass basic auth credentials to the client
$client->credentials({
realm => 'My Authenticated Realm',
username => 'foo@example.com',
password => 'zimzamfoo123',
});
# authenticate the client, returns an WebService::iThenticate::Response object $response = $client->login; # access the session id from the response object $sid = $response->sid;
The session id (sid) is stored internally in the client for future authentication so there is no need to pass it explicitly
# add a folder group
$response = $client->add_folder_group({
name => 'iThenticate',
});
$folder_group_id = $response->id;
# list folder groups
$response = $client->list_folder_groups;
# returns an array reference of hash references holding the folder group data owned by the api user
$folder_groups = $response->groups;
# Example response data:
# $folder_groups->[0] = { id => 1, name => 'First Folder Group' };
# returns all the folders in a group
$response = $client->group_folders({ id => $folder_group_id });
# returns an array reference of folder hashes
$folders = $response->folders;
# Example response data:
# $folders->[0] = { id => 1,
# name => 'First Folder',
# group => {
# id => 1,
# name => 'First Folder Group', }, };
# remove a folder group
$response = $client->drop_group({ id => $folder_group_id });
# Returns a message on successful response, with no errors
if (!$response->errors &&
$response->messages->[0] eq "Group \"$folder_group_id\" removed") {
print "Group $folder_group_id dropped successfully\n";
}
# add a folder
$response = $client->add_folder({
name => 'API Specification',
description => 'Holds documentation referencing the iThenticate API',
folder_group => 79, # id of the folder group
exclude_quotes => 1, # 1 (true), or 0 (false)
add_to_index => 1, # 1 (true), or 0 (false), needed if account has
# a private storage node
});
# returns the id of the newly created folder
$folder_id = $response->id;
# get a folder and related documents
$response = $client->get_folder({ id => $folder_id });
# see group_folders() for folder response data format
$folder = $response->folder;
# get the documents for this folder
$documents = $response->documents;
# Example document data
# $documents->[0] = { author_first => 'Jules', author_last => 'Varne',
# is_pending => 1, percent_match => '83.2',
# processed_time => '94.3', title => '10,000 Leagues Over The Sea',
# parts => $parts, uploaded_time => '2008-03-13 07:35:35 PST',
# id => 1, };
# Example document parts data
# $parts->[0] = { part_id => 1, doc_id => 1, score => '95.2', word => 456, };
# returns all the folders for a user $response = $client->list_folders(); # returns an array reference of folder hashes $folders = $response->folders; # see get_folder() for the response folder data example
# move a folder to the trash
$response = $client->trash_folder({ id => $folder_id });
print "Folder trashed ok!" if ( !$response->errors &&
$response->messages->[0] eq 'Moved to Trash' );
# submit a document
$response = $client->add_document({
title => 'Moby Dick',
author_first => 'Herman',
author_last => 'Melville',
filename => 'moby_dick.doc',
# binary content of document
# the client module will base64 and chunk it
# note - don't actually use backticks like shown here :)
upload => `cat moby_dick.doc`,
folder => 72, # folder id
# options 2 and 3 only available for accounts with private nodes
submit_to => 1, # 1 => 'Generate Report Only'
# 2 => 'to Document Repository Only'
# 3 => 'to Document Repository & Generate Report'
});
# get the newly created document id
$document_id = $response->id;
$document = $response->document;
# see get_folder() for the response data format for the document
# check the status of a document submission
$response = $client->get_document({
id => $document_id,
});
# access the document attributes from the response
$document_id = $response->id;
# returns an array reference of document part hash references
$document_parts = $document->{parts};
# see get_folder() for the document and document parts data formats
# move a document to the trash
$response = $client->trash_document({ id => $document_id });
# get an get report
$response = $client->get_report({
id => $document_part_id,
});
# see if the report is ready
if ( $response->errors && ( $response->status == 404 ) ) {
# the report may still be in progress
if ( $response->messages->[0] =~ m/report in progress/i ) {
print "Report is still being prepared, please try later\n";
} else {
print STDERR "Report not found found document part $document_part_id\n";
}
} else {
# report is ready, see WebService::iThenticate::Response for report object details
$report = $response->report;
$report_url = $report->{view_only_url};
# save the report content to disk
$grab_report = `wget --output-document=$HOME/reports/new.html $report_url`;
}
# get the account status $response = $client->get_account; $account_status = $response->account_status;
# add a user
$response = $client->add_user({
first_name => 'Joe',
last_name => 'User',
email => 'joe@user.com',
password => 'swizzlestick123',
});
$user_id = $response->id;
# update a user's information
$response = $client->put_user({
email => 'joeuser@gmail.com',
});
if ( $response->messages->[1] eq 'Email updated for user joeuser@gmail.com' ) {
print 'got the right message';
}
# delete a user from the account
$response = $client->drop_user({ id => $user_id });
print 'some errors occurred' if $response->errors;
# users listing
$response = $client->list_users;
# returns a an array reference of user data in hashes
$users = $response->users;
# Example user data format
# $users->[0] = { id => 1, email => 'jules@varne.com',
# first_name => 'Jules', last_name => 'Varne', };
To enable testing against the iThenticate live test API, set the following environment variables before running 'make test'.
IT_USERNAME IT_PASSWORD IT_API_URL
See your iThenticate account representative to obtain these credentials to the API testing environment.
If you receive an error back from the server that looks like 'mismatched tag' then you likely have an invalid url specified for IT_API_URL instead of an actual mismatched tag in the request xml.
Q: Why doesn't this code do X?
A: Because that feature hasn't been requested yet :)
Q: How is this module related to iThenticate::API::Client?
A: This module takes the place of iThenticate::API::Client in a more generally accepted namespace
WebService::iThenticate::Request, WebService::iThenticate::Response, RPC::XML, SOAP::Lite
Fred Moyer <fred@iparadigms.com>
Copyright 2008 iParadigms LLC
| WebService-iThenticate documentation | Contained in the WebService-iThenticate distribution. |
package WebService::iThenticate::Client; use strict; use warnings; our $VERSION = 0.10; use constant DEFAULT_URL => 'https://test.api.ithenticate.com:443/rpc'; ## no critic use URI; use RPC::XML::Client; use WebService::iThenticate::Request; use WebService::iThenticate::Response;
sub new { my ( $class, $args_ref ) = @_; # need some auth credentials to proceed die 'username needed to create new client object' unless $args_ref->{username}; die 'password needed to create new client object' unless $args_ref->{password}; # set defaults my $url = $args_ref->{url} || DEFAULT_URL; # canonicalize the url $url = URI->new( $url )->canonical; die "invalid url $url\n" unless $url; # create a new rpc client my $rpc_client = RPC::XML::Client->new( $url ); die "unable to create rpc client from url $url" unless $rpc_client; # make an object my %self; bless \%self, $class; # stash the auth object $self{auth} = { username => $args_ref->{username}, password => $args_ref->{password}, }; # stash the rpc object $self{rpc_client} = $rpc_client; return \%self; } ## end sub new
sub credentials { my ( $self, $args ) = @_; my $realm = $args->{realm} || die 'no realm'; my $username = $args->{username} || die 'no username'; my $password = $args->{password} || die 'no password'; return $self->{rpc_client}->credentials( $realm, $username, $password ); }
sub login { my $self = shift; # we don't use _dispatch_request here because we set the sid as the authentication token my $request = WebService::iThenticate::Request->new( { method => 'login', auth => $self->{auth}, } ); die 'unable to create login request' unless $request; my $response = $self->_make_request( $request ); # check for errors return $response if $response->errors; if ( my $sid = $response->sid ) { # successful login, stash the sid for future auth $self->{auth} = $sid; } return $response; } ## end sub login
sub add_folder_group { my ( $self, $args ) = @_; return $self->_dispatch_request( 'group.add', $args ); }
sub list_folder_groups { return shift->_dispatch_request( 'group.list' ); }
sub group_folders { my ( $self, $args ) = @_; return $self->_dispatch_request( 'group.folders', $args ); }
sub drop_group { my ( $self, $args ) = @_; return $self->_dispatch_request( 'group.drop', $args ); }
sub add_folder { my ( $self, $args ) = @_; return $self->_dispatch_request( 'folder.add', $args ); }
sub get_folder { my ( $self, $args ) = @_; return $self->_dispatch_request( 'folder.get', $args ); }
sub list_folders { my ( $self, $args ) = @_; return $self->_dispatch_request( 'folder.list', $args ); }
sub trash_folder { my ( $self, $args ) = @_; return $self->_dispatch_request( 'folder.trash', $args ); }
sub add_document { my ( $self, $args ) = @_; $args->{uploads}->[0] = RPC::XML::struct->new( { title => RPC::XML::string->new( delete $args->{title} ), author_first => RPC::XML::string->new( delete $args->{author_first} ), author_last => RPC::XML::string->new( delete $args->{author_last} ), filename => RPC::XML::string->new( delete $args->{filename} ), upload => RPC::XML::base64->new( delete $args->{upload} ), } ); return $self->_dispatch_request( 'document.add', $args, 1 ); }
sub get_document { my ( $self, $args ) = @_; return $self->_dispatch_request( 'document.get', $args ); }
sub trash_document { my ( $self, $args ) = @_; return $self->_dispatch_request( 'document.trash', $args ); }
sub get_report { my ( $self, $args ) = @_; return $self->_dispatch_request( 'report.get', $args ); }
sub get_account { return shift->_dispatch_request( 'account.get' ); }
sub add_user { my ( $self, $args ) = @_; return $self->_dispatch_request( 'user.add', $args ); }
sub put_user { my ( $self, $args ) = @_; return $self->_dispatch_request( 'user.put', $args ); }
sub drop_user { my ( $self, $args ) = @_; return $self->_dispatch_request( 'user.drop', $args ); }
sub list_users { return shift->_dispatch_request( 'user.list' ); } # internal dispatch method to dispatch common requests sub _dispatch_request { my ( $self, $method, $args, $novalidate ) = @_; my $request = WebService::iThenticate::Request->new( { method => $method, auth => { sid => $self->{auth} }, req_args => $args, novalidate => $novalidate, } ); die "unable to create $method request" unless $request; my $response = $self->_make_request( $request ); return $response; } # internal dispatch method which makes the request based # on what transport mechanism we are using, rpc, soap, etc. sub _make_request { my ( $self, $request ) = @_; die 'need a request object' unless $request; my $response = $self->{rpc_client}->send_request( $request->{rpc_request} ); # When no connection can be made RPC::XML returns a string (error) if ( ref( \$response ) eq 'SCALAR' ) { die "Error: $response\n"; } # else check for RPC::XML::fault elsif ( $response->isa( 'RPC::XML::fault' ) ) { require Data::Dumper; die sprintf( "Error code: %s\nError string: %s\nRequest object: %s\n", $response->{faultCode}->value, $response->{faultString}->value, Data::Dumper::Dumper( $request ), ); # if it isn't a fault and not a struct it is an unknown error } elsif ( ref( $response ) ne 'RPC::XML::struct' ) { # unknown response require Data::Dumper; die 'unknown response returned, unable to handle: ' . Data::Dumper::Dumper( $response ); } # at this point we have a valid response # transform the response to an object my $ithenticate_response = WebService::iThenticate::Response->_new( $response ); ## no critic return $ithenticate_response; } ## end sub _make_request
1;