Using scripting languages
- 1 Overview
- 1.1 curl
- 1.2 Python
- 1.2.1 Python module for Okapi queries
- 1.2.2 Jupyter Notebooks
- 1.3 Perl
- 1.3.1 Authentication: Get OKAPI Token
- 1.3.2 Get all users
- 1.4 Bruno
- 1.5 Postman
- 1.6 NodeJS
Overview
This page provides information on using scripting languages to automate calls to the FOLIO REST API (OKAPI/Kong/Sidecar). It uses the snapshot server as an example.
Please improve the code examples and extend this page to cover additional languages and use cases.
curl
See dedicated curl page.
Python
Python module for Okapi queries
Members of EBSCO's FSE team have published a python module for FOLIO - https://pypi.org/project/folioclient/ – https://github.com/folio-fse/FolioClient – that is a wrapper around common API calls.
Jupyter Notebooks
Jupyter Notebooks (https://jupyter.org/) are common, user-friendly tools that community members are learning to use to query FOLIO for data.
The advantage of Jupyter Notebooks is that you don't have to install anything on your computer to write programs, they are easy to publish and share, and their format makes it intuitive to document what you are doing as you go.
An example notebook has been shared by @Lisa Sjögren (EBSCO) - https://colab.research.google.com/drive/12geGqqIEfLsEpxYlnt6m0M7ARQG64jIH?usp=sharing - this example is published on Google's Colaboratory platform, which is based on Jupyter Notebooks (https://colab.research.google.com/).
See Getting started with Jupyter Notebooks
Perl
Use the LWP::UserAgent module to simplify REST calls:
use LWP::UserAgent;
Authentication: Get OKAPI Token
This code will retrieve the token that is required for communication with the server:
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use LWP::UserAgent;
use HTTP::CookieJar::LWP;
my $ua = LWP::UserAgent->new(
cookie_jar => HTTP::CookieJar::LWP->new,
);
my $host = 'folio-snapshot-okapi.dev.folio.org';
my $x_okapi_token = '';
my $res = $ua->post(
'https://' . $host . '/authn/login-with-expiry',
'content-type' => 'application/json',
'x-okapi-tenant' => 'diku',
'Content' => '{ "username": "diku_admin",
"password": "admin" }',
);
if ( $res->is_success ) {
if ( $res->status_line =~ /^201 / ) {
my $ref = $ua->cookie_jar;
my %cookies = %$ref;
$x_okapi_token = $cookies{store}{$host}{'/'}{folioAccessToken}{value};
}
} else {
say STDERR 'failed:';
say STDERR $res->status_line;
say STDERR $res->decoded_content;
}
die 'No okapi token retrieved' unless $x_okapi_token;
say 'Auth token: ' . $x_okapi_token;
exit 0;
__END__
Get all users
This code will use the token to retrieve all active users, retrieving the records in batches of 10, until all the records are retrieved:
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use JSON;
use Data::Dumper;
use LWP::UserAgent;
use HTTP::CookieJar::LWP;
my $ua = LWP::UserAgent->new(
cookie_jar => HTTP::CookieJar::LWP->new,
);
my $host = 'folio-snapshot-okapi.dev.folio.org';
my $x_okapi_token = '';
my $res = $ua->post(
'https://' . $host . '/authn/login-with-expiry',
'Accept' => 'text/plain',
'content-type' => 'application/json',
'x-okapi-tenant' => 'diku',
'x-okapi-token' => '',
'Content' => '{ "username": "diku_admin",
"password": "admin" }',
);
if ( $res->is_success ) {
if ( $res->status_line =~ /^201 / ) {
my $ref = $ua->cookie_jar;
my %cookies = %$ref;
$x_okapi_token = $cookies{store}{$host}{'/'}{folioAccessToken}{value};
}
} else {
say STDERR 'failed:';
say STDERR $res->status_line;
say STDERR $res->decoded_content;
}
die 'No okapi token retrieved' unless $x_okapi_token;
my @folioUsers;
my $totalRecords = 0;
my $offset = 0;
{
do {
( $offset, $totalRecords, @folioUsers ) = getUsers( $offset, @folioUsers );
say $offset;
} while ( $offset < $totalRecords );
}
say 'TotalRecords: ', $totalRecords;
say 'Records retrieved: ', scalar @folioUsers;
say Dumper @folioUsers;
exit 0;
# -------------- subroutines ----------------------#
sub getUsers {
my ( $offset, @folioUsers ) = @_;
say 'offset: ', $offset;
my $jsonString;
$res = $ua->get(
'https://folio-snapshot-okapi.dev.folio.org/users?limit=10&query=(active=="true")&offset=' . $offset,
'Accept' => 'text/plain',
'content-type' => 'application/json',
'x-okapi-tenant' => 'diku',
'x-okapi-token' => "$x_okapi_token"
);
if ( $res->is_success ) {
if ( $res->status_line ne '200 OK' ) {
say STDERR 'not ok:';
say STDERR $res->status_line;
say STDERR $res->decoded_content;
return;
}
$jsonString = $res->decoded_content;
} else {
say STDERR 'failed:';
say STDERR $res->status_line;
say STDERR $res->decoded_content;
return;
}
my $ref = JSON->new->decode( $jsonString );
my %hash = %$ref;
my $totalRecords = $hash{'totalRecords'};
my @users = $hash{users};
foreach ( @users ) {
my @records = @$_;
foreach my $ref ( @records ) {
push @folioUsers, JSON->new->encode( $ref );
$offset++;
}
}
return $offset, $totalRecords, @folioUsers;
}
__END__
Bruno
See dedicated Bruno page.
Postman
See the dedicated Postman pages, including the Postman and RTR setup page.
NodeJS
Use the https module:
import { default as https } from 'https';
Authentication: Get OKAPI token
This code can be used within a NodeJS app to retrieve the token that is required for communication with the server:
async function get_okapi_token(username, password, hostname, x_okapi_tenant, https, res) {
function getPromise_token(username, password, hostname, x_okapi_tenant, https, res) {
return new Promise((resolve, reject) => {
const data = JSON.stringify({
username: username,
password: password
});
const options = {
hostname: hostname,
path: '/authn/login-with-expiry',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
'Content-Length': data.length,
'x-okapi-tenant': x_okapi_tenant,
}
};
const req = https.request(options, res => {
const cookie = res.headers['set-cookie'][0];
const cs = cookie.split(';');
for (let i = 0; i < cs.length; i++) {
let c = cs[i];
const ts = c.split('=');
if (ts[0] == 'folioAccessToken') {
resolve(ts[1]);
}
}
});
req.on('error', error => {
reject(error);
});
req.write(data);
req.end();
});
}
async function get_token(username, password, hostname, x_okapi_tenant, https, res) {
try {
let http_promise = getPromise_token(username, password, hostname, x_okapi_tenant, https, res);
let x_okapi_token = await http_promise;
return x_okapi_token;
}
catch (error) {
console.log(error);
log.info(error);
}
}
let x_okapi_token = await get_token(username, password, hostname, x_okapi_tenant, https, res);
if (x_okapi_token === '') {
res.locals.status = 'alert-danger';
let msg = 'Error: failed to retrieve token';
log.error(msg);
res.send('Error: ' + msg);
return;
}
return x_okapi_token;
}
const username = 'diku_admin';
const password = 'admin';
const hostname = 'folio-snapshot-okapi.dev.folio.org';
const tenant = 'diku';
let x_okapi_token = await get_okapi_token(username, password, hostname, tenant, https, res);
console.log(x_okapi_token);