Bio-BioVeL

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

Examples/Nexus_MultiplePartitions.nex
Examples/Nexus_SimplePartition.nex
Examples/TaxaDataExample.nex
Examples/TaxaMetadataExample.json
Examples/TaxaMetadataExample.tsv
Examples/TaxaTreeExample.dnd
Examples/treebase-record.xml
Examples/TreeMetadata.tsv
Examples/TreesExample.xml
lib/Bio/BioVeL.pm
lib/Bio/BioVeL/AsynchronousService.pm
lib/Bio/BioVeL/AsynchronousService/Mock.pm
lib/Bio/BioVeL/AsynchronousService/TNRS.pm
lib/Bio/BioVeL/Service.pm
lib/Bio/BioVeL/Service/NeXMLExtractor.pm
lib/Bio/BioVeL/Service/NeXMLMerger.pm
lib/Bio/BioVeL/Service/NeXMLMerger/CharSetReader.pm
lib/Bio/BioVeL/Service/NeXMLMerger/CharSetReader/nexus.pm
lib/Bio/BioVeL/Service/NeXMLMerger/CharSetReader/text.pm
lib/Bio/BioVeL/Service/NeXMLMerger/DataReader.pm
lib/Bio/BioVeL/Service/NeXMLMerger/DataReader/fasta.pm
lib/Bio/BioVeL/Service/NeXMLMerger/DataReader/nexus.pm
lib/Bio/BioVeL/Service/NeXMLMerger/DataReader/phylip.pm

README.md  view on Meta::CPAN

`metaformat={tsv|JSON|csv}`, `charsetformat={txt}`

Output
------
* A subset of the NeXML data in the requested format, with a separate download of the 
metadata, likewise in the requested format.

Service deployment
==================
We deploy the services as [mod_perl](http://perl.apache.org) handlers, which means that for 
synchronous services (i.e. everything is done in one request/response cycle) no forking is 
done at all. For asynchronous servers, the service class doesn't have to keep track of its 
session: the superclass keeps track of serializing and de-serializing the job object 
between requests.

Links
=====
* [Naturalis BioVeL github repo](https://github.com/naturalis/biovel-nbc)
* [BioVeL](http://biovel.eu)
* [BiodiversityCatalogue](http://biodiversitycatalogue.org)
* [NeXML](http://nexml.org)
* [Taverna](http://taverna.org.uk)

lib/Bio/BioVeL/AsynchronousService.pm  view on Meta::CPAN

package Bio::BioVeL::AsynchronousService;
use strict;
use warnings;
use File::Path 'make_path';
use Scalar::Util 'refaddr';
use Bio::BioVeL::Service;
use Digest::MD5 'md5_hex';
use Apache2::Const '-compile' => qw'OK REDIRECT';
use Proc::ProcessTable;
use base 'Bio::BioVeL::Service';

# status constants
use constant RUNNING => 'running';
use constant DONE    => 'done';
use constant ERROR   => 'error';

=head1 NAME

Bio::BioVeL::AsynchronousService - base class for asynchronous web services

=head1 SYNOPSIS

 use Bio::BioVeL::AsynchronousService::Mock; # example class
 
 # this static method returns a writable directory into which
 # service objects are persisted between request/response cycles
 my $wd = Bio::BioVeL::AsynchronousService::Mock->workdir;

 # when instantiating objects, values for the 'parameters' that are defined
 # in their constructors can be provided as named arguments
 my $mock = Bio::BioVeL::AsynchronousService::Mock->new( 'seconds' => 1 );

 # every async service has a record of when it started
 my $epoch_time = $mock->timestamp;

 # can be RUNNING, ERROR or DONE
 if ( $mock->status eq Bio::BioVeL::AsynchronousService::DONE ) {
 	print $mock->response_body;
 }

=head1 DESCRIPTION

Asynchronous services need to subclass this class and implement at least the following
methods: C<launch> and C<response_body>. The parent class makes sure that launch()
forks off a process and returns immediately with enough information, stored as object
properties, so that update() can check how things are going and update the status(). 
Once the status set to C<DONE>, C<response_body> is executed to generate the output.

Successful implementations are likely going to have simple, serializable object properties
that allow a newly de-serialized object (i.e. during the next polling cycle) to probe
the process table or the job directory to check the status.

=head1 METHODS

lib/Bio/BioVeL/AsynchronousService/Mock.pm  view on Meta::CPAN

package Bio::BioVeL::AsynchronousService::Mock;
use strict;
use warnings;
use Bio::BioVeL::AsynchronousService;
use base 'Bio::BioVeL::AsynchronousService';

=head1 NAME

Bio::BioVeL::AsynchronousService::Mock - example asynchronous service

=head1 DESCRIPTION

This dummy service runs the 'sleep' shell command for the provided number
of seconds, then returns with a simple text message.

=head1 METHODS

=over

lib/Bio/BioVeL/AsynchronousService/Mock.pm  view on Meta::CPAN

the service should sleep for.

=cut

sub new {
	shift->SUPER::new( 'parameters' => [ 'seconds' ], @_ );
}

=item launch

Runs the shell's C<sleep> command to demonstrate asynchronous operation.
Updates the status as needed to indicate success or failure.

=cut

sub launch {
	my $self = shift;
	if ( system("sleep", ( $self->seconds || 2 ) ) ) {
		$self->status( Bio::BioVeL::AsynchronousService::ERROR );
		$self->lasterr( $? );
	}
	else {
		$self->status( Bio::BioVeL::AsynchronousService::DONE );
	}
}

=item response_body

Returns a simple text string that specifies how long the process has slept for.

=cut

sub response_body { "I slept for ".shift->seconds." seconds" }

lib/Bio/BioVeL/AsynchronousService/TNRS.pm  view on Meta::CPAN

package Bio::BioVeL::AsynchronousService::TNRS;
use strict;
use warnings;
use Bio::BioVeL::AsynchronousService;
use base 'Bio::BioVeL::AsynchronousService';

=head1 NAME

Bio::BioVeL::AsynchronousService::TNRS - wrapper for the SUPERSMART TNRS service

=head1 DESCRIPTION

B<NOTE>: this service is untested, it is a work in progress. It is meant to show
how the scripts of the L<http://www.supersmart-project.org> could be executed as
asynchronous web services.

=head1 METHODS

=over

=item new

The constructor specifies one object property: the location of the input C<names>
list.

lib/Bio/BioVeL/AsynchronousService/TNRS.pm  view on Meta::CPAN

	# SUPERSMART_HOME needs to be known and accessible to the httpd process
	my $script = $ENV{'SUPERSMART_HOME'} . '/script/supersmart/mpi_write_taxa_table.pl';
	
	# fetch the input file
	my $readfh  = $self->open_handle( $self->names );	
	open my $writefh, '>', $infile;
	print $writefh $_ while <$readfh>; 
	
	# run the job
	if ( system( $script, '-i' => $infile, ">$outfile", "2>$logfile" ) ) {
		$self->status( Bio::BioVeL::AsynchronousService::ERROR );
		$self->lasterr( $? );
	}
	else {
		$self->status( Bio::BioVeL::AsynchronousService::DONE );
	}
}

=item response_location

B<NOTE>: this is an untested feature. The idea is that child classes can re-direct
the client to an alternate location with, e.g. the most important output file or a
directory listing of files.

=cut

lib/Bio/BioVeL/Service.pm  view on Meta::CPAN

	'-level' => INFO,
	'-class' => [ 
		'Bio::BioVeL::Service::NeXMLMerger', 
		'Bio::BioVeL::Service::NeXMLExtractor' 
	]
);
our $AUTOLOAD;

=head1 NAME

Bio::BioVeL::Service - base class for synchronous web services

=head1 DESCRIPTION

The BioVeL API makes a distinction between "synchronised" and "asynchronous" services.
Synchronised services produce their final result within a single HTTP request/response
cycle by generating a response_body that is returned to the client at the end of the
cycle. Asynchronous services produce a result at the end of a longer running, forked 
process, which needs to be tracked between request/response cycles.

All concrete service classes need to inherit from either one of these service type 
superclasses (L<Bio::BioVeL::Service> or L<Bio::BioVeL::AsynchronousService>) so that
all the bookkeeping (processing request parameters, managing forked processes) is 
taken care of and the concrete child class only needs to worry about producing its
result.

=head1 METHODS

=over

=item new

t/async.t  view on Meta::CPAN

#!/usr/bin/perl
use strict;
use warnings;
use File::Temp 'tempdir';
use Test::More 'no_plan';
use Scalar::Util 'looks_like_number';

BEGIN { use_ok('Bio::BioVeL::AsynchronousService::Mock') }

$ENV{'BIOVEL_HOME'} = tempdir( 'CLEANUP' => 1 );

# $TEMP/Bio/BioVeL/AsynchronousService/Mock
ok( -d Bio::BioVeL::AsynchronousService::Mock->workdir );

my $new = Bio::BioVeL::AsynchronousService::Mock->new( 'seconds' => 1 );
isa_ok( $new, 'Bio::BioVeL::AsynchronousService' );

ok( looks_like_number $new->timestamp );

ok( $new->status eq Bio::BioVeL::AsynchronousService::RUNNING );



( run in 0.401 second using v1.01-cache-2.11-cpan-0d8aa00de5b )