yankel
yankel

Reputation: 145

I can't connect using an api

I'm quite new to API's so I don't know if this should be more straight forward.

I write the following perl script

use strict;
use  LWP::UserAgent;
require HTTP::Request;

my $request = HTTP::Request->new(GET => 'http://api.elsevier.com/content/ev/results?apiKey=1234&query=stress&database=c&updateNumber=1&pageSize=1');

my $ua = LWP::UserAgent->new;
my  $response = $ua->request($request);

then when I get my response and print it in the debugger I get the following

HTTP::Response=HASH(0x9aedff8)
   '_content' => '{"service-error":{"status":{"statusCode":"AUTHENTICATION_ERROR","statusText":"Requestor configuration settings insufficient for access to this resource."}}}'
   '_headers' => HTTP::Headers=HASH(0x9aedfe8)
      'allow' => 'GET'
      'client-date' => 'Wed, 29 Mar 2017 08:08:25 GMT'
      'client-peer' => '198.185.19.118:80'
      'client-response-num' => 1
      'content-length' => 156
      'content-type' => 'application/json;charset=UTF-8'
      'date' => 'Wed, 29 Mar 2017 08:08:24 GMT'
      'p3p' => 'CP="IDC DSP LAW ADM DEV TAI PSA PSD IVA IVD CON HIS TEL OUR DEL SAM OTR IND OTC"'
      'server' => 'api.elsevier.com  9999'
      'vary' => 'Origin'
      'x-cnection' => 'close'
      'x-els-apikey' => 'e688c9db4db0386581dbe4c4dda46164'
      'x-els-reqid' => '0000015b190d89fe-a0d0'
      'x-els-status' => 'AUTHENTICATION_ERROR(Requestor configuration settings insufficient for access to this resource.)'
      'x-els-transid' => 'cbf787b4-d171-4e35-8237-8cab3c931205'
      'x-re-ref' => '1 1490774904423414'
   '_msg' => 'Forbidden'
   '_protocol' => 'HTTP/1.1'
   '_rc' => 403
   '_request' => HTTP::Request=HASH(0x9fc3000)
      '_content' => ''
      '_headers' => HTTP::Headers=HASH(0x9ae73e0)
         'user-agent' => 'libwww-perl/5.831'
      '_method' => 'GET'
      '_uri' => URI::http=SCALAR(0x9e25188)
         -> 'http://api.elsevier.com/content/ev/results?apiKey=e688c9db4db0386581dbe4c4dda46164&query=stress&database=c&updateNumber=1&pageSize=1'
      '_uri_canonical' => URI::http=SCALAR(0x9e25188)
         -> REUSED_ADDRESS

one of the notable lines is

x-els-status' => 'AUTHENTICATION_ERROR(Requestor configuration settings     insufficient for access to this resource.)'

I don't know how to get a proper response text. I tried searching their websites for examples, but I can't seem to get it. as well I'm not sure if the key is only for scopus but not engineering village which I'm trying to use.

There website is here. https://dev.elsevier.com/index.html?utm_expid=89327795-0.AtRZzToKQ2u1mZEyQ3n7OQ.0&utm_referrer=https%3A%2F%2Fdev.elsevier.com%2Ftecdoc_ev_retrieval_request.html

any help would be appreciated

Upvotes: 0

Views: 805

Answers (1)

simbabque
simbabque

Reputation: 54371

To get the text out of your response, you need to call the $response->decoded_content method. That will give you the JSON string that you can see in _content in your debug output. I've indented it to make it easier to read.

{
   "service-error" : {
      "status" : {
         "statusCode" : "AUTHENTICATION_ERROR",
         "statusText" : "Requestor configuration settings insufficient for access to this resource."
      }
   }
}

You can use the JSON module to decode this into a Perl data structure.

use JSON 'from_json';

my $res = $ua->request($req);
my $json = from_json( $res->decoded_content );

The error message you get back clearly states that you are not authenticated properly. I've looked at this guide from the documentation you mentioned. It seems that the apiKey URL param works, if you have the right type of account. You should check with whoever made that account for you, or if that was you and you're not sure, the account manager at that service that is working with you. They'll tell you if you are using the right API key, and if this method of authentication works for you.

Since this API also offers to use a custom header X-ELS-APIKey: [apikey] for the authentication I would suggest using that. Your API key is a secret, and you shouldn't share it with anyone. It's like a password. If you put it into the URL, it might show up in log files. But as a header, it does usually not.

This is how you add a custom header to an HTTP request. Make sure you don't have the apiKey URL param any more if you do this.

my $req = HTTP::Request->new( GET => $url ); # no apiKey=123 here!
$req->header( 'X-ELS-APIKey' => 123 );

Now as a last step, you should check the HTTP response code of the response. A 200 (or most other codes that start with 2) means the request was successful. The 403 that you are getting back means unauthorized, which also hints at that you are not authenticated correctly.

Since it seems that this API returns JSON in both success and failure cases, you might need to decode it for both. If you care to examine the failure response, that makes sense. If not, you can skip that part. To do this, use $res->is_success, which is also used in the synopsis of the LWP::UserAgent documentation.

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use JSON 'from_json';

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new( GET => 'http://api.elsevier.com/content/ev/results?query=stress&database=c&updateNumber=1&pageSize=1' );
$req->header( 'X-ELS-APIKey' => 123 );

if ($req->is_success) {
    my $json = from_json( $res->decoded_content );
    # ... do stuff with the response
} else {
    # something went wrong
}

Upvotes: 2

Related Questions