view aresite2/RestAPI.pl @ 3:755662977150 draft

Uploaded repo
author jfallmann
date Wed, 01 Feb 2017 09:59:29 -0500
parents
children
line wrap: on
line source

#!/usr/bin/env perl

#Copyright (C) 2015 Joerg Fallmann E<lt>joerg.fallmann@univie.ac.atE<gt>
#This library is free software; you can redistribute it and/or modify
#it under the same terms as Perl itself, either Perl version 5.10.0 or,
#at your option, any later version of Perl 5 you may have available.
#This program is distributed in the hope that it will be useful, but
#WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#General Public License for more details.
#With code fragments from https://github.com/Ensembl/ensembl-rest/wiki/Example-Perl-Client
#Last changed Time-stamp: <2015-10-30 15:25:52> by joerg.fallmann@univie.ac.at

########## Load Modules ##########
#### We use HTTP::Tiny simple to send a GET request to aresite2
#### The returned JSON object is parsed with the module JSON
#### Data::Dumper is used to print the returned hash ref
use strict;
use warnings;
use HTTP::Tiny;
use Time::HiRes;
#use LWP::Simple;
use JSON qw( decode_json );
use Data::Dumper;
use Getopt::Long qw( :config posix_default bundling no_ignore_case );
use Pod::Usage;

########## MAIN ##########

########## Define variables ##########
my ($VERBOSE, $species, @motifs, $gene, $list);

########## Process Commandline ##########
Getopt::Long::config('no_ignore_case');
pod2usage(-verbose => 0)
	unless GetOptions(
		"species|s=s" => \$species,
		"motifs|o=s"  => \@motifs,
		"gene|g=s"	  => \$gene,
		"help|h"			=> sub{pod2usage(-verbose => 1)},
		"man|m"				=> sub{pod2usage(-verbose => 2)},      
		"verbose"			=> sub{ $VERBOSE++ }
	);

########## Get PID and print command ##########
my $pid = $$;
(my $job = `cat /proc/$pid/cmdline`)=~ s/\0/ /g;
print STDERR "You called ",$job,"\n";

########## Send request ##########
my $http = HTTP::Tiny->new();
### Define url
my $url = 'http://rna.tbi.univie.ac.at/AREsite2/api/';
my $urltest = 'https://rest.ensembl.org/info/species?content-type=application/json';
my $global_headers = { 'Content-Type' => 'application/json' };
my $last_request_time = Time::HiRes::time();
my $request_count = 0;

### Define gene, species, and a comma-separated list of motifs
$species = "Homo_sapiens" unless (defined $species);
$list = join(",",split(/,/,join(",",@motifs))) if (@motifs);
$list = "ATTTA" unless (defined $list);
$gene = "cxcl2" unless (defined $gene);

### Fetch response and create hash ref from response
my $aresite = run();

### print hash dump to STDOUT
print Dumper (\$aresite);

### Check for request errors
print STDOUT "ERROR:\t".$aresite->{message}."\n" if (defined $aresite->{reason});

### print some values to STDOUT if no error
print STDOUT "GENE: $aresite->{id}\tENSEMBL: $aresite->{ensid}\tCoords: $aresite->{coordinates}\n" unless (defined $aresite->{reason});


sub run {

	### Create query
	my $query = join("&","?query=$gene","species=$species","list=$list");
	$url .= $query;
	my $aresite = perform_json_action($url);
	return $aresite;
}

sub perform_json_action {
	my ($endpoint) = @_;
	my $headers = $global_headers;
	my $content = perform_rest_action($endpoint, $headers);
	return {} unless $content;
	my $json = decode_json($content);
	return $json;
}

sub perform_rest_action {
	my ($endpoint, $headers) = @_;
	$headers ||= {};
	$headers->{'Content-Type'} = 'application/json' unless exists $headers->{'Content-Type'};
	if($request_count == 15) { # check every 15
		my $current_time = Time::HiRes::time();
		my $diff = $current_time - $last_request_time;
		# if less than a second then sleep for the remainder of the second
		if($diff < 1) {
			Time::HiRes::sleep(1-$diff);
		}
		# reset
		$last_request_time = Time::HiRes::time();
		$request_count = 0;
	}
	
	my $url = $endpoint;
	print STDERR "Fetching from ",$url,"\n";
	my $response = $http->get($url, {headers => $headers});
	my $status = $response->{status};
	if(!$response->{success}) {
		# Quickly check for rate limit exceeded & Retry-After (lowercase due to our client)
		if($status == 429 && exists $response->{headers}->{'retry-after'}) {
			my $retry = $response->{headers}->{'retry-after'};
			Time::HiRes::sleep($retry);
			# After sleeping see that we re-request
			return perform_rest_action($endpoint, $headers);
		}
		else {
			my ($status, $reason) = ($response->{status}, $response->{reason});
			die "Failed for $endpoint! Status code: ${status}. Reason: ${reason}\n";
		}
	}
	$request_count++;
	if(length $response->{content}) {
		return $response->{content};
	}
	return;
}