38
38
from tempfile import mkdtemp
39
39
from zipfile import ZipFile
40
40
from io import BytesIO
41
- from shutil import copyfile
42
41
43
42
44
43
class BaseHandlerDownload (BaseHandler ):
@@ -383,6 +382,10 @@ class DownloadDataReleaseFromPrep(BaseHandlerDownload):
383
382
@coroutine
384
383
@execute_as_transaction
385
384
def get (self , prep_template_id ):
385
+ """ This method constructs an on the fly ZIP with all the files
386
+ required for a data-prep release/data-delivery. Mainly sample, prep
387
+ info, bioms and coverage
388
+ """
386
389
user = self .current_user
387
390
if user .level not in ('admin' , 'web-lab admin' ):
388
391
raise HTTPError (403 , reason = "%s doesn't have access to download "
@@ -411,6 +414,7 @@ def get(self, prep_template_id):
411
414
'' ,
412
415
]
413
416
417
+ # helper dict to add "user/human" friendly names to the bioms
414
418
human_names = {
415
419
'ec.biom' : 'KEGG Enzyme (EC)' ,
416
420
'per-gene.biom' : 'Per gene Predictions' ,
@@ -421,18 +425,21 @@ def get(self, prep_template_id):
421
425
'rna_copy_counts.biom' : 'RNA copy counts'
422
426
}
423
427
428
+ # sample-info creation
424
429
fn = join (td , f'sample_information_from_prep_{ pid } .tsv' )
425
430
readme .append (f'Sample information: { basename (fn )} ' )
426
- files .append (fn )
431
+ files .append ([ fn , basename ( fn )] )
427
432
st .to_dataframe (samples = list (pt )).to_csv (fn , sep = '\t ' )
428
433
434
+ # prep-info creation
429
435
fn = join (td , f'prep_information_{ pid } .tsv' )
430
436
readme .append (f'Prep information: { basename (fn )} ' )
431
- files .append (fn )
437
+ files .append ([ fn , basename ( fn )] )
432
438
pt .to_dataframe ().to_csv (fn , sep = '\t ' )
433
439
434
440
readme .append ('' )
435
441
442
+ # finding the bioms to be added
436
443
bioms = dict ()
437
444
coverages = None
438
445
for a in Study (sid ).artifacts (artifact_type = 'BIOM' ):
@@ -447,25 +454,27 @@ def get(self, prep_template_id):
447
454
if biom is None :
448
455
continue
449
456
biom_fn = basename (biom ['fp' ])
457
+ # there is a small but real chance that the same prep has the same
458
+ # artifacts so using the latests
450
459
if biom_fn not in bioms :
451
460
bioms [biom_fn ] = [a , biom ]
452
461
else :
453
462
if getctime (biom ['fp' ]) > getctime (bioms [biom_fn ][1 ]['fp' ]):
454
463
bioms [biom_fn ] = [a , biom ]
455
464
465
+ # once we have all the bioms, we can add them to the list of zips
466
+ # and to the readme the biom details and all the processing
456
467
for fn , (a , fp ) in bioms .items ():
457
468
aname = basename (fp ["fp" ])
458
469
nname = f'{ a .id } _{ aname } '
459
- nfile = join (td , nname )
460
- copyfile (fp ['fp' ], nfile )
461
- files .append (nfile )
470
+ files .append (fp ['fp' ], nname )
462
471
463
472
hname = ''
464
473
if aname in human_names :
465
474
hname = human_names [aname ]
466
475
readme .append (f'{ nname } \t { hname } ' )
467
476
468
- for an in a .ancestors .nodes ():
477
+ for an in set ( a .ancestors .nodes () ):
469
478
p = an .processing_parameters
470
479
if p is not None :
471
480
c = p .command
@@ -476,22 +485,22 @@ def get(self, prep_template_id):
476
485
pd = p .dump ()
477
486
readme .append (f'\t { cn } \t { sn } \t { sv } \t { pd } ' )
478
487
488
+ # if a coverage was found, add it to the list of files
479
489
if coverages is not None :
480
- aname = basename (coverages )
481
- nfile = join (td , aname )
482
- copyfile (coverages , nfile )
483
- files .append (nfile )
490
+ fn = basename (coverages )
491
+ readme .append (f'{ fn } \t coverage files' )
492
+ files .append ([coverages , fn ])
484
493
485
494
fn = join (td , 'README.txt' )
486
495
with open (fn , 'w' ) as fp :
487
496
fp .write ('\n ' .join (readme ))
488
- files .append (fn )
497
+ files .append ([ fn , basename ( fn )] )
489
498
490
499
zp_fn = f'data_release_{ pid } _{ date } .zip'
491
500
zp = BytesIO ()
492
501
with ZipFile (zp , 'w' ) as zipf :
493
- for fp in files :
494
- zipf .write (fp , basename ( fp ) )
502
+ for fp , fn in files :
503
+ zipf .write (fp , fn )
495
504
496
505
self .set_header ('Content-Type' , 'application/zip' )
497
506
self .set_header ("Content-Disposition" , f"attachment; filename={ zp_fn } " )
0 commit comments