# HG changeset patch # User eric-rasche # Date 1484239948 18000 # Node ID d4ae83dedb142cd067cbf20780871cdfcf2956bc # Parent c8e16c8eff984241b91308234836dbf0677c2278 planemo upload for repository https://github.com/TAMU-CPT/galaxy-webapollo commit 4ac38d0b6dba1183f3e78eb5c224c7051064b4a5 diff -r c8e16c8eff98 -r d4ae83dedb14 README.md --- a/README.md Tue May 03 13:48:11 2016 -0400 +++ b/README.md Thu Jan 12 11:52:28 2017 -0500 @@ -1,7 +1,20 @@ -# galaxy-webapollo +# galaxy-apollo + +Galaxy tools to interface with Apollo +The webapollo.py file is also [separately available](https://github.com/erasche/python-apollo) as a pip-installable package. + +## ENV + +The following environment variables must be set: -Galaxy tools to interface with WebApollo -The webapollo.py file is also [separately available](https://github.com/erasche/python-apollo) as a pip-installable package. + +ENV | Use +--- | --- + `$GALAXY_WEBAPOLLO_URL` | The URL at which Apollo is accessible, internal to Galaxy and where the tools run. Must be absolute, with FQDN and protocol. + `$GALAXY_WEBAPOLLO_USER` | The admin user which Galaxy should use to talk to Apollo. + `$GALAXY_WEBAPOLLO_PASSWORD` | The password for the admin user. + `$GALAXY_WEBAPOLLO_EXT_URL` | The external URL at which Apollo is accessible to end users. May be relative or absolute. + `$GALAXY_SHARED_DIR` | Directory shared between Galaxy and Apollo, used to exchange JBrowse instances. ## License diff -r c8e16c8eff98 -r d4ae83dedb14 add_organism.py --- a/add_organism.py Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -#!/usr/bin/env python -import json -import argparse -import time -from webapollo import WebApolloInstance -import logging -logging.basicConfig(level=logging.INFO) -log = logging.getLogger(__name__) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Admin Username') - parser.add_argument('password', help='WA Admin Password') - - parser.add_argument('cn', help='Organism Common Name') - parser.add_argument('jbrowse', help='JBrowse Data Directory') - parser.add_argument('email', help='User Email') - parser.add_argument('--blatdb', help='BlatDB Directory') - parser.add_argument('--genus', help='Organism Genus') - parser.add_argument('--species', help='Organism Species') - parser.add_argument('--public', action='store_true', help='Make organism public') - - args = parser.parse_args() - - - wa = WebApolloInstance(args.apollo, args.username, args.password) - # User must have an account - gx_user = wa.users.loadUsers(email=args.email) - if len(gx_user) == 0: - raise Exception("Unknown user. Please register first") - - log.info("Adding Organism") - orgs = wa.organisms.addOrganism( - args.cn, - args.jbrowse, - blatdb=args.blatdb, - genus=args.genus, - species=args.species, - public=args.public - ) - log.info("Success: %s", orgs[0]['id']) - - # Must sleep before we're ready to handle - time.sleep(1) - log.info("Updating permissions for %s on %s", gx_user[0], args.cn) - data = wa.users.updateOrganismPermission( - gx_user[0], args.cn, - write=True, - export=True, - read=True, - ) - - print json.dumps([org for org in orgs if org['commonName'] == args.cn], indent=2) diff -r c8e16c8eff98 -r d4ae83dedb14 add_organism.xml --- a/add_organism.xml Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ - - - registers a new genome with WebApollo - - macros.xml - - - $output]]> - - - - - - - - - - - - - - diff -r c8e16c8eff98 -r d4ae83dedb14 clean_org.py --- a/clean_org.py Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -#!/usr/bin/env python -import argparse -from webapollo import WebApolloInstance -import logging -logging.basicConfig(level=logging.INFO) -log = logging.getLogger(__name__) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Admin Username') - parser.add_argument('password', help='WA Admin Password') - - parser.add_argument('cn', help='Organism Common Name') - parser.add_argument('email', help='User Email') - args = parser.parse_args() - - wa = WebApolloInstance(args.apollo, args.username, args.password) - # User must have an account - gx_user = wa.users.loadUsers(email=args.email) - if len(gx_user) == 0: - raise Exception("Unknown user. Please register first") - - # TODO: Check user perms on org. - org = wa.organisms.findOrganismByCn(args.cn) - - wa.annotations.setSequence(args.cn, org['id']) - - for feature in wa.annotations.getFeatures().get('features', []): - print feature['uniquename'] - wa.annotations.deleteFeatures([feature['uniquename']]) diff -r c8e16c8eff98 -r d4ae83dedb14 create_account.py --- a/create_account.py Tue May 03 13:48:11 2016 -0400 +++ b/create_account.py Thu Jan 12 11:52:28 2017 -0500 @@ -2,7 +2,8 @@ import random import argparse import time -from webapollo import WebApolloInstance, GroupObj +from webapollo import WAAuth, WebApolloInstance + def pwgen(length): chars = list('qwrtpsdfghjklzxcvbnm') @@ -10,28 +11,28 @@ if __name__ == '__main__': parser = argparse.ArgumentParser(description='Sample script to add an account via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Admin Username') - parser.add_argument('password', help='WA Admin Password') + WAAuth(parser) parser.add_argument('email', help='User Email') - parser.add_argument('--first', help='First Name', default='J') + parser.add_argument('--first', help='First Name', default='Jane') parser.add_argument('--last', help='Last Name', default='Aggie') args = parser.parse_args() wa = WebApolloInstance(args.apollo, args.username, args.password) password = pwgen(12) - wa.users.createUser(args.email, args.first, args.last, password, role='user') time.sleep(1) - user = [u for u in wa.users.loadUsers() - if u.username == args.email][0] - - bich464 = GroupObj(name="bich464-2016-spring") + users = wa.users.loadUsers() + user = [u for u in users + if u.username == args.email] - # Update name, regen password if the user ran it again - wa.users.updateUser(user, args.email, args.first, args.last, password) - # Add to bich464 group - wa.users.addUserToGroup(bich464, user) + if len(user) == 1: + # Update name, regen password if the user ran it again + userObj = user[0] + returnData = wa.users.updateUser(userObj, args.email, args.first, args.last, password) + print 'Updated User\nUsername: %s\nPassword: %s' % (args.email, password) + else: + returnData = wa.users.createUser(args.email, args.first, args.last, password, role='user') + print 'Created User\nUsername: %s\nPassword: %s' % (args.email, password) - print 'Username: %s\nPassword: %s' % (args.email, password) + print "Return data: " + str(returnData) diff -r c8e16c8eff98 -r d4ae83dedb14 create_account.xml --- a/create_account.xml Tue May 03 13:48:11 2016 -0400 +++ b/create_account.xml Thu Jan 12 11:52:28 2017 -0500 @@ -1,6 +1,6 @@ - - registers a new account with WebApollo + + with Apollo macros.xml @@ -8,7 +8,7 @@ - + - - - - macros.xml - - - $output]]> - - - - - - - - - diff -r c8e16c8eff98 -r d4ae83dedb14 create_or_update_organism.py --- a/create_or_update_organism.py Tue May 03 13:48:11 2016 -0400 +++ b/create_or_update_organism.py Thu Jan 12 11:52:28 2017 -0500 @@ -2,7 +2,7 @@ import json import argparse import time -from webapollo import WebApolloInstance +from webapollo import WAAuth, WebApolloInstance, OrgOrGuess, GuessOrg, AssertUser import logging logging.basicConfig(level=logging.INFO) log = logging.getLogger(__name__) @@ -10,41 +10,39 @@ if __name__ == '__main__': parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Admin Username') - parser.add_argument('password', help='WA Admin Password') + WAAuth(parser) - parser.add_argument('cn', help='Organism Common Name') parser.add_argument('jbrowse', help='JBrowse Data Directory') parser.add_argument('email', help='User Email') - parser.add_argument('--blatdb', help='BlatDB Directory') + OrgOrGuess(parser) parser.add_argument('--genus', help='Organism Genus') parser.add_argument('--species', help='Organism Species') parser.add_argument('--public', action='store_true', help='Make organism public') args = parser.parse_args() - + wa = WebApolloInstance(args.apollo, args.username, args.password) - wa = WebApolloInstance(args.apollo, args.username, args.password) + org_cn = GuessOrg(args, wa) + if isinstance(org_cn, list): + org_cn = org_cn[0] + # User must have an account - gx_user = wa.users.loadUsers(email=args.email) - if len(gx_user) == 0: - raise Exception("Unknown user. Please register first") + gx_user = AssertUser(wa.users.loadUsers(email=args.email)) log.info("Determining if add or update required") try: - org = wa.organisms.findOrganismByCn(args.cn) + org = wa.organisms.findOrganismByCn(org_cn) except Exception: org = None + # TODO: Check ownership if org: log.info("\tUpdating Organism") data = wa.organisms.updateOrganismInfo( org['id'], - args.cn, + org_cn, args.jbrowse, # mandatory - blatdb=args.blatdb, genus=args.genus, species=args.species, public=args.public @@ -53,23 +51,22 @@ # New organism log.info("\tAdding Organism") data = wa.organisms.addOrganism( - args.cn, + org_cn, args.jbrowse, - blatdb=args.blatdb, genus=args.genus, species=args.species, public=args.public ) # Must sleep before we're ready to handle - time.sleep(1) - log.info("Updating permissions for %s on %s", gx_user[0], args.cn) + time.sleep(2) + log.info("Updating permissions for %s on %s", gx_user, org_cn) wa.users.updateOrganismPermission( - gx_user[0], args.cn, + gx_user, org_cn, write=True, export=True, read=True, ) - data = [o for o in data if o['commonName'] == args.cn] + data = [o for o in data if o['commonName'] == org_cn] print json.dumps(data, indent=2) diff -r c8e16c8eff98 -r d4ae83dedb14 create_or_update_organism.xml --- a/create_or_update_organism.xml Tue May 03 13:48:11 2016 -0400 +++ b/create_or_update_organism.xml Thu Jan 12 11:52:28 2017 -0500 @@ -1,58 +1,53 @@ - + will create the organism if it doesn't exist, and update otherwise macros.xml + $output]]> - - - - - + + + diff -r c8e16c8eff98 -r d4ae83dedb14 export.py --- a/export.py Tue May 03 13:48:11 2016 -0400 +++ b/export.py Thu Jan 12 11:52:28 2017 -0500 @@ -1,44 +1,74 @@ #!/usr/bin/env python +import sys import StringIO -import sys import json import argparse from Bio import SeqIO from BCBio import GFF -from webapollo import WebApolloInstance +from webapollo import WAAuth, WebApolloInstance, CnOrGuess, GuessCn + + +def export(org_cn, seqs): + org_data = wa.organisms.findOrganismByCn(org_cn) + + data = StringIO.StringIO() + + kwargs = dict( + exportType='GFF3', + seqType='genomic', + exportGff3Fasta=True, + output="text", + exportFormat="text", + organism=org_cn, + ) + + if len(seqs) > 0: + data.write(wa.io.write( + exportAllSequences=False, + sequences=seqs, + **kwargs + ).encode('utf-8')) + else: + data.write(wa.io.write( + exportAllSequences=True, + sequences=[], + **kwargs + ).encode('utf-8')) + + # Seek back to start + data.seek(0) + + records = list(GFF.parse(data)) + if len(records) == 0: + print "Could not find any sequences or annotations for this organism + reference sequence" + sys.exit(2) + else: + for record in records: + record.annotations = {} + if args.gff: + GFF.write([record], args.gff) + record.description = "" + if args.fasta: + SeqIO.write([record], args.fasta, 'fasta') + + return org_data if __name__ == '__main__': - json parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Username') - parser.add_argument('password', help='WA Password') - - parser.add_argument('commonName', nargs='+', help='Sequence Unique Names') - + WAAuth(parser) + CnOrGuess(parser) parser.add_argument('--gff', type=argparse.FileType('w')) parser.add_argument('--fasta', type=argparse.FileType('w')) + parser.add_argument('--json', type=argparse.FileType('w')) args = parser.parse_args() wa = WebApolloInstance(args.apollo, args.username, args.password) - data = StringIO.StringIO(wa.io.write( - exportType='GFF3', - seqType='genomic', - exportAllSequences=False, - exportGff3Fasta=True, - output="text", - exportFormat="text", - # TODO: CPT specific convention!!!!!!!! - organism=args.commonName, - sequences=args.commonName - )) - data.seek(0) + org_cn_list, seqs = GuessCn(args, wa) - for record in GFF.parse(data): - record.annotations = {} - GFF.write([record], args.gff) - record.description = "" - SeqIO.write([record], args.fasta, 'fasta') - sys.exit() + org_data = [] + for org_cn in org_cn_list: + indiv_org_data = export(org_cn, seqs) + org_data.append(indiv_org_data) + args.json.write(json.dumps(org_data, indent=2)) diff -r c8e16c8eff98 -r d4ae83dedb14 export.xml --- a/export.xml Tue May 03 13:48:11 2016 -0400 +++ b/export.xml Thu Jan 12 11:52:28 2017 -0500 @@ -1,32 +1,41 @@ - - from WebApollo into Galaxy + + from Apollo into Galaxy macros.xml + - - + + + diff -r c8e16c8eff98 -r d4ae83dedb14 fetch_organism_jbrowse.py --- a/fetch_organism_jbrowse.py Tue May 03 13:48:11 2016 -0400 +++ b/fetch_organism_jbrowse.py Thu Jan 12 11:52:28 2017 -0500 @@ -1,9 +1,7 @@ #!/usr/bin/env python import os -import json import argparse -import time -from webapollo import WebApolloInstance +from webapollo import WAAuth, WebApolloInstance, GuessOrg, OrgOrGuess import logging import subprocess logging.basicConfig(level=logging.INFO) @@ -12,23 +10,18 @@ if __name__ == '__main__': parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Admin Username') - parser.add_argument('password', help='WA Admin Password') - parser.add_argument('cn', help='Organism Common Name') - parser.add_argument('email', help='User Email') + WAAuth(parser) + OrgOrGuess(parser) parser.add_argument('target_dir', help='Target directory') args = parser.parse_args() - wa = WebApolloInstance(args.apollo, args.username, args.password) # User must have an account - gx_user = wa.users.loadUsers(email=args.email) - if len(gx_user) == 0: - raise Exception("Unknown user. Please register first") - org = wa.organisms.findOrganismByCn(args.cn) - + org_cn = GuessOrg(args, wa) + if isinstance(org_cn, list): + org_cn = org_cn[0] + org = wa.organisms.findOrganismByCn(org_cn) if not os.path.exists(args.target_dir): os.makedirs(args.target_dir) @@ -38,5 +31,4 @@ org['directory'], os.path.join(args.target_dir, 'data') ] - print ' '.join(cmd) subprocess.check_call(cmd) diff -r c8e16c8eff98 -r d4ae83dedb14 fetch_organism_jbrowse.xml --- a/fetch_organism_jbrowse.xml Tue May 03 13:48:11 2016 -0400 +++ b/fetch_organism_jbrowse.xml Thu Jan 12 11:52:28 2017 -0500 @@ -1,17 +1,18 @@ - - fetches JBrowse data for existing organisms + + for an organism, from Apollo macros.xml + - + diff -r c8e16c8eff98 -r d4ae83dedb14 find_organism.py --- a/find_organism.py Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -#!/usr/bin/env python -import json -import argparse -from webapollo import WebApolloInstance - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Admin Username') - parser.add_argument('password', help='WA Admin Password') - - parser.add_argument('--commonName', help='Common Name') - - args = parser.parse_args() - - wa = WebApolloInstance(args.apollo, args.username, args.password) - data = wa.organisms.findAllOrganisms() - if args.commonName is not None: - data = [o for o in data if o['commonName'] == args.commonName] - - print json.dumps(data, indent=2) diff -r c8e16c8eff98 -r d4ae83dedb14 find_organism.xml --- a/find_organism.xml Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ - - - finds an organism's details by common name - - macros.xml - - - $output]]> - - - - - - - - diff -r c8e16c8eff98 -r d4ae83dedb14 gff3_cleaner.py --- a/gff3_cleaner.py Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -#!/usr/bin/env python -import sys -import argparse -from gff3 import feature_lambda, feature_test_type -from BCBio import GFF -import logging -logging.basicConfig(level=logging.WARN) -log = logging.getLogger(name='pav') - -def coding_genes(feature_list): - for x in feature_lambda(feature_list, feature_test_type, {'type': 'gene'}, subfeatures=True): - if len(list(feature_lambda(x.sub_features, feature_test_type, {'type': 'CDS'}, subfeatures=False))) > 0: - yield x - - -def genes(feature_list, feature_type='gene'): - for x in feature_lambda(feature_list, feature_test_type, - {'type': feature_type}, - subfeatures=True): - yield x - - -def fix_apollo_issues(annotations, user_email): - for rec in GFF.parse(annotations): - for feat in rec.features: - if feat.type != 'gene': - continue - - for sf in feat.sub_features: - if sf.type != 'mRNA': - continue - - for ssf in sf.sub_features: - if ssf.type != 'exon': - continue - - if len(ssf) > 10: - continue - - ssf.type = 'Shine_Dalgarno_sequence' - - sf.sub_features = [x for x in sf.sub_features if x.type not in - ('non_canonical_five_prime_splice_site', - 'non_canonical_three_prime_splice_site')] - yield rec - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='rebase gff3 features against parent locations', epilog="") - parser.add_argument('annotations', type=file, help='Parent GFF3 annotations') - # parser.add_argument('genome', type=file, help='Genome Sequence') - parser.add_argument('--user_email') - - args = parser.parse_args() - for rec in fix_apollo_issues(**vars(args)): - rec.annotations = {} - GFF.write([rec], sys.stdout) diff -r c8e16c8eff98 -r d4ae83dedb14 gff3_cleaner.xml --- a/gff3_cleaner.xml Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ - - - - - macros.xml - - - $output]]> - - - - - - - - - - - - - - diff -r c8e16c8eff98 -r d4ae83dedb14 json2iframe.py --- a/json2iframe.py Tue May 03 13:48:11 2016 -0400 +++ b/json2iframe.py Thu Jan 12 11:52:28 2017 -0500 @@ -7,15 +7,12 @@ parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') parser.add_argument('apollo', help='Complete Apollo URL') parser.add_argument('json', type=file, help='JSON Data') + parser.add_argument('external_apollo_url') args = parser.parse_args() - - # https://cpt.tamu.edu/apollo/annotator/loadLink?loc=NC_005880:0..148317&organism=326&tracks= + # https://fqdn/apollo/annotator/loadLink?loc=NC_005880:0..148317&organism=326&tracks= data = json.load(args.json) - print data - if len(data) > 1: - raise Exception("More than one organism listed. Contact your local admin for help.") # This is base64 encoded to get past the toolshed's filters. HTML_TPL = """ @@ -27,4 +24,4 @@ """ HTML_TPL = base64.b64decode(HTML_TPL.replace('\n', '')) - print HTML_TPL.format(base_url=args.apollo, chrom="", orgId=data[0]['id']) + print HTML_TPL.format(base_url=args.external_apollo_url, chrom="", orgId=data[0]['id']) diff -r c8e16c8eff98 -r d4ae83dedb14 json2iframe.xml --- a/json2iframe.xml Tue May 03 13:48:11 2016 -0400 +++ b/json2iframe.xml Thu Jan 12 11:52:28 2017 -0500 @@ -1,5 +1,5 @@ - + opens an IFrame to Apollo macros.xml @@ -9,9 +9,10 @@ python $__tool_directory__/json2iframe.py @URL@ $json_file +@EXT_URL@ > $output]]> - + @@ -19,7 +20,7 @@ WebApollo bridge, this +Given a json file that's output by the Galaxy<->Apollo bridge, this generates a nice little IFrame that you can use to access Apollo @REFERENCES@ diff -r c8e16c8eff98 -r d4ae83dedb14 list_organisms.py --- a/list_organisms.py Tue May 03 13:48:11 2016 -0400 +++ b/list_organisms.py Thu Jan 12 11:52:28 2017 -0500 @@ -1,17 +1,19 @@ #!/usr/bin/env python import json import argparse -from webapollo import WebApolloInstance +from webapollo import WAAuth, WebApolloInstance, AssertUser, accessible_organisms if __name__ == '__main__': - json parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Username') - parser.add_argument('password', help='WA Password') - + WAAuth(parser) + parser.add_argument('email', help='User Email') args = parser.parse_args() wa = WebApolloInstance(args.apollo, args.username, args.password) - print json.dumps(wa.organisms.findAllOrganisms(), indent=2) + + gx_user = AssertUser(wa.users.loadUsers(email=args.email)) + all_orgs = wa.organisms.findAllOrganisms() + orgs = accessible_organisms(gx_user, all_orgs) + + print json.dumps(orgs, indent=2) diff -r c8e16c8eff98 -r d4ae83dedb14 list_organisms.xml --- a/list_organisms.xml Tue May 03 13:48:11 2016 -0400 +++ b/list_organisms.xml Thu Jan 12 11:52:28 2017 -0500 @@ -1,13 +1,14 @@ - - lists all organisms know to Apollo + + in Apollo macros.xml $output]]> diff -r c8e16c8eff98 -r d4ae83dedb14 macros.xml --- a/macros.xml Tue May 03 13:48:11 2016 -0400 +++ b/macros.xml Thu Jan 12 11:52:28 2017 -0500 @@ -3,48 +3,94 @@ python + biopython + bcbiogff + \$GALAXY_SHARED_DIR + +\$GALAXY_WEBAPOLLO_EXT_URL + \$GALAXY_WEBAPOLLO_URL - -@URL@ -galaxy@gmod.org + +\$GALAXY_WEBAPOLLO_URL +$__user_email__ +"" +--remote_user REMOTE_USER + + +\$GALAXY_WEBAPOLLO_URL +\$GALAXY_WEBAPOLLO_USER \$GALAXY_WEBAPOLLO_PASSWORD - - - - + ' | head -n 1 | sed 's/\s.*//g;s/>//g') -#elif $cn_source.source_select == "auto_json": - \$(cat $cn_source.cn_file | grep 'commonName' | head -n 1| sed 's/.*: "//g;s/".*//g') -#else - "${cn_source.organism_cn}" +#if $org_source.source_select == "auto_json": + --org_json "${org_source.org_file}" +#elif $org_source.source_select == "select": + --org_id "${org_source.org_select}" +#else: + --org_raw "${org_source.org_raw}" #end if ]]> - - + + 0: + --seq_raw + #for $item in $cn_source.refseqs: + "${item.refseq}" + #end for + #end if +#end if +]]> + + + - + + - - - + + + + + - + + + + + + + + + + + + + + + + - + + + @@ -53,21 +99,6 @@ - - - - With workflows that contact remote databases, it is sometimes - necessary to have particular operations happen in a particular - order. I.e. you would not want to try and add data to an organism - if the organism did not yet exist in WebApollo. - Since few of the WebApollo2 toolsuite output files which are - used in a downstream task (e.g. the output adding an organism is - not used elsewhere), we provide this dummy option which lets you - select outputs to help provide context for when this task should - execute. - - - diff -r c8e16c8eff98 -r d4ae83dedb14 renumber.py --- a/renumber.py Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -#!/usr/bin/env python -import json -import copy -import argparse -from webapollo import WebApolloInstance -import logging -logging.basicConfig(level=logging.INFO) -log = logging.getLogger(__name__) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Admin Username') - parser.add_argument('password', help='WA Admin Password') - - parser.add_argument('cn', help='Organism Common Name') - - parser.add_argument('--email') - parser.add_argument('--prefix', default='gene_') - parser.add_argument('--leading', default='3') - - args = parser.parse_args() - - - wa = WebApolloInstance(args.apollo, args.username, args.password) - # User must have an account - gx_user = wa.users.loadUsers(email=args.email) - if len(gx_user) == 0: - raise Exception("Unknown user. Please register first") - - # Must find the organism - org = wa.organisms.findOrganismByCn(args.cn) - # TODO: verify user has permissions on the organism - wa.annotations.setSequence(args.cn, org['id']) - raw_data = wa.annotations.getFeatures()['features'] - - data = sorted([ - (x['parent_id'], x['uniquename'], x['location']['fmin'], x['name']) - for x in raw_data - ], key=lambda x: x[2]) - - format_string = args.prefix + '%0' + args.leading + 'd' - format_string_mrna = format_string + '.mRNA' - - outData = copy.copy(org) - outData['changes'] = [] - - for i, feat in enumerate(data): - idx = i + 1 - log.info('Renaming %s to %s', feat[3], format_string % idx) - outData['changes'].append((feat[0], format_string % idx)) - wa.annotations.setName(feat[0], format_string % idx) - outData['changes'].append((feat[1], format_string_mrna % idx)) - wa.annotations.setName(feat[1], format_string_mrna % idx) - - print json.dumps(outData, indent=2) diff -r c8e16c8eff98 -r d4ae83dedb14 renumber.xml --- a/renumber.xml Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ - - - following standard conventions - - macros.xml - - - $output]]> - - - - - - - - - - diff -r c8e16c8eff98 -r d4ae83dedb14 test.json --- a/test.json Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -[ - { - "chrom": "Test", - "id": 123 - } -] diff -r c8e16c8eff98 -r d4ae83dedb14 update_organism.py --- a/update_organism.py Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -#!/usr/bin/env python -import json -import argparse -from webapollo import WebApolloInstance - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services') - parser.add_argument('apollo', help='Complete Apollo URL') - parser.add_argument('username', help='WA Admin Username') - parser.add_argument('password', help='WA Admin Password') - - parser.add_argument('organismId', help='Organism ID #') - parser.add_argument('email', help='User Email') - - parser.add_argument('--commonName', help='Organism Common Name') - parser.add_argument('--jbrowse', help='JBrowse Data Directory') - parser.add_argument('--blatdb', help='BlatDB Directory') - parser.add_argument('--genus', help='Organism Genus') - parser.add_argument('--species', help='Organism Species') - parser.add_argument('--public', action='store_true', help='Make organism public') - - args = parser.parse_args() - - wa = WebApolloInstance(args.apollo, args.username, args.password) - data = wa.organisms.updateOrganismInfo( - args.organismId, - args.commonName, - args.jbrowse, - # mandatory - blatdb=args.blatdb, - genus=args.genus, - species=args.species, - public=args.public - ) - # Need to filter data - wanted_data = [x for x in data if str(x['id']) == str(args.organismId)] - print json.dumps(wanted_data, indent=2) diff -r c8e16c8eff98 -r d4ae83dedb14 update_organism.xml --- a/update_organism.xml Tue May 03 13:48:11 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ - - - updates an existing genome with WebApollo - - macros.xml - - - $output]]> - - - - - - - - - - - - - - - diff -r c8e16c8eff98 -r d4ae83dedb14 webapollo.py --- a/webapollo.py Tue May 03 13:48:11 2016 -0400 +++ b/webapollo.py Thu Jan 12 11:52:28 2017 -0500 @@ -1,13 +1,79 @@ import requests import json +import os import collections -from BCBio import GFF import StringIO import logging +from BCBio import GFF +from Bio import SeqIO logging.getLogger("requests").setLevel(logging.CRITICAL) log = logging.getLogger() +def WAAuth(parser): + parser.add_argument('apollo', help='Complete Apollo URL') + parser.add_argument('username', help='WA Username') + parser.add_argument('password', help='WA Password') + parser.add_argument('--remote_user', default='', help='If set, ignore password, set the header with the name supplied to this argument to the value of email') + + +def OrgOrGuess(parser): + parser.add_argument('--org_json', type=file, help='Apollo JSON output, source for common name') + parser.add_argument('--org_raw', help='Common Name') + parser.add_argument('--org_id', help='Organism ID') + + +def CnOrGuess(parser): + OrgOrGuess(parser) + parser.add_argument('--seq_fasta', type=file, help='Fasta file, IDs used as sequence sources') + parser.add_argument('--seq_raw', nargs='*', help='Sequence Names') + + +def GuessOrg(args, wa): + if args.org_json: + orgs = [x.get('commonName', None) + for x in json.load(args.org_json)] + orgs = [x for x in orgs if x is not None] + return orgs + elif args.org_raw: + org = args.org_raw.strip() + if len(org) > 0: + return [org] + else: + raise Exception("Organism Common Name not provided") + elif args.org_id: + return [wa.organisms.findOrganismById(args.org_id).get('commonName', None)] + else: + raise Exception("Organism Common Name not provided") + + +def GuessCn(args, wa): + org = GuessOrg(args, wa) + seqs = [] + if args.seq_fasta: + # If we have a fasta, pull all rec ids from that. + for rec in SeqIO.parse(args.seq_fasta, 'fasta'): + seqs.append(rec.id) + elif args.seq_raw: + # Otherwise raw list. + seqs = [x.strip() for x in args.seq_raw if len(x.strip()) > 0] + + return org, seqs + + +def AssertUser(user_list): + if len(user_list) == 0: + raise Exception("Unknown user. Please register first") + else: + return user_list[0] + + +def AssertAdmin(user): + if user.role == 'ADMIN': + return True + else: + raise Exception("User is not an administrator. Permission denied") + class WebApolloInstance(object): @@ -53,7 +119,6 @@ self.__props = kwargs.keys() - def isAdmin(self): if hasattr(self, 'role'): return self.role == self.ROLE_ADMIN @@ -100,9 +165,9 @@ }) r = requests.post(url, data=json.dumps(data), headers=headers, - verify=self.__verify, params=post_params, **self._requestArgs) + verify=self.__verify, params=post_params, allow_redirects=False, **self._requestArgs) - if r.status_code == 200: + if r.status_code == 200 or r.status_code == 302: if isJson: d = r.json() if 'username' in d: @@ -146,7 +211,9 @@ CLIENT_BASE = '/annotationEditor/' def _update_data(self, data): - if not hasattr(self, '_extra_data'): raise Exception("Please call setSequence first") + if not hasattr(self, '_extra_data'): + raise Exception("Please call setSequence first") + data.update(self._extra_data) return data @@ -399,7 +466,7 @@ return self.request('getOrganismPermissionsForGroup', data) def loadGroups(self, group=None): - data ={} + data = {} if group is not None: data['groupId'] = group.groupId @@ -517,6 +584,14 @@ else: return orgs[0] + def findOrganismById(self, id_number): + orgs = self.findAllOrganisms() + orgs = [x for x in orgs if str(x['id']) == str(id_number)] + if len(orgs) == 0: + raise Exception("Unknown ID") + else: + return orgs[0] + def deleteOrganism(self, organismId): return self.request('deleteOrganism', {'id': organismId}) @@ -547,11 +622,16 @@ class UsersClient(Client): CLIENT_BASE = '/user/' + # Real one + # def getOrganismPermissionsForUser(self, user): + # data = { + # 'userId': user.userId, + # } + # return self.request('getOrganismPermissionsForUser', data) + + # Utter frigging hack def getOrganismPermissionsForUser(self, user): - data = { - 'userId': user.userId, - } - return self.request('getOrganismPermissionsForUser', data) + return self.loadUser(user).organismPermissions def updateOrganismPermission(self, user, organism, administrate=False, write=False, export=False, read=False): @@ -651,7 +731,6 @@ def __getattr__(self, key): if key in ('_sr', '_wa'): - print self.__dict__ return self.__dict__[key] else: if key == 'features': @@ -666,7 +745,6 @@ else: self._sr.__dict__[key] = value # Methods acting on the SeqRecord object - print key, value class WebApolloSeqFeature(object): @@ -703,7 +781,7 @@ self._sf.__dict__[key] = value else: self._sf.__dict__[key] = value - print key, value + def _tnType(feature): if feature.type in ('gene', 'mRNA', 'exon', 'CDS'): @@ -711,6 +789,7 @@ else: return 'exon' + def _yieldFeatData(features): for f in features: current = { @@ -733,6 +812,7 @@ yield current + def featuresToFeatureSchema(features): compiled = [] for feature in features: @@ -743,3 +823,36 @@ for x in _yieldFeatData([feature]): compiled.append(x) return compiled + + +def accessible_organisms(user, orgs): + permissionMap = { + x['organism']: x['permissions'] + for x in user.organismPermissions + if 'WRITE' in x['permissions'] or + 'READ' in x['permissions'] or + 'ADMINISTRATE' in x['permissions'] or + user.role == 'ADMIN' + } + return [ + (org['commonName'], org['id'], False) + for org in sorted(orgs, key=lambda x: x['commonName']) + if org['commonName'] in permissionMap + ] + + +def galaxy_list_orgs(trans, *args, **kwargs): + email = trans.get_user().email + + wa = WebApolloInstance( + os.environ.get('GALAXY_WEBAPOLLO_URL', 'https://example.com'), + os.environ.get('GALAXY_WEBAPOLLO_USER', 'admin'), + os.environ.get('GALAXY_WEBAPOLLO_PASSWORD', 'admin') + ) + + gx_user = AssertUser(wa.users.loadUsers(email=email)) + all_orgs = wa.organisms.findAllOrganisms() + + orgs = accessible_organisms(gx_user, all_orgs) + + return orgs