diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 449402cb7bc..a864a68b05c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -158,7 +158,7 @@ https://help.github.com/en/github/getting-started-with-github/git-and-github-lea particular emphasis on readability being the ultimate goal: - 4 spaces (not tabs!) per indentation level - divergences from PEP-8 are listed in the `[flake8]` section of the - `setup.cfg` file + `.flake8` file - The Python code base is automatically formatted using [isort](https://pycqa.github.io/isort/) (for imports) and [black](https://black.readthedocs.io). To easily format your Python code diff --git a/contrib/galaxy_config_merger.py b/contrib/galaxy_config_merger.py index f7d60f183aa..229fb57af6b 100644 --- a/contrib/galaxy_config_merger.py +++ b/contrib/galaxy_config_merger.py @@ -6,21 +6,6 @@ Created by Anne Pajon on 31 Jan 2012 Copyright (c) 2012 Cancer Research UK - Cambridge Research Institute. -This source file is licensed under the Academic Free License version -3.0 available at http://www.opensource.org/licenses/AFL-3.0. - -Permission is hereby granted to reproduce, translate, adapt, alter, -transform, modify, or arrange this source file (the "Original Work"); -to distribute or communicate copies of it under any license of your -choice that does not contradict the terms and conditions; to perform -or display the Original Work publicly. - -THE ORIGINAL WORK IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS -AND WITHOUT WARRANTY, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT -LIMITATION, THE WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR -FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF -THE ORIGINAL WORK IS WITH YOU. - Script for merging specific local Galaxy config galaxy.ini.cri with default Galaxy galaxy.ini.sample """ diff --git a/lib/galaxy/job_execution/output_collect.py b/lib/galaxy/job_execution/output_collect.py index a06c9c231e8..066681c2eb0 100644 --- a/lib/galaxy/job_execution/output_collect.py +++ b/lib/galaxy/job_execution/output_collect.py @@ -646,7 +646,7 @@ class DatasetCollector: def __init__(self, dataset_collection_description): self.discover_via = dataset_collection_description.discover_via # dataset_collection_description is an abstract description - # built from the tool parsing module - see galaxy.tool_util.parser.output_colleciton_def + # built from the tool parsing module - see galaxy.tool_util.parser.output_collection_def self.sort_key = dataset_collection_description.sort_key self.sort_reverse = dataset_collection_description.sort_reverse self.sort_comp = dataset_collection_description.sort_comp diff --git a/lib/galaxy/jobs/__init__.py b/lib/galaxy/jobs/__init__.py index 07f912d45b5..b6d99043eba 100644 --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -2128,10 +2128,8 @@ class MinimalJobWrapper(HasResourceParameters): raise Exception(f"Unknown target type [{target}]") def get_tool_provided_job_metadata(self): - if self.tool_provided_job_metadata is not None: - return self.tool_provided_job_metadata - - self.tool_provided_job_metadata = self.tool.tool_provided_metadata(self) + if self.tool_provided_job_metadata is None: + self.tool_provided_job_metadata = self.tool.tool_provided_metadata(self) return self.tool_provided_job_metadata def get_dataset_finish_context(self, job_context, output_dataset_assoc): diff --git a/lib/galaxy/tool_util/toolbox/base.py b/lib/galaxy/tool_util/toolbox/base.py index d32754f782d..d606a493cdf 100644 --- a/lib/galaxy/tool_util/toolbox/base.py +++ b/lib/galaxy/tool_util/toolbox/base.py @@ -1322,9 +1322,9 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): def _tool_from_lineage_version(self, lineage_tool_version): if lineage_tool_version.id_based: - return self._tools_by_id.get(lineage_tool_version.id, None) + return self._tools_by_id.get(lineage_tool_version.id) else: - return self._tool_versions_by_id.get(lineage_tool_version.id, {}).get(lineage_tool_version.version, None) + return self._tool_versions_by_id.get(lineage_tool_version.id, {}).get(lineage_tool_version.version) def _build_filter_method(self, trans): context = Bunch(toolbox=self, trans=trans) diff --git a/lib/galaxy/tool_util/verify/interactor.py b/lib/galaxy/tool_util/verify/interactor.py index 7b8ccd52f8a..28627ac8d0c 100644 --- a/lib/galaxy/tool_util/verify/interactor.py +++ b/lib/galaxy/tool_util/verify/interactor.py @@ -1332,14 +1332,6 @@ def _verify_outputs(testdef, history, jobs, data_list, data_collection_list, gal job_stdio = galaxy_interactor.get_job_stdio(job["id"]) - if testdef.num_outputs is not None: - expected = testdef.num_outputs - actual = len(data_list) + len(data_collection_list) - if expected != actual: - message = f"Incorrect number of outputs - expected {expected}, found {actual}: datasets {data_list.keys()} collections {data_collection_list.keys()}" - error = AssertionError(message) - register_exception(error) - if testdef.num_outputs is not None: expected = testdef.num_outputs actual = len(data_list) + len(data_collection_list) diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py index aa1255d592c..988a040e36c 100644 --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -3528,7 +3528,7 @@ class RelabelFromFileTool(DatabaseOperationTool): add_copied_value_to_new_elements(new_labels[i], dce_object) for key in new_elements.keys(): if not re.match(r"^[\w\- \.,]+$", key): - raise Exception(f"Invalid new colleciton identifier [{key}]") + raise Exception(f"Invalid new collection identifier [{key}]") self._add_datasets_to_history(history, new_elements.values()) output_collections.create_collection( next(iter(self.outputs.values())), "output", elements=new_elements, propagate_hda_tags=False diff --git a/lib/galaxy/tools/execute.py b/lib/galaxy/tools/execute.py index b64f91ec873..f0bb67bcb9b 100644 --- a/lib/galaxy/tools/execute.py +++ b/lib/galaxy/tools/execute.py @@ -33,7 +33,7 @@ if typing.TYPE_CHECKING: log = logging.getLogger(__name__) SINGLE_EXECUTION_SUCCESS_MESSAGE = "Tool ${tool_id} created job ${job_id}" -BATCH_EXECUTION_MESSAGE = "Executed ${job_count} job(s) for tool ${tool_id} request" +BATCH_EXECUTION_MESSAGE = "Created ${job_count} job(s) for tool ${tool_id} request" class PartialJobExecution(Exception): diff --git a/lib/galaxy/webapps/base/webapp.py b/lib/galaxy/webapps/base/webapp.py index 2ac753025e5..19b6f457313 100644 --- a/lib/galaxy/webapps/base/webapp.py +++ b/lib/galaxy/webapps/base/webapp.py @@ -19,6 +19,7 @@ from urllib.parse import urlparse import mako.lookup import mako.runtime from apispec import APISpec +from paste.urlmap import URLMap from sqlalchemy import ( and_, true, @@ -47,6 +48,7 @@ from galaxy.web.framework import ( helpers, url_for, ) +from galaxy.web.framework.middleware.static import CacheableStaticURLParser as Static try: from importlib.resources import files # type: ignore[attr-defined] @@ -1114,10 +1116,6 @@ def default_url_path(path): def build_url_map(app, global_conf, **local_conf): - from paste.urlmap import URLMap - - from galaxy.web.framework.middleware.static import CacheableStaticURLParser as Static - urlmap = URLMap() # Merge the global and local configurations conf = global_conf.copy() diff --git a/lib/galaxy/webapps/galaxy/api/jobs.py b/lib/galaxy/webapps/galaxy/api/jobs.py index d418ce5b3cf..4dfb1bfc9e9 100644 --- a/lib/galaxy/webapps/galaxy/api/jobs.py +++ b/lib/galaxy/webapps/galaxy/api/jobs.py @@ -260,7 +260,7 @@ class JobController(BaseGalaxyAPIController, UsesVisualizationMixin): return {"has_empty_inputs": has_empty_inputs, "has_duplicate_inputs": has_duplicate_inputs} @expose_api - def inputs(self, trans: ProvidesUserContext, id, **kwd): + def inputs(self, trans: ProvidesUserContext, id, **kwd) -> List[dict]: """ GET /api/jobs/{id}/inputs @@ -269,14 +269,14 @@ class JobController(BaseGalaxyAPIController, UsesVisualizationMixin): :type id: string :param id: Encoded job id - :rtype: dictionary - :returns: dictionary containing input dataset associations + :rtype: list of dicts + :returns: list of dictionaries containing input dataset associations """ job = self.__get_job(trans, id) return self.__dictify_associations(trans, job.input_datasets, job.input_library_datasets) @expose_api - def outputs(self, trans: ProvidesUserContext, id, **kwd): + def outputs(self, trans: ProvidesUserContext, id, **kwd) -> List[dict]: """ outputs( trans, id ) * GET /api/jobs/{id}/outputs @@ -285,8 +285,8 @@ class JobController(BaseGalaxyAPIController, UsesVisualizationMixin): :type id: string :param id: Encoded job id - :rtype: dictionary - :returns: dictionary containing output dataset associations + :rtype: list of dicts + :returns: list of dictionaries containing output dataset associations """ job = self.__get_job(trans, id) return self.__dictify_associations(trans, job.output_datasets, job.output_library_datasets) @@ -309,7 +309,7 @@ class JobController(BaseGalaxyAPIController, UsesVisualizationMixin): return self.job_manager.stop(job, message=message) @expose_api - def resume(self, trans: ProvidesUserContext, id, **kwd): + def resume(self, trans: ProvidesUserContext, id, **kwd) -> List[dict]: """ * PUT /api/jobs/{id}/resume Resumes a paused job @@ -317,8 +317,8 @@ class JobController(BaseGalaxyAPIController, UsesVisualizationMixin): :type id: string :param id: Encoded job id - :rtype: dictionary - :returns: dictionary containing output dataset associations + :rtype: list of dicts + :returns: list of dictionaries containing output dataset associations """ job = self.__get_job(trans, id) if not job: @@ -425,13 +425,13 @@ class JobController(BaseGalaxyAPIController, UsesVisualizationMixin): raise exceptions.ConfigDoesNotAllowException(f"Tool '{job.tool_id}' cannot be rerun.") return tool.to_json(trans, {}, job=job) - def __dictify_associations(self, trans, *association_lists): - rval = [] + def __dictify_associations(self, trans, *association_lists) -> List[dict]: + rval: List[dict] = [] for association_list in association_lists: rval.extend(self.__dictify_association(trans, a) for a in association_list) return rval - def __dictify_association(self, trans, job_dataset_association): + def __dictify_association(self, trans, job_dataset_association) -> dict: dataset_dict = None dataset = job_dataset_association.dataset if dataset: diff --git a/lib/galaxy_test/api/test_history_contents.py b/lib/galaxy_test/api/test_history_contents.py index fc6beed6627..50bb1ea9b25 100644 --- a/lib/galaxy_test/api/test_history_contents.py +++ b/lib/galaxy_test/api/test_history_contents.py @@ -434,7 +434,7 @@ class HistoryContentsApiTestCase(ApiTestCase): assert post_combined_count == pre_combined_count + 1 assert pre_dataset_count == post_dataset_count - # Test show dataset colleciton. + # Test show dataset collection. collection_url = f"histories/{self.history_id}/contents/dataset_collections/{dataset_collection['id']}" show_response = self._get(collection_url) self._assert_status_code_is(show_response, 200) diff --git a/lib/galaxy_test/base/populators.py b/lib/galaxy_test/base/populators.py index f7a7c188c64..5971780112a 100644 --- a/lib/galaxy_test/base/populators.py +++ b/lib/galaxy_test/base/populators.py @@ -2662,7 +2662,7 @@ class BaseDatasetCollectionPopulator: return element_identifiers def __create(self, payload, wait=False): - # Create a colleciton - either from existing datasets using collection creation API + # Create a collection - either from existing datasets using collection creation API # or from direct uploads with the fetch API. Dispatch on "targets" keyword in payload # to decide which to use. if "targets" not in payload: diff --git a/lib/tool_shed/test/base/twilltestcase.py b/lib/tool_shed/test/base/twilltestcase.py index de90dcf0d0b..403af4d246c 100644 --- a/lib/tool_shed/test/base/twilltestcase.py +++ b/lib/tool_shed/test/base/twilltestcase.py @@ -43,8 +43,6 @@ from . import ( # Set a 10 minute timeout for repository installation. repository_installation_timeout = 600 -# Dial ClientCookie logging down (very noisy) -logging.getLogger("ClientCookie.cookies").setLevel(logging.WARNING) log = logging.getLogger(__name__) tc.options["equiv_refresh_interval"] = 0 diff --git a/lib/tool_shed/util/shed_util_common.py b/lib/tool_shed/util/shed_util_common.py index 070917f05a9..68ae530f123 100644 --- a/lib/tool_shed/util/shed_util_common.py +++ b/lib/tool_shed/util/shed_util_common.py @@ -212,16 +212,17 @@ def get_repository_file_contents(app, file_path, repository_id, is_admin=False): elif checkers.check_binary(file_path): return "
Binary file
" else: - for line in open(file_path): - safe_str = f"{safe_str}{basic_util.to_html_string(line)}" - # Stop reading after string is larger than MAX_CONTENT_SIZE. - if len(safe_str) > MAX_CONTENT_SIZE: - large_str = ( - "
File contents truncated because file size is larger than maximum viewing size of %s
" - % util.nice_size(MAX_CONTENT_SIZE) - ) - safe_str = f"{safe_str}{large_str}" - break + with open(file_path) as fh: + for line in fh: + safe_str = f"{safe_str}{basic_util.to_html_string(line)}" + # Stop reading after string is larger than MAX_CONTENT_SIZE. + if len(safe_str) > MAX_CONTENT_SIZE: + large_str = ( + "
File contents truncated because file size is larger than maximum viewing size of %s
" + % util.nice_size(MAX_CONTENT_SIZE) + ) + safe_str = f"{safe_str}{large_str}" + break if len(safe_str) > basic_util.MAX_DISPLAY_SIZE: # Eliminate the middle of the file to display a file no larger than basic_util.MAX_DISPLAY_SIZE. diff --git a/lib/tool_shed/webapp/model/__init__.py b/lib/tool_shed/webapp/model/__init__.py index 52def04404b..e0989af283c 100644 --- a/lib/tool_shed/webapp/model/__init__.py +++ b/lib/tool_shed/webapp/model/__init__.py @@ -11,6 +11,10 @@ from typing import ( TYPE_CHECKING, ) +from mercurial import ( + hg, + ui, +) from sqlalchemy import ( Boolean, Column, @@ -414,11 +418,6 @@ class Repository(Base, Dictifiable, _HasTable): @property def hg_repo(self): - from mercurial import ( - hg, - ui, - ) - if not WEAK_HG_REPO_CACHE.get(self): WEAK_HG_REPO_CACHE[self] = hg.cachedlocalrepo(hg.repository(ui.ui(), self.repo_path().encode("utf-8"))) return WEAK_HG_REPO_CACHE[self].fetch()[0] diff --git a/pyproject.toml b/pyproject.toml index 96be89e3f10..29425a1bc79 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ cwltool = "==3.1.20211107152837" dictobj = "*" docutils = "!=0.17, !=0.17.1" edam-ontology = "*" -fastapi = ">=0.68.2, !=0.69.0, !=0.70.0, !=0.70.1" # https://github.com/tiangolo/fastapi/issues/4041 +fastapi = ">=0.71.0" # https://github.com/tiangolo/fastapi/issues/4041 fastapi-utils = "*" fs = "*" future = "*"