[Bio] / FigKernelPackages / RASTserver.pm Repository:
ViewVC logotype

Annotation of /FigKernelPackages/RASTserver.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.23 - (view) (download) (as text)

1 : olson 1.1 package RASTserver;
2 :    
3 :     #
4 :     # This is a SAS Component
5 :     #
6 :    
7 :     use LWP::UserAgent;
8 : olson 1.19 #use LWP::Debug qw(+trace +debug +conns);
9 : olson 1.1 use Data::Dumper;
10 :     use YAML;
11 : olson 1.18 use File::Basename;
12 : parrello 1.20 use ClientThing;
13 : olson 1.18 use Cwd 'abs_path';
14 : olson 1.1
15 : olson 1.5 $YAML::CompressSeries = 0;
16 :    
17 : olson 1.1 use strict;
18 :    
19 : disz 1.13
20 :     =head1 RAST Submission Server Function Object
21 :    
22 :     This file contains the functions and utilities used by the RAST Submission Server
23 :     . The various methods listed in the sections below represent
24 :     function calls direct to the server. These all have a signature similar to the
25 :     following.
26 :    
27 :     my $document = $rastObject->function_name($args);
28 :    
29 :     where C<$rastObject> is an object created by this module,
30 :     C<$args> is a parameter structure, and C<function_name> is the RAST
31 :     Server function name. The output document is a structure, generally a hash
32 :     reference, but sometimes a string or a list reference.
33 :    
34 :    
35 :     =head2 Constructor
36 :    
37 :     Use
38 :    
39 :     my $rastObject = RASTserver->new($username, $password);
40 :    
41 :     Where $username and $password are your RAST username and password.
42 :    
43 :    
44 :     =cut
45 :    
46 :    
47 :    
48 :    
49 : olson 1.1 sub new
50 :     {
51 : olson 1.11 my($class, $username, $password, $opts) = @_;
52 : olson 1.1
53 : parrello 1.20 my $server_url;
54 : olson 1.11 if ($opts->{-test})
55 :     {
56 :     $server_url = "http://servers.nmpdr.org/rast-test/server.cgi";
57 :     }
58 :     elsif ($opts->{-server})
59 :     {
60 :     $server_url = $opts->{-server};
61 :     }
62 : olson 1.1
63 :     my $self = {
64 : parrello 1.20 server_url => ClientThing::ComputeURL($server_url, 'rast_submit_server.cgi', 'rast'),
65 : olson 1.1 ua => LWP::UserAgent->new(),
66 :     username => $username,
67 :     password => $password,
68 :     };
69 :     $self->{ua}->timeout(20 * 60);
70 :    
71 :     return bless $self, $class;
72 :     }
73 :    
74 : disz 1.13 =head1 Primary Methods
75 :    
76 :     =head3 submit_RAST_job
77 :    
78 :     my $jobH = $rastObject->submit_RAST_job({
79 :    
80 : gdpusch 1.22 -taxonomyID => The NCBI taxonomy id | Domain => [Archaea | Bacteria | Virus]
81 : disz 1.15 -filetype => [Fasta|Genbank]
82 :     if Fasta && ! TaxonomyID
83 :     -geneticCode => [4 | 11]
84 :     -organismName => Name of the organism
85 :     -keepGeneCalls => [0 | 1],
86 :     -geneCaller => [RAST | Glimmer3],
87 :     -file => full path to the input file
88 : disz 1.13 }
89 :     );
90 :    
91 :     This method submits a job to the RAST server. It returns a hash of:
92 :    
93 :     {jobid} =id
94 :     {status} = [submitted|error]
95 :     {error_message} = message
96 :    
97 :     =cut
98 :    
99 :    
100 : olson 1.1 sub submit_RAST_job
101 :     {
102 : gdpusch 1.23 my ($self, $params) = @_;
103 :     my ($result, $error_string);
104 :    
105 :     my $user = $self->{username};
106 :     my $file = $params->{-file};
107 : disz 1.4 my $filetype = lc($params->{-filetype});
108 : gdpusch 1.23 my $tax_id = $params->{-taxonomyID};
109 :     my $domain = lc($params->{-domain});
110 : disz 1.4 my $organism = $params->{-organismName};
111 : gdpusch 1.23 my $keep = $params->{-keepGeneCalls};
112 : disz 1.4 my $genetic_code = $params->{-geneticCode};
113 : gdpusch 1.23 my $gene_caller = lc($params->{-geneCaller});
114 : disz 1.4
115 : gdpusch 1.23 my $is_euk_user = defined($FIG_Config::rast_euk_users)
116 :     && defined($FIG_Config::rast_euk_users->{$user})
117 :     && $FIG_Config::rast_euk_users->{$user};
118 :    
119 :     my %allowed_domains = map { $_ => 1 } (qw(Bacteria Archaea Viruses), ($is_euk_user ? q(Eukaryota) : ()));
120 :     my %allowed_codes = map { $_ => 1 } (4, 11, ($is_euk_user ? (1) : ()));
121 :    
122 : disz 1.4 if ($filetype ne "fasta" && $filetype ne "genbank") {
123 :     $error_string .= "-filetype not Fasta or Genbank\n";
124 :     }
125 : gdpusch 1.23
126 : olson 1.18 if ($tax_id) {
127 : disz 1.4 if ($tax_id =~ /\D/) {
128 :     $error_string .= "-taxonomyID must be numeric\n";
129 :     }
130 : olson 1.18 } elsif ($filetype ne 'genbank' ) {
131 : gdpusch 1.23 if (0 == grep { lc(substr($_,0,1)) eq lc(substr($domain,0,1)) } (keys %allowed_domains)) {
132 :     my @tmp = sort keys %allowed_domains;
133 :     $tmp[-1] = q(or ) . $tmp[-1];
134 :     my $tmp = join(q(, ), @tmp);
135 :     $error_string .= "-domain must be $tmp\n";
136 : disz 1.4 }
137 : gdpusch 1.23
138 :     if ($organism !~ m/^[A-Z][a-z]*\s+\S+/o) {
139 :     $error_string .= "-organismName is mandatory for non-GenBank submissions\n";
140 :     }
141 : disz 1.4 }
142 : gdpusch 1.23
143 : disz 1.4 if (!$file) {
144 :     $error_string .= "You must supply a file\n";
145 :     } else {
146 : gdpusch 1.23 if (! open( F, "<$file" )) {
147 :     $error_string .= "Invalid file path\n";
148 :     }
149 : disz 1.4 }
150 :     if (!defined($keep) || ($keep != 0 && $keep != 1)) {
151 :     $error_string .= "-keepGeneCalls must be 0 or 1\n";
152 :     }
153 : gdpusch 1.23
154 : disz 1.4 if ($filetype eq "fasta" && ! $tax_id) {
155 : gdpusch 1.23 if (!$genetic_code || (not $allowed_codes{$genetic_code})) {
156 :     my @tmp = sort { $a <=> $b } (keys %allowed_codes);
157 :     $tmp[-1] = q( or ) . $tmp[-1];
158 :     my $tmp = join(q(, ), @tmp);
159 :     $error_string .= "-geneticCode must be $tmp\n";
160 :     }
161 : disz 1.4 }
162 :     if ($gene_caller ne "rast" && $gene_caller ne "glimmer3") {
163 :     $error_string .= "-geneCaller must be RAST or Glimmer3\n";
164 :     }
165 : gdpusch 1.23
166 :    
167 : disz 1.4 if ($error_string) {
168 : olson 1.10 $result->{status} = 'error';
169 : disz 1.4 $result->{error_message} = $error_string;
170 :     return ($result);
171 :     }
172 : gdpusch 1.23
173 : disz 1.4 {
174 :     local $/;
175 :     undef $/;
176 :     $params->{-file} = <F>;
177 :     }
178 : olson 1.5 close(F);
179 : olson 1.1
180 :     return $self->run_query('submit_RAST_job', $params);
181 :     }
182 :    
183 : olson 1.3 sub get_contig_ids_in_project_from_entrez
184 :     {
185 :     my($self, $params) = @_;
186 :    
187 :     return $self->run_query('get_contig_ids_in_project_from_entrez', $params);
188 :     }
189 :    
190 : olson 1.5 sub get_contigs_from_entrez
191 :     {
192 :     my($self, $params) = @_;
193 :    
194 :     return $self->run_query('get_contigs_from_entrez', $params);
195 :     }
196 :    
197 : disz 1.13
198 :     =head3 status_of_RAST_job
199 :    
200 :     my $rastjobH = $rastObject->status_of_RAST_job({-job => \@jobs});
201 :    
202 : disz 1.14 Where @jobs is a list of jobs
203 : disz 1.13
204 :     The return value is a hash keyed by Jobid of
205 :    
206 :     {status} = Job Stage
207 :     {error_msg} = message
208 :     {verbose-status} = RAST Metadata
209 :    
210 :     =cut
211 :    
212 :    
213 :    
214 : olson 1.1 sub status_of_RAST_job
215 :     {
216 :     my($self, $params) = @_;
217 :    
218 :     return $self->run_query('status_of_RAST_job', $params);
219 :     }
220 :    
221 : disz 1.13
222 :     =head3 retrieve_RAST_job
223 :    
224 :     my $result = $rastObject->retrieve_RAST_job(-job => $jobid, -format => $format)
225 :    
226 :     where $jobid is the RAST id of the job and
227 :    
228 :     $format is one of:
229 :    
230 :     genbank (Genbank format)
231 :     genbank_stripped (Genbank with EC numbers removed)
232 :     embl (EMBL format)
233 :     embl_stripped (EMBL with EC numbers stripped)
234 :     gff3 (GFF3 format)
235 :     gff3_stripped (GFF3 with EC numbers stripped)
236 :     rast_tarball (gzipped tar file of the entire job)
237 :    
238 :     The return is a hash of
239 :    
240 :     {status} = ok|error
241 :     {file} = the downloaded file name
242 :     {error_msg} = The error message
243 :    
244 :     =cut
245 :    
246 :    
247 : olson 1.2 sub retrieve_RAST_job
248 :     {
249 :     my($self, $params) = @_;
250 :    
251 : olson 1.7 my $filehandle = delete $params->{-filehandle};
252 :    
253 :     my $cb = sub {
254 :     my($chunk) = @_;
255 :     print $filehandle $chunk;
256 :     };
257 :    
258 :     my $form = [function => 'retrieve_RAST_job',
259 :     args => YAML::Dump($params),
260 :     username => $self->{username},
261 :     password => $self->{password},
262 :     ];
263 :    
264 :     my $res = $self->{ua}->post($self->{server_url}, $form,
265 :     ':content_cb' => $cb,
266 :     );
267 :    
268 :     if ($res->is_success)
269 :     {
270 :     return { status => 'ok' };
271 :     }
272 :     else
273 :     {
274 : olson 1.19 return { status => 'error', error_msg => $res->status_line . $res->content };
275 : olson 1.7 }
276 :     }
277 : olson 1.2
278 : disz 1.13
279 :    
280 :    
281 :     =head3 kill_RAST_job
282 :    
283 :    
284 :     my $ret = rastObject->kill_RAST_job(-job => \@jobids);
285 :    
286 :     where @jobids is an array of RAST job ids to kill.
287 :    
288 :    
289 :     Return is a hash keyed by Job ID of
290 :    
291 :     {status} = ok|error
292 :     {messages} = Messages
293 :    
294 :     =cut
295 :    
296 :    
297 :    
298 : olson 1.6 sub kill_RAST_job
299 :     {
300 :     my($self, $params) = @_;
301 :    
302 :     return $self->run_query('kill_RAST_job', $params);
303 :     }
304 :    
305 : disz 1.13
306 :    
307 :     =head3 delete_RAST_job
308 :    
309 :    
310 :     my $ret = rastObject->delete_RAST_job(-job => \@jobids);
311 :    
312 :     where @jobids is an array of RAST job ids to kill.
313 :    
314 :    
315 :     Return is a hash keyed by Job ID of
316 :    
317 :     {status} = ok|error
318 :     {error_message} = Error Message
319 :    
320 :     =cut
321 :    
322 : olson 1.6 sub delete_RAST_job
323 :     {
324 :     my($self, $params) = @_;
325 :    
326 :     return $self->run_query('delete_RAST_job', $params);
327 :     }
328 :    
329 : disz 1.13
330 :     =head3 get_job_metadata
331 :    
332 :    
333 :     my $ret = rastObject->get_job_metadata($jobid)
334 :    
335 :     where $jobid is the RAST id of a RAST job
336 :    
337 :    
338 :     Return is a hash of
339 :    
340 :     {status} = ok|error
341 :     {error_message} = Error Message
342 :     {key} => {metdata}
343 :     =cut
344 :    
345 :    
346 :    
347 : olson 1.12 sub get_job_metadata
348 :     {
349 :     my($self, $params) = @_;
350 :     return $self->run_query('get_job_metadata', $params);
351 :     }
352 : olson 1.1
353 :     sub run_query
354 :     {
355 :     my($self, $function, @args ) = @_;
356 :     my $form = [function => $function,
357 :     args => YAML::Dump(@args),
358 :     username => $self->{username},
359 :     password => $self->{password},
360 :     ];
361 :     return $self->run_query_form($form);
362 :     }
363 :    
364 :     sub run_query_form
365 :     {
366 :     my($self, $form, $raw) = @_;
367 :    
368 :     my $res = $self->{ua}->post($self->{server_url}, $form);
369 :    
370 :     if ($res->is_success)
371 :     {
372 :     my $content = $res->content;
373 :     if ($raw)
374 :     {
375 :     return $content;
376 :     }
377 :    
378 :     # print "Got $content\n";
379 :     my $ret;
380 : olson 1.5 eval {
381 : olson 1.1 $ret = Load($content);
382 :     };
383 :     if ($@)
384 :     {
385 :     die "Query returned unparsable content ($@): " . $content;
386 :     }
387 :     return $ret;
388 :     }
389 :     else
390 :     {
391 :     die "error on post " . $res->status_line . " " . $res->content;
392 :     }
393 :     }
394 :    
395 : overbeek 1.17 =head3 copy_to_RAST_dir
396 :    
397 :     my $result = $rastObject->copy_to_RAST_dir(-job => $jobid,
398 :     -from => $file_or_dir,
399 :     -to => $to_dir);
400 :    
401 :     where $jobid is the RAST id of the job,
402 :    
403 :     $file_or_dir is a file or directory to be copied into the RAST UserSpace, and
404 :    
405 :     $to_dir is optional. If omitted the copy is to UserSpace. If present, the
406 :     copy is to UserSpace/$to_dir (intermediate directories get created, if
407 :     necessary)
408 :    
409 :     The return is a hash of
410 :    
411 :     {status} = ok|error
412 :     {error_msg} = The error message
413 :    
414 :     =cut
415 :    
416 :     sub copy_to_RAST_dir
417 :     {
418 :     my($self, $params) = @_;
419 :    
420 :     my $from = delete $params->{-from};
421 : olson 1.18 my $to_name;
422 : olson 1.19 my $src_fh;
423 :    
424 : overbeek 1.17 if (-f $from)
425 :     {
426 : olson 1.19 if (!open($src_fh, "<", $from))
427 :     {
428 :     return { status => 'error',
429 :     error_msg => "Could not open $from: $!" };
430 :     }
431 : olson 1.18 $params->{-type} = 'file';
432 : overbeek 1.17 }
433 :     elsif (-d $from)
434 :     {
435 : olson 1.19 if (!open($src_fh, "-|", "tar", "-c", "-f", "-", $from))
436 :     {
437 :     return { status => 'error',
438 :     error_msg => "Could not open tar pipe for $from: $!" };
439 :     }
440 :     $params->{-type} = 'tar';
441 : overbeek 1.17 }
442 :     else
443 :     {
444 :     return { status => 'error',
445 :     error_msg => "From not found: $from"
446 :     };
447 :     }
448 :    
449 : olson 1.19 my $block_size = 50_000_000;
450 :    
451 : olson 1.18 $to_name = basename($from);
452 :     $params->{-toName} = $to_name;
453 :    
454 : olson 1.19 my $buf;
455 :     my $chunk_num = 0;
456 :     my $size = 0;
457 : olson 1.21
458 :     # my @stat = stat($src_fh);
459 :     # my $file_size = $stat[7];
460 :    
461 : olson 1.19 while (my $n = read($src_fh, $buf, $block_size))
462 :     {
463 :     $params->{-chunkNum} = $chunk_num;
464 :    
465 :     my $form = [function => 'copy_to_RAST_dir',
466 :     args => YAML::Dump($params),
467 :     username => $self->{username},
468 :     password => $self->{password},
469 :     file => $buf,
470 :     ];
471 :    
472 : olson 1.21 warn "Sending chunk " . $chunk_num + 1 . "\n";
473 : olson 1.19 my $res = $self->{ua}->post($self->{server_url},
474 :     Content_Type => 'form-data',
475 :     Content => $form,
476 :     );
477 :    
478 :     if ($res->is_success)
479 :     {
480 :     my $content = $res->content;
481 :     my $ret;
482 :     eval {
483 :     $ret = Load($content);
484 :     };
485 :     if ($@)
486 :     {
487 :     die "Query returned unparsable content ($@): " . $content;
488 :     }
489 :     warn "response " . Dumper($ret);
490 :     if ($ret->{status} ne 'ok')
491 :     {
492 :     return $ret;
493 :     }
494 :     }
495 :     else
496 :     {
497 :     return { status => 'error', error_msg => $res->status_line };
498 :     }
499 :     $size += $n;
500 :     $chunk_num++;
501 :     }
502 :     $params->{-totalSize} = $size;
503 :    
504 : overbeek 1.17 my $form = [function => 'copy_to_RAST_dir',
505 :     args => YAML::Dump($params),
506 :     username => $self->{username},
507 :     password => $self->{password},
508 :     ];
509 : olson 1.19
510 :     warn "send total size $size\n";
511 : olson 1.18 my $res = $self->{ua}->post($self->{server_url},
512 :     Content_Type => 'form-data',
513 :     Content => $form,
514 : overbeek 1.17 );
515 : olson 1.19
516 : overbeek 1.17 if ($res->is_success)
517 :     {
518 : olson 1.18 my $content = $res->content;
519 :     my $ret;
520 :     eval {
521 :     $ret = Load($content);
522 :     };
523 :     if ($@)
524 :     {
525 :     die "Query returned unparsable content ($@): " . $content;
526 :     }
527 : olson 1.19 warn "response " . Dumper($ret);
528 : olson 1.18 return $ret;
529 : overbeek 1.17 }
530 :     else
531 :     {
532 :     return { status => 'error', error_msg => $res->status_line };
533 :     }
534 :     }
535 : olson 1.1
536 :     1;
537 :    

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3