CPAN Testers is only made possible with the support of our sponsors.
For more information on sponsoring, please visit the I ♥ CPAN Testers website.

Upgrade Notice

The CPAN Testers Blog site has been upgraded since you last accessed the site. Please press the F5 key or CTRL-R to refresh your browser cache to use the latest javascript and CSS files.

News & Views

Posted by Barbie
on 8th May 2014

As part of the QA Hackathon in Lyon, one of my aims was to produce an API to the CPAN Testers reports. More specifically, provide the ability to retrieve a copy of a report as it was stored in the Metabase.

Although reports are available on the Reports site, they are a reconstruction of the report, as if it was an email. This was how reports were originally sent, but since 2010, the Metabase recieves each report as a JSON object, which it then saves with further references to other facts. When the Generator retrieves the JSON object it stores a copy before parsing the contents for the cpanstats database.

The reconstructed report pages might be enough to glean enough information to figure out the immediate problem, but sometimes it requires more long term analysis, which is where the Analysis site comes in. Currently Andreas scrapes the reports pages, which although mostly works, in the future, when we start to include much more metadata, this isn't going to be suitable. As such, returning a hash or JSON object is needed.

During the QA Hackathon I did manage to write the server side software to provide the API needed. However, I didn't get to finish the client side software. Over the following weeks I cleaned up the code, added some tests and finally CPAN-Testers-WWW-Reports-Query-Report was released to the world.

The module does a little more than I first planned, but that is mainly because I wanted people to be able to use the report returned in any way the see fit. So you can retrieve a Metabase::Fact object (the default), a Perl hash representation or the original JSON object. All that is required is the report Metabase GUID or the cpanstats ID. So how does it work?

The Options

You don't need to provide any options, as the module will use some defaults. Below is an example of the options, which incidentally happen to be the default options:

my %options = (
    as_json => 0,
    as_hash => 0,
    host    => 'http://cpantesters.org'
);

I allow you to defined the host, just in case we supply a similar API from the Metabase directly, or a new mirror (possibly even a local one) can support the same API.

The Object

Now we establish the object. If an options hash isn't provided, the defaults will be used.

my $query = CPAN::Testers::WWW::Reports::Query::Report->new( %options );

The Report

# get by cpanstats ID
my $result = $query->report( report => 40000000 );
# get by Metabase GUID
$result = $query->report( report => '0b3fd09a-7e50-11e3-9609-5744ee331862' );

The report method also allows you to override the as_json and as_hash attributes, should you need to retrieve the report slightly differently in some cases.

# force return as JSON
my $result = $query->report( report => 40000000, as_json => 1 );

The Last Error

In the event something goes wrong, you can hopefully get some information about what the problem was via the error() method. I can't guarantee it will be the whole picture, but hopefully it will give you some indication of what the problem might be.

my $error = $query->error;

The Conclusion

If you have suggestions for improvements, or spot problems in the current code, please let me know. If you do use the code, whether for mash-ups or for personal analysis, it would be nice to hear you've found the module useful. You could even blog about it :)

Comments

error handling

Why did you make error handling optional instead of throwing an exception?

It's happens far too easy to forget to check ->error after every method call and makes the code unnecessary long an unreadable.

Posted by Alexander Hartmaier (abraxxa) on Friday, 9th May 2014


error handling - check for undef

Err, it's not necessary to check ->error after every method call, all you have to do is check the returned value for definedness, just like with many other APIs.  If it's undefined, well, *then* you check ->error to get the actual error message.

Posted by Peter Pentchev on Friday, 16th May 2014


Add A Comment

Comments now have limited rich text support thanks to TinyMCE.

*
*