Mercurial > repos > fubar > tool_factory_2
comparison toolfactory/rgToolFactory2.py @ 113:6873c211b250 draft
Uploaded
author | fubar |
---|---|
date | Tue, 01 Dec 2020 09:03:34 +0000 |
parents | 5509dc4c1cf2 |
children | e0cf315853cf |
comparison
equal
deleted
inserted
replaced
112:5509dc4c1cf2 | 113:6873c211b250 |
---|---|
192 self.repdir = "./TF_run_report_tempdir" | 192 self.repdir = "./TF_run_report_tempdir" |
193 self.testdir = os.path.join(self.tooloutdir, "test-data") | 193 self.testdir = os.path.join(self.tooloutdir, "test-data") |
194 if not os.path.exists(self.tooloutdir): | 194 if not os.path.exists(self.tooloutdir): |
195 os.mkdir(self.tooloutdir) | 195 os.mkdir(self.tooloutdir) |
196 if not os.path.exists(self.testdir): | 196 if not os.path.exists(self.testdir): |
197 os.mkdir(self.testdir) # make tests directory | 197 os.mkdir(self.testdir) |
198 if not os.path.exists(self.repdir): | 198 if not os.path.exists(self.repdir): |
199 os.mkdir(self.repdir) | 199 os.mkdir(self.repdir) |
200 self.tinputs = gxtp.Inputs() | 200 self.tinputs = gxtp.Inputs() |
201 self.toutputs = gxtp.Outputs() | 201 self.toutputs = gxtp.Outputs() |
202 self.testparam = [] | 202 self.testparam = [] |
222 aCL(self.executeme) | 222 aCL(self.executeme) |
223 aCL(self.sfile) | 223 aCL(self.sfile) |
224 aXCL(self.executeme) | 224 aXCL(self.executeme) |
225 aXCL("$runme") | 225 aXCL("$runme") |
226 else: | 226 else: |
227 aCL(self.executeme) # this little CL will just run | 227 aCL(self.executeme) |
228 aXCL(self.executeme) | 228 aXCL(self.executeme) |
229 self.elog = os.path.join(self.repdir, "%s_error_log.txt" % self.tool_name) | 229 self.elog = os.path.join(self.repdir, "%s_error_log.txt" % self.tool_name) |
230 self.tlog = os.path.join(self.repdir, "%s_runner_log.txt" % self.tool_name) | 230 self.tlog = os.path.join(self.repdir, "%s_runner_log.txt" % self.tool_name) |
231 | 231 |
232 if self.args.parampass == "0": | 232 if self.args.parampass == "0": |
255 xclsuffix.append(xappendme) | 255 xclsuffix.append(xappendme) |
256 for i, p in enumerate(self.outfiles): | 256 for i, p in enumerate(self.outfiles): |
257 if p[OOCLPOS] == "STDOUT": | 257 if p[OOCLPOS] == "STDOUT": |
258 self.lastclredirect = [">", p[ONAMEPOS]] | 258 self.lastclredirect = [">", p[ONAMEPOS]] |
259 self.lastxclredirect = [">", "$%s" % p[OCLPOS]] | 259 self.lastxclredirect = [">", "$%s" % p[OCLPOS]] |
260 else: # for (o_v, k, v, koverride) in self.xclsuffix: | 260 else: |
261 clsuffix.append([p[ONAMEPOS], p[ONAMEPOS], p[ONAMEPOS], ""]) | 261 clsuffix.append([p[ONAMEPOS], p[ONAMEPOS], p[ONAMEPOS], ""]) |
262 xclsuffix.append([p[ONAMEPOS], p[ONAMEPOS], "$%s" % p[ONAMEPOS], ""]) | 262 xclsuffix.append([p[ONAMEPOS], p[ONAMEPOS], "$%s" % p[ONAMEPOS], ""]) |
263 for p in self.addpar: | 263 for p in self.addpar: |
264 clsuffix.append([p[AOCLPOS], p[ACLPOS], p[AVALPOS], p[AOVERPOS]]) | 264 clsuffix.append([p[AOCLPOS], p[ACLPOS], p[AVALPOS], p[AOVERPOS]]) |
265 xclsuffix.append( | 265 xclsuffix.append( |
311 infp[ICLPOS] = scl | 311 infp[ICLPOS] = scl |
312 self.infiles[i] = infp | 312 self.infiles[i] = infp |
313 for i, p in enumerate( | 313 for i, p in enumerate( |
314 self.outfiles | 314 self.outfiles |
315 ): | 315 ): |
316 if self.args.parampass == "positional" and p[OCLPOS] != "STDOUT": | 316 if self.args.parampass == "positional" and p[OCLPOS].upper() != "STDOUT": |
317 assert p[ | 317 assert p[ |
318 OCLPOS | 318 OCLPOS |
319 ].isdigit(), "Positional parameters must be ordinal integers - got %s for %s" % ( | 319 ].isdigit(), "Positional parameters must be ordinal integers - got %s for %s" % ( |
320 p[OCLPOS], | 320 p[OCLPOS], |
321 p[ONAMEPOS], | 321 p[ONAMEPOS], |
322 ) | 322 ) |
323 p.append(p[OCLPOS]) # keep copy | 323 p.append(p[OCLPOS]) # keep copy |
324 if p[OOCLPOS].isdigit() or p[OOCLPOS] == "STDOUT": | 324 if p[OOCLPOS].isdigit() or p[OOCLPOS].upper() == "STDOUT": |
325 scl = p[ONAMEPOS] | 325 scl = p[ONAMEPOS] |
326 p[OCLPOS] = scl | 326 p[OCLPOS] = scl |
327 self.outfiles[i] = p | 327 self.outfiles[i] = p |
328 for i, p in enumerate(self.addpar): | 328 for i, p in enumerate(self.addpar): |
329 if self.args.parampass == "positional": | 329 if self.args.parampass == "positional": |
367 for (o_v, k, v, koverride) in self.xclsuffix: | 367 for (o_v, k, v, koverride) in self.xclsuffix: |
368 aXCL(v) | 368 aXCL(v) |
369 if self.lastxclredirect: | 369 if self.lastxclredirect: |
370 aXCL(self.lastxclredirect[0]) | 370 aXCL(self.lastxclredirect[0]) |
371 aXCL(self.lastxclredirect[1]) | 371 aXCL(self.lastxclredirect[1]) |
372 if os.path.exists(self.tlog): | |
373 tout = open(self.tlog, "a") | |
374 else: | |
375 tout = open(self.tlog, "w") | |
376 tout.write(f" #### clpositional: self.clsuffix = {self.clsuffix} and self.xclsuffix = {self.xclsuffix}") | |
377 tout.close() | |
378 | 372 |
379 | 373 |
380 def clargparse(self): | 374 def clargparse(self): |
381 """argparse style""" | 375 """argparse style""" |
382 aCL = self.cl.append | 376 aCL = self.cl.append |
399 k = "-%s" % k | 393 k = "-%s" % k |
400 else: | 394 else: |
401 k = "--%s" % k | 395 k = "--%s" % k |
402 aCL(k) | 396 aCL(k) |
403 aCL(v) | 397 aCL(v) |
404 if os.path.exists(self.tlog): | |
405 tout = open(self.tlog, "a") | |
406 else: | |
407 tout = open(self.tlog, "w") | |
408 tout.write(f" #### clargparse: self.clsuffix = {self.clsuffix} and self.xclsuffix = {self.xclsuffix}") | |
409 tout.close() | |
410 | 398 |
411 | 399 |
412 def getNdash(self, newname): | 400 def getNdash(self, newname): |
413 if self.is_positional: | 401 if self.is_positional: |
414 ndash = 0 | 402 ndash = 0 |
425 test = test.strip() | 413 test = test.strip() |
426 ndash = self.getNdash(newcl) | 414 ndash = self.getNdash(newcl) |
427 aparm = gxtp.OutputData(name=newname, format=newfmt, num_dashes=ndash, label=newcl) | 415 aparm = gxtp.OutputData(name=newname, format=newfmt, num_dashes=ndash, label=newcl) |
428 aparm.positional = self.is_positional | 416 aparm.positional = self.is_positional |
429 if self.is_positional: | 417 if self.is_positional: |
430 if oldcl == "STDOUT": | 418 if oldcl.upper() == "STDOUT": |
431 aparm.positional = 9999999 | 419 aparm.positional = 9999999 |
432 aparm.command_line_override = "> $%s" % newname | 420 aparm.command_line_override = "> $%s" % newname |
433 else: | 421 else: |
434 aparm.positional = int(oldcl) | 422 aparm.positional = int(oldcl) |
435 aparm.command_line_override = "$%s" % newname | 423 aparm.command_line_override = "$%s" % newname |
601 ) | 589 ) |
602 self.newtool.version_command = None # do not want | 590 self.newtool.version_command = None # do not want |
603 requirements = gxtp.Requirements() | 591 requirements = gxtp.Requirements() |
604 if self.args.packages: | 592 if self.args.packages: |
605 for d in self.args.packages.split(","): | 593 for d in self.args.packages.split(","): |
594 ver = '' | |
595 d = d.replace('==',':') | |
596 d = d.replace('=',':') | |
606 if ":" in d: | 597 if ":" in d: |
607 packg, ver = d.split(":") | 598 packg, ver = d.split(":") |
608 else: | 599 else: |
609 packg = d | 600 packg = d |
610 ver = "" | |
611 requirements.append( | 601 requirements.append( |
612 gxtp.Requirement("package", packg.strip(), ver.strip()) | 602 gxtp.Requirement("package", packg.strip(), ver.strip()) |
613 ) | 603 ) |
614 self.newtool.requirements = requirements | 604 self.newtool.requirements = requirements |
615 if self.args.parampass == "0": | 605 if self.args.parampass == "0": |
749 def prun(container, tout, cl, user="biodocker"): | 739 def prun(container, tout, cl, user="biodocker"): |
750 rlog = container.exec_run(cl, user=user) | 740 rlog = container.exec_run(cl, user=user) |
751 slogl = str(rlog).split("\\n") | 741 slogl = str(rlog).split("\\n") |
752 slog = "\n".join(slogl) | 742 slog = "\n".join(slogl) |
753 tout.write(f"## got rlog {slog} from {cl}\n") | 743 tout.write(f"## got rlog {slog} from {cl}\n") |
744 | |
754 if os.path.exists(self.tlog): | 745 if os.path.exists(self.tlog): |
755 tout = open(self.tlog, "a") | 746 tout = open(self.tlog, "a") |
756 else: | 747 else: |
757 tout = open(self.tlog, "w") | 748 tout = open(self.tlog, "w") |
758 planemoimage = "quay.io/fubar2/planemo-biocontainer" | 749 planemoimage = "quay.io/fubar2/planemo-biocontainer" |
763 client = docker.from_env() | 754 client = docker.from_env() |
764 tvol = client.volumes.create() | 755 tvol = client.volumes.create() |
765 tvolname = tvol.name | 756 tvolname = tvol.name |
766 destdir = "/toolfactory/ptest" | 757 destdir = "/toolfactory/ptest" |
767 imrep = os.path.join(destdir, repname) | 758 imrep = os.path.join(destdir, repname) |
768 # need to keep the container running so sleep a while - we stop and destroy it when we are done | 759 # need to keep the container running so keep it open with tail -f. |
760 # will stop and destroy it when we are done | |
769 container = client.containers.run( | 761 container = client.containers.run( |
770 planemoimage, | 762 planemoimage, |
771 "sleep 30m", | 763 "tail -f /galaxy-central/CITATION", |
772 detach=True, | 764 detach=True, |
773 user="biodocker", | 765 user="biodocker", |
774 volumes={f"{tvolname}": {"bind": "/toolfactory", "mode": "rw"}}, | 766 volumes={f"{tvolname}": {"bind": "/toolfactory", "mode": "rw"}}, |
775 ) | 767 ) |
776 cl = f"mkdir -p {destdir}" | 768 cl = f"mkdir -p {destdir}" |
777 prun(container, tout, cl, user="root") | 769 prun(container, tout, cl, user="root") |
770 # that's how hard it is to get root on a biodocker container :( | |
778 cl = f"rm -rf {destdir}/*" | 771 cl = f"rm -rf {destdir}/*" |
779 prun(container, tout, cl, user="root") | 772 prun(container, tout, cl, user="root") |
780 ptestpath = os.path.join(destdir, "tfout", xreal) | 773 ptestpath = os.path.join(destdir, "tfout", xreal) |
781 self.copy_to_container(self.tooloutdir, destdir, container) | 774 self.copy_to_container(self.tooloutdir, destdir, container) |
782 cl = "chown -R biodocker /toolfactory" | 775 cl = "chown -R biodocker /toolfactory" |
783 prun(container, tout, cl, user="root") | 776 prun(container, tout, cl, user="root") |
784 rlog = container.exec_run(f"ls -la {destdir}") | 777 rlog = container.exec_run(f"ls -la {destdir}") |
785 ptestcl = f"planemo test --update_test_data --no_cleanup --test_data {destdir}/tfout/test-data --galaxy_root /home/biodocker/galaxy-central {ptestpath}" | 778 ptestcl = f"planemo test --update_test_data --no_cleanup --test_data {destdir}/tfout/test-data --galaxy_root /home/biodocker/galaxy-central {ptestpath}" |
786 try: | 779 try: |
787 rlog = container.exec_run(ptestcl) | 780 rlog = container.exec_run(ptestcl) |
781 # fails because test outputs missing but updates the test-data directory | |
788 except: | 782 except: |
789 e = sys.exc_info()[0] | 783 e = sys.exc_info()[0] |
790 tout.write(f"#### error: {e} from {ptestcl}\n") | 784 tout.write(f"#### error: {e} from {ptestcl}\n") |
791 # fails - used to generate test outputs | |
792 cl = f"planemo test --test_output {imrep} --no_cleanup --test_data {destdir}/tfout/test-data --galaxy_root /home/biodocker/galaxy-central {ptestpath}" | 785 cl = f"planemo test --test_output {imrep} --no_cleanup --test_data {destdir}/tfout/test-data --galaxy_root /home/biodocker/galaxy-central {ptestpath}" |
793 try: | 786 try: |
794 prun(container, tout, cl) | 787 prun(container, tout, cl) |
795 except: | 788 except: |
796 pass | 789 pass |
806 tout.write(f"No output from run to shutil.copytree in {src}\n") | 799 tout.write(f"No output from run to shutil.copytree in {src}\n") |
807 tout.close() | 800 tout.close() |
808 container.stop() | 801 container.stop() |
809 container.remove() | 802 container.remove() |
810 tvol.remove() | 803 tvol.remove() |
811 # shutil.rmtree(testouts) | 804 # shutil.rmtree(testouts) leave for debugging |
812 | 805 |
813 def shedLoad(self): | 806 def shedLoad(self): |
814 """ | 807 """ |
815 {'deleted': False, | 808 use bioblend to create new repository |
816 'description': 'Tools for manipulating data', | 809 or update existing |
817 'id': '175812cd7caaf439', | |
818 'model_class': 'Category', | |
819 'name': 'Text Manipulation', | |
820 'url': '/api/categories/175812cd7caaf439'}] | |
821 | |
822 | 810 |
823 """ | 811 """ |
824 if os.path.exists(self.tlog): | 812 if os.path.exists(self.tlog): |
825 sto = open(self.tlog, "a") | 813 sto = open(self.tlog, "a") |
826 else: | 814 else: |
849 remote_repository_url=self.args.toolshed_url, | 837 remote_repository_url=self.args.toolshed_url, |
850 homepage_url=None, | 838 homepage_url=None, |
851 category_ids=catID, | 839 category_ids=catID, |
852 ) | 840 ) |
853 tid = res.get("id", None) | 841 tid = res.get("id", None) |
854 sto.write(f"#####create_repository {self.args.tool_name} tid={tid} res={res}\n") | 842 sto.write(f"#create_repository {self.args.tool_name} tid={tid} res={res}\n") |
855 else: | 843 else: |
856 i = rnames.index(self.tool_name) | 844 i = rnames.index(self.tool_name) |
857 tid = rids[i] | 845 tid = rids[i] |
858 try: | 846 try: |
859 res = ts.repositories.update_repository( | 847 res = ts.repositories.update_repository( |
860 id=tid, tar_ball_path=self.newtarpath, commit_message=None | 848 id=tid, tar_ball_path=self.newtarpath, commit_message=None |
861 ) | 849 ) |
862 sto.write(f"#####update res id {id} ={res}\n") | 850 sto.write(f"#update res id {id} ={res}\n") |
863 except ConnectionError: | 851 except ConnectionError: |
864 sto.write( | 852 sto.write( |
865 "Is the toolshed running and the API key correct? Bioblend shed upload failed\n" | 853 "####### Is the toolshed running and the API key correct? Bioblend shed upload failed\n" |
866 ) | 854 ) |
867 sto.close() | 855 sto.close() |
868 | 856 |
869 def eph_galaxy_load(self): | 857 def eph_galaxy_load(self): |
870 """load the new tool from the local toolshed after planemo uploads it""" | 858 """ |
859 use ephemeris to load the new tool from the local toolshed after planemo uploads it | |
860 """ | |
871 if os.path.exists(self.tlog): | 861 if os.path.exists(self.tlog): |
872 tout = open(self.tlog, "a") | 862 tout = open(self.tlog, "a") |
873 else: | 863 else: |
874 tout = open(self.tlog, "w") | 864 tout = open(self.tlog, "w") |
875 cll = [ | 865 cll = [ |
1032 a("--galaxy_api_key", default="fakekey") | 1022 a("--galaxy_api_key", default="fakekey") |
1033 a("--galaxy_root", default="/galaxy-central") | 1023 a("--galaxy_root", default="/galaxy-central") |
1034 a("--galaxy_venv", default="/galaxy_venv") | 1024 a("--galaxy_venv", default="/galaxy_venv") |
1035 args = parser.parse_args() | 1025 args = parser.parse_args() |
1036 assert not args.bad_user, ( | 1026 assert not args.bad_user, ( |
1037 'UNAUTHORISED: %s is NOT authorized to use this tool until Galaxy admin adds %s to "admin_users" in the Galaxy configuration file' | 1027 'UNAUTHORISED: %s is NOT authorized to use this tool until Galaxy admin adds %s to "admin_users" in the galaxy.yml Galaxy configuration file' |
1038 % (args.bad_user, args.bad_user) | 1028 % (args.bad_user, args.bad_user) |
1039 ) | 1029 ) |
1040 assert args.tool_name, "## Tool Factory expects a tool name - eg --tool_name=DESeq" | 1030 assert args.tool_name, "## Tool Factory expects a tool name - eg --tool_name=DESeq" |
1041 assert ( | 1031 assert ( |
1042 args.sysexe or args.packages | 1032 args.sysexe or args.packages |