From 57e97db9ffbcf131f1168cb3e9c9cfff00961fd4 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Wed, 5 Nov 2025 00:15:42 +0000 Subject: [PATCH] Drop support for Python 3.9 which has reached end of life on 2025-10-31. --- .github/workflows/lint.yaml | 2 +- .github/workflows/test.yaml | 40 ++++---- ABOUT.rst | 2 +- CHANGELOG.md | 4 + CONTRIBUTING.md | 2 +- README.rst | 2 +- bioblend/__init__.py | 10 +- .../_tests/TestGalaxyDatasetCollections.py | 3 +- bioblend/_tests/TestGalaxyObjects.py | 7 +- bioblend/_tests/TestGalaxyWorkflows.py | 3 +- bioblend/_tests/TestToolshed.py | 1 - bioblend/_tests/pytest_galaxy_test_wrapper.py | 3 +- bioblend/_tests/test_util.py | 9 +- bioblend/config.py | 3 +- bioblend/galaxy/__init__.py | 12 +-- bioblend/galaxy/client.py | 51 +++++----- .../galaxy/container_resolution/__init__.py | 24 +++-- .../galaxy/dataset_collections/__init__.py | 9 +- bioblend/galaxy/datasets/__init__.py | 40 ++++---- bioblend/galaxy/folders/__init__.py | 14 ++- bioblend/galaxy/genomes/__init__.py | 21 ++-- bioblend/galaxy/groups/__init__.py | 9 +- bioblend/galaxy/histories/__init__.py | 95 +++++++++---------- bioblend/galaxy/invocations/__init__.py | 35 ++++--- bioblend/galaxy/jobs/__init__.py | 25 +++-- bioblend/galaxy/libraries/__init__.py | 54 +++++------ bioblend/galaxy/objects/client.py | 42 ++++---- bioblend/galaxy/objects/galaxy_instance.py | 11 +-- bioblend/galaxy/objects/wrappers.py | 38 ++++---- bioblend/galaxy/quotas/__init__.py | 23 +++-- bioblend/galaxy/roles/__init__.py | 5 +- bioblend/galaxy/tool_dependencies/__init__.py | 9 +- bioblend/galaxy/tools/__init__.py | 28 +++--- bioblend/galaxy/tools/inputs.py | 6 +- bioblend/galaxy/toolshed/__init__.py | 8 +- bioblend/galaxy/users/__init__.py | 9 +- bioblend/galaxy/workflows/__init__.py | 41 ++++---- bioblend/galaxyclient.py | 36 ++++--- bioblend/toolshed/__init__.py | 10 +- bioblend/toolshed/repositories/__init__.py | 38 ++++---- bioblend/util/__init__.py | 3 +- pyproject.toml | 7 +- run_bioblend_tests.sh | 4 +- tox.ini | 2 +- 44 files changed, 375 insertions(+), 425 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index c192f9027..d9152a79e 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.14'] + python-version: ['3.10', '3.14'] steps: - uses: actions/checkout@v5 with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 18405ab90..b3107ad95 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -31,86 +31,86 @@ jobs: matrix: include: - os: ubuntu-latest - tox_env: py39 + tox_env: py310 galaxy_version: dev galaxy_python_version: '3.9' - os: ubuntu-latest - tox_env: py39 + tox_env: py310 galaxy_version: release_25.1 galaxy_python_version: '3.9' - os: ubuntu-latest - tox_env: py39 + tox_env: py310 galaxy_version: release_25.0 galaxy_python_version: '3.9' - os: ubuntu-latest - tox_env: py39 + tox_env: py310 galaxy_version: release_24.2 galaxy_python_version: '3.8' - os: ubuntu-latest - tox_env: py39 + tox_env: py310 galaxy_version: release_24.1 galaxy_python_version: '3.8' - os: ubuntu-latest - tox_env: py39 + tox_env: py310 galaxy_version: release_24.0 galaxy_python_version: '3.8' # Python 3.7 is not available via setup-python on ubuntu >=24.04 - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_23.2 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_23.1 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_23.0 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_22.05 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_22.01 galaxy_python_version: '3.7' # The minimum Python supported version by the following releases is # 3.6, but it is EOL - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_21.09 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_21.05 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_21.01 galaxy_python_version: '3.7' # The minimum Python supported version by the following releases is # 3.5, but it is EOL - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_20.09 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_20.05 galaxy_python_version: '3.7' # The minimum Python supported version by the following releases is # 2.7, but it is EOL - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_20.01 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_19.09 galaxy_python_version: '3.7' - os: ubuntu-22.04 - tox_env: py39 + tox_env: py310 galaxy_version: release_19.05 galaxy_python_version: '3.7' - os: ubuntu-latest @@ -120,7 +120,7 @@ jobs: # Cannot test on macOS because service containers are not supported # yet: https://github.community/t/github-actions-services-available-on-others-vms/16916 # - os: macos-latest - # tox_env: py39 + # tox_env: py310 # galaxy_version: dev # galaxy_python_version: '3.8' steps: diff --git a/ABOUT.rst b/ABOUT.rst index da11a4ebe..78619dde6 100644 --- a/ABOUT.rst +++ b/ABOUT.rst @@ -3,7 +3,7 @@ interacting with the `Galaxy`_ API. BioBlend is supported and tested on: -- Python 3.9 - 3.14 +- Python 3.10 - 3.14 - Galaxy release 19.05 and later. BioBlend's goal is to make it easier to script and automate the running of diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b787206..d1408ef91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## BioBlend v + +* Dropped support for Python 3.9. + ## BioBlend v1.7.0 - 2025-11-07 * Deprecation: this is the last release to support end-of-life Python 3.9. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9210ecf48..2a54493a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,7 @@ How to run BioBlend tests 1. Clone Galaxy to a directory outside of BioBlend source directory via `git clone https://github.com/galaxyproject/galaxy.git` -2. Change directory to your BioBlend source and run the tests via `./run_bioblend_tests.sh -g GALAXY_PATH [-r GALAXY_REV] [-e TOX_ENV]` where `GALAXY_PATH` is the directory where the galaxy repository was cloned, `GALAXY_REV` is the branch or commit of Galaxy that you would like to test against (if different from the current state of your galaxy clone), and `TOX_ENV` is used to specify the Python version to use for BioBlend, e.g. `py39` for Python 3.9. +2. Change directory to your BioBlend source and run the tests via `./run_bioblend_tests.sh -g GALAXY_PATH [-r GALAXY_REV] [-e TOX_ENV]` where `GALAXY_PATH` is the directory where the galaxy repository was cloned, `GALAXY_REV` is the branch or commit of Galaxy that you would like to test against (if different from the current state of your galaxy clone), and `TOX_ENV` is used to specify the Python version to use for BioBlend, e.g. `py310` for Python 3.10. You can also add `2>&1 | tee log.txt` to the command above to contemporarily view the test output and save it to the `log.txt` file. diff --git a/README.rst b/README.rst index e402bc53c..8d6686fdd 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ BioBlend is a Python library for interacting with the `Galaxy`_ API. BioBlend is supported and tested on: -- Python 3.9 - 3.14 +- Python 3.10 - 3.14 - Galaxy release 19.05 and later. Full docs are available at https://bioblend.readthedocs.io/ with a quick library diff --git a/bioblend/__init__.py b/bioblend/__init__.py index 63ee26e6b..9b75a83c4 100644 --- a/bioblend/__init__.py +++ b/bioblend/__init__.py @@ -3,11 +3,9 @@ import logging.config import os import time +from collections.abc import Callable from typing import ( - Callable, - Optional, TypeVar, - Union, ) from bioblend.config import ( @@ -68,7 +66,7 @@ def emit(self, record: logging.LogRecord) -> None: def set_file_logger( - name: str, filepath: str, level: Union[int, str] = logging.INFO, format_string: Optional[str] = None + name: str, filepath: str, level: int | str = logging.INFO, format_string: str | None = None ) -> None: global log if not format_string: @@ -83,7 +81,7 @@ def set_file_logger( log = logger -def set_stream_logger(name: str, level: Union[int, str] = logging.DEBUG, format_string: Optional[str] = None) -> None: +def set_stream_logger(name: str, level: int | str = logging.DEBUG, format_string: str | None = None) -> None: global log if not format_string: format_string = default_format_string @@ -107,7 +105,7 @@ class ConnectionError(Exception): """ def __init__( # noqa: B042 # https://github.com/PyCQA/flake8-bugbear/issues/525 - self, message: str, body: Optional[Union[bytes, str]] = None, status_code: Optional[int] = None + self, message: str, body: bytes | str | None = None, status_code: int | None = None ) -> None: super().__init__(message) self.body = body diff --git a/bioblend/_tests/TestGalaxyDatasetCollections.py b/bioblend/_tests/TestGalaxyDatasetCollections.py index 2f54b01fe..1b32a1973 100644 --- a/bioblend/_tests/TestGalaxyDatasetCollections.py +++ b/bioblend/_tests/TestGalaxyDatasetCollections.py @@ -4,7 +4,6 @@ from inspect import signature from typing import ( Any, - Union, ) from zipfile import ZipFile @@ -166,7 +165,7 @@ def test_download_dataset_collection(self): os.mkdir(extract_dir_path) if archive_type == "zip": - archive: Union[ZipFile, tarfile.TarFile] = ZipFile(archive_path) + archive: ZipFile | tarfile.TarFile = ZipFile(archive_path) elif archive_type == "tgz": archive = tarfile.open(archive_path) diff --git a/bioblend/_tests/TestGalaxyObjects.py b/bioblend/_tests/TestGalaxyObjects.py index 0739d8949..7cb73a73e 100644 --- a/bioblend/_tests/TestGalaxyObjects.py +++ b/bioblend/_tests/TestGalaxyObjects.py @@ -9,15 +9,14 @@ import unittest import uuid from collections.abc import ( + Callable, Collection, Iterable, ) from ssl import SSLError from typing import ( Any, - Callable, Literal, - Union, ) from urllib.error import URLError from urllib.request import urlopen @@ -128,7 +127,7 @@ def is_reachable(url: str) -> bool: res = None try: res = urlopen(url, timeout=5) - except (SSLError, URLError, socket.timeout): + except (SSLError, URLError, TimeoutError): return False if res is not None: res.close() @@ -990,7 +989,7 @@ def tearDown(self): def _test(self, existing_hist: bool = False, pass_params: bool = False) -> None: hist_name = f"test_{uuid.uuid4().hex}" if existing_hist: - hist: Union[str, wrappers.History] = self.gi.histories.create(hist_name) + hist: str | wrappers.History = self.gi.histories.create(hist_name) else: hist = hist_name if pass_params: diff --git a/bioblend/_tests/TestGalaxyWorkflows.py b/bioblend/_tests/TestGalaxyWorkflows.py index 3a581d101..565b9f742 100644 --- a/bioblend/_tests/TestGalaxyWorkflows.py +++ b/bioblend/_tests/TestGalaxyWorkflows.py @@ -6,7 +6,6 @@ from typing import ( Any, Literal, - Optional, ) import pytest @@ -155,7 +154,7 @@ def test_import_other_users_published_workflow(self) -> None: assert not imported_wf_by_new_user["deleted"] assert not imported_wf_by_new_user["published"] - def _import_export(self, style: Optional[Literal["ga", "format2"]] = None): + def _import_export(self, style: Literal["ga", "format2"] | None = None): path = test_util.get_abspath(os.path.join("data", "paste_columns.ga")) with open(path) as f: wf_dict = json.load(f) diff --git a/bioblend/_tests/TestToolshed.py b/bioblend/_tests/TestToolshed.py index 97cc2bb0f..f8b8602f1 100644 --- a/bioblend/_tests/TestToolshed.py +++ b/bioblend/_tests/TestToolshed.py @@ -1,7 +1,6 @@ import os import unittest -import bioblend import bioblend.toolshed from . import test_util diff --git a/bioblend/_tests/pytest_galaxy_test_wrapper.py b/bioblend/_tests/pytest_galaxy_test_wrapper.py index 0af83a1e9..a7c56ab36 100755 --- a/bioblend/_tests/pytest_galaxy_test_wrapper.py +++ b/bioblend/_tests/pytest_galaxy_test_wrapper.py @@ -8,7 +8,6 @@ import sys from typing import ( NoReturn, - Optional, ) try: @@ -28,7 +27,7 @@ ] -def main(args: Optional[list[str]] = None) -> NoReturn: +def main(args: list[str] | None = None) -> NoReturn: """Entry point that delegates to pytest.main.""" if pytest is None: raise Exception("pytest is required to use this script.") diff --git a/bioblend/_tests/test_util.py b/bioblend/_tests/test_util.py index 879c58489..19805a50b 100644 --- a/bioblend/_tests/test_util.py +++ b/bioblend/_tests/test_util.py @@ -4,11 +4,8 @@ import random import string import unittest -from typing import ( - Any, - Callable, - Optional, -) +from collections.abc import Callable +from typing import Any import requests @@ -43,7 +40,7 @@ def skip_unless_toolshed() -> Callable: return lambda f: f -def skip_unless_galaxy(min_release: Optional[str] = None) -> Callable: +def skip_unless_galaxy(min_release: str | None = None) -> Callable: """Decorate tests with this to skip the test if Galaxy is not configured. """ diff --git a/bioblend/config.py b/bioblend/config.py index c77aa3dcc..d37a13872 100644 --- a/bioblend/config.py +++ b/bioblend/config.py @@ -2,7 +2,6 @@ import os from typing import ( IO, - Optional, ) BioBlendConfigPath = "/etc/bioblend.cfg" @@ -21,7 +20,7 @@ class Config(configparser.ConfigParser): * Individual user: ``~/.bioblend`` (which works on both Windows and Unix) """ - def __init__(self, path: Optional[str] = None, fp: Optional[IO[str]] = None, do_load: bool = True) -> None: + def __init__(self, path: str | None = None, fp: IO[str] | None = None, do_load: bool = True) -> None: super().__init__({"working_dir": "/mnt/pyami", "debug": "0"}) if do_load: if path: diff --git a/bioblend/galaxy/__init__.py b/bioblend/galaxy/__init__.py index b04911b5c..b2dd16a8b 100644 --- a/bioblend/galaxy/__init__.py +++ b/bioblend/galaxy/__init__.py @@ -2,8 +2,6 @@ A base representation of an instance of Galaxy """ -from typing import Optional - from bioblend.galaxy import ( config, container_resolution, @@ -36,13 +34,13 @@ class GalaxyInstance(GalaxyClient): def __init__( self, url: str, - key: Optional[str] = None, - email: Optional[str] = None, - password: Optional[str] = None, + key: str | None = None, + email: str | None = None, + password: str | None = None, *, - token: Optional[str] = None, + token: str | None = None, verify: bool = True, - user_agent: Optional[str] = None, + user_agent: str | None = None, ) -> None: """ A base representation of a connection to a Galaxy instance, identified diff --git a/bioblend/galaxy/client.py b/bioblend/galaxy/client.py index 36e781a12..66f0521e1 100644 --- a/bioblend/galaxy/client.py +++ b/bioblend/galaxy/client.py @@ -9,7 +9,6 @@ from typing import ( Any, Literal, - Optional, overload, TYPE_CHECKING, ) @@ -58,7 +57,7 @@ def __init__(self, galaxy_instance: "GalaxyClient") -> None: """ self.gi = galaxy_instance - def _make_url(self, module_id: Optional[str] = None, deleted: bool = False, contents: bool = False) -> str: + def _make_url(self, module_id: str | None = None, deleted: bool = False, contents: bool = False) -> str: """ Compose a URL based on the provided arguments. @@ -85,11 +84,11 @@ def _make_url(self, module_id: Optional[str] = None, deleted: bool = False, cont @overload def _get( self, - id: Optional[str] = None, + id: str | None = None, deleted: bool = False, contents: bool = False, - url: Optional[str] = None, - params: Optional[dict] = None, + url: str | None = None, + params: dict | None = None, *, json: Literal[False], stream: bool = False, @@ -98,22 +97,22 @@ def _get( @overload def _get( self, - id: Optional[str] = None, + id: str | None = None, deleted: bool = False, contents: bool = False, - url: Optional[str] = None, - params: Optional[dict] = None, + url: str | None = None, + params: dict | None = None, json: bool = True, stream: bool = False, ) -> Any: ... def _get( self, - id: Optional[str] = None, + id: str | None = None, deleted: bool = False, contents: bool = False, - url: Optional[str] = None, - params: Optional[dict] = None, + url: str | None = None, + params: dict | None = None, json: bool = True, stream: bool = False, ) -> Any: @@ -170,11 +169,11 @@ def _get( def _post( self, - payload: Optional[dict] = None, - id: Optional[str] = None, + payload: dict | None = None, + id: str | None = None, deleted: bool = False, contents: bool = False, - url: Optional[str] = None, + url: str | None = None, files_attached: bool = False, ) -> Any: """ @@ -198,10 +197,10 @@ def _post( def _put( self, - payload: Optional[dict] = None, - id: Optional[str] = None, - url: Optional[str] = None, - params: Optional[dict] = None, + payload: dict | None = None, + id: str | None = None, + url: str | None = None, + params: dict | None = None, ) -> Any: """ Do a generic PUT request, composing the url from the contents of the @@ -219,10 +218,10 @@ def _put( def _patch( self, - payload: Optional[dict] = None, - id: Optional[str] = None, - url: Optional[str] = None, - params: Optional[dict] = None, + payload: dict | None = None, + id: str | None = None, + url: str | None = None, + params: dict | None = None, ) -> Any: """ Do a generic PATCH request, composing the url from the contents of the @@ -240,12 +239,12 @@ def _patch( def _delete( self, - payload: Optional[dict] = None, - id: Optional[str] = None, + payload: dict | None = None, + id: str | None = None, deleted: bool = False, contents: bool = False, - url: Optional[str] = None, - params: Optional[dict] = None, + url: str | None = None, + params: dict | None = None, ) -> Any: """ Do a generic DELETE request, composing the url from the contents of the diff --git a/bioblend/galaxy/container_resolution/__init__.py b/bioblend/galaxy/container_resolution/__init__.py index 29a32995d..cd6cbe4b6 100644 --- a/bioblend/galaxy/container_resolution/__init__.py +++ b/bioblend/galaxy/container_resolution/__init__.py @@ -3,8 +3,6 @@ Works only with Galaxy > 22.01 """ -from typing import Optional - from bioblend.galaxy.client import Client @@ -57,9 +55,9 @@ def show_container_resolver(self, index: int) -> dict: def resolve( self, tool_id: str, - index: Optional[int] = None, - resolver_type: Optional[str] = None, - container_type: Optional[str] = None, + index: int | None = None, + resolver_type: str | None = None, + container_type: str | None = None, requirements_only: bool = False, install: bool = False, ) -> dict: @@ -117,10 +115,10 @@ def resolve( def resolve_toolbox( self, - index: Optional[int] = None, - tool_ids: Optional[list[str]] = None, - resolver_type: Optional[str] = None, - container_type: Optional[str] = None, + index: int | None = None, + tool_ids: list[str] | None = None, + resolver_type: str | None = None, + container_type: str | None = None, requirements_only: bool = False, install: bool = False, ) -> list: @@ -169,10 +167,10 @@ def resolve_toolbox( def resolve_toolbox_with_install( self, - index: Optional[int] = None, - tool_ids: Optional[list[str]] = None, - resolver_type: Optional[str] = None, - container_type: Optional[str] = None, + index: int | None = None, + tool_ids: list[str] | None = None, + resolver_type: str | None = None, + container_type: str | None = None, requirements_only: bool = False, ) -> list: """ diff --git a/bioblend/galaxy/dataset_collections/__init__.py b/bioblend/galaxy/dataset_collections/__init__.py index 31f8fa96d..a4e550b46 100644 --- a/bioblend/galaxy/dataset_collections/__init__.py +++ b/bioblend/galaxy/dataset_collections/__init__.py @@ -1,7 +1,6 @@ import logging from typing import ( Any, - Optional, TYPE_CHECKING, Union, ) @@ -26,12 +25,12 @@ def __init__( self, name: str, type: str = "list", - elements: Optional[Union[list[Union["CollectionElement", "SimpleElement"]], dict[str, Any]]] = None, + elements: list[Union["CollectionElement", "SimpleElement"]] | dict[str, Any] | None = None, ) -> None: self.name = name self.type = type if isinstance(elements, dict): - self.elements: list[Union[CollectionElement, SimpleElement]] = [ + self.elements: list[CollectionElement | SimpleElement] = [ HistoryDatasetElement(name=key, id=value) for key, value in elements.values() ] elif elements: @@ -43,7 +42,7 @@ def add(self, element: Union["CollectionElement", "SimpleElement"]) -> "HasEleme class CollectionDescription(HasElements): - def to_dict(self) -> dict[str, Union[str, list]]: + def to_dict(self) -> dict[str, str | list]: return { "name": self.name, "collection_type": self.type, @@ -52,7 +51,7 @@ def to_dict(self) -> dict[str, Union[str, list]]: class CollectionElement(HasElements): - def to_dict(self) -> dict[str, Union[str, list]]: + def to_dict(self) -> dict[str, str | list]: return { "src": "new_collection", "name": self.name, diff --git a/bioblend/galaxy/datasets/__init__.py b/bioblend/galaxy/datasets/__init__.py index 9fc8460c8..124221aa6 100644 --- a/bioblend/galaxy/datasets/__init__.py +++ b/bioblend/galaxy/datasets/__init__.py @@ -9,10 +9,8 @@ from typing import ( Any, Literal, - Optional, overload, TYPE_CHECKING, - Union, ) from requests import Response @@ -112,11 +110,11 @@ def download_dataset( def download_dataset( self, dataset_id: str, - file_path: Optional[str] = None, + file_path: str | None = None, use_default_filename: bool = True, require_ok_state: bool = True, maxwait: float = 12000, - ) -> Union[bytes, str]: + ) -> bytes | str: """ Download a dataset to file or in memory. If the dataset state is not 'ok', a ``DatasetStateException`` will be thrown, unless ``require_ok_state=False``. @@ -191,19 +189,19 @@ def get_datasets( self, limit: int = 500, offset: int = 0, - name: Optional[str] = None, - extension: Optional[Union[str, list[str]]] = None, - state: Optional[Union[str, list[str]]] = None, - visible: Optional[bool] = None, - deleted: Optional[bool] = None, - purged: Optional[bool] = None, - tool_id: Optional[str] = None, - tag: Optional[str] = None, - history_id: Optional[str] = None, - create_time_min: Optional[str] = None, - create_time_max: Optional[str] = None, - update_time_min: Optional[str] = None, - update_time_max: Optional[str] = None, + name: str | None = None, + extension: str | list[str] | None = None, + state: str | list[str] | None = None, + visible: bool | None = None, + deleted: bool | None = None, + purged: bool | None = None, + tool_id: str | None = None, + tag: str | None = None, + history_id: str | None = None, + create_time_min: str | None = None, + create_time_max: str | None = None, + update_time_min: str | None = None, + update_time_max: str | None = None, order: str = "create_time-dsc", ) -> list[dict[str, Any]]: """ @@ -331,7 +329,7 @@ def get_datasets( return self._get(params=params) - def _param_to_filter(self, param: Union[str, list[str]]) -> tuple[str, str]: + def _param_to_filter(self, param: str | list[str]) -> tuple[str, str]: if isinstance(param, str): return "eq", param if isinstance(param, list): @@ -364,9 +362,9 @@ def publish_dataset(self, dataset_id: str, published: bool = False) -> dict[str, def update_permissions( self, dataset_id: str, - access_ids: Optional[list] = None, - manage_ids: Optional[list] = None, - modify_ids: Optional[list] = None, + access_ids: list | None = None, + manage_ids: list | None = None, + modify_ids: list | None = None, ) -> dict: """ Set access, manage or modify permissions for a dataset to a list of roles. diff --git a/bioblend/galaxy/folders/__init__.py b/bioblend/galaxy/folders/__init__.py index 08d67c4a5..076871027 100644 --- a/bioblend/galaxy/folders/__init__.py +++ b/bioblend/galaxy/folders/__init__.py @@ -7,10 +7,8 @@ from typing import ( Any, Literal, - Optional, overload, TYPE_CHECKING, - Union, ) from bioblend.galaxy.client import Client @@ -25,7 +23,7 @@ class FoldersClient(Client): def __init__(self, galaxy_instance: "GalaxyInstance") -> None: super().__init__(galaxy_instance) - def create_folder(self, parent_folder_id: str, name: str, description: Optional[str] = None) -> dict[str, Any]: + def create_folder(self, parent_folder_id: str, name: str, description: str | None = None) -> dict[str, Any]: """ Create a folder. @@ -157,7 +155,7 @@ def delete_folder(self, folder_id: str, undelete: bool = False) -> dict[str, Any payload = {"undelete": undelete} return self._delete(payload=payload, id=folder_id) - def update_folder(self, folder_id: str, name: str, description: Optional[str] = None) -> dict[str, Any]: + def update_folder(self, folder_id: str, name: str, description: str | None = None) -> dict[str, Any]: """ Update folder information. @@ -198,9 +196,9 @@ def set_permissions( self, folder_id: str, action: Literal["set_permissions"] = "set_permissions", - add_ids: Optional[list[str]] = None, - manage_ids: Optional[list[str]] = None, - modify_ids: Optional[list[str]] = None, + add_ids: list[str] | None = None, + manage_ids: list[str] | None = None, + modify_ids: list[str] | None = None, ) -> dict[str, Any]: """ Set the permissions of a folder. @@ -224,7 +222,7 @@ def set_permissions( :return: dictionary including details of the folder """ url = self._make_url(folder_id) + "/permissions" - payload: dict[str, Union[str, list[str]]] = {"action": action} + payload: dict[str, str | list[str]] = {"action": action} if add_ids: payload["add_ids[]"] = add_ids if manage_ids: diff --git a/bioblend/galaxy/genomes/__init__.py b/bioblend/galaxy/genomes/__init__.py index dcef315aa..9e254ce9a 100644 --- a/bioblend/galaxy/genomes/__init__.py +++ b/bioblend/galaxy/genomes/__init__.py @@ -5,7 +5,6 @@ from typing import ( Any, Literal, - Optional, TYPE_CHECKING, ) @@ -34,10 +33,10 @@ def get_genomes(self) -> list: def show_genome( self, id: str, - num: Optional[str] = None, - chrom: Optional[str] = None, - low: Optional[str] = None, - high: Optional[str] = None, + num: str | None = None, + chrom: str | None = None, + low: str | None = None, + high: str | None = None, ) -> dict[str, Any]: """ Returns information about build @@ -74,12 +73,12 @@ def show_genome( def install_genome( self, func: Literal["download", "index"] = "download", - source: Optional[str] = None, - dbkey: Optional[str] = None, - ncbi_name: Optional[str] = None, - ensembl_dbkey: Optional[str] = None, - url_dbkey: Optional[str] = None, - indexers: Optional[list] = None, + source: str | None = None, + dbkey: str | None = None, + ncbi_name: str | None = None, + ensembl_dbkey: str | None = None, + url_dbkey: str | None = None, + indexers: list | None = None, ) -> dict[str, Any]: """ Download and/or index a genome. diff --git a/bioblend/galaxy/groups/__init__.py b/bioblend/galaxy/groups/__init__.py index 281066320..eaaee1f1a 100644 --- a/bioblend/galaxy/groups/__init__.py +++ b/bioblend/galaxy/groups/__init__.py @@ -4,7 +4,6 @@ from typing import ( Any, - Optional, TYPE_CHECKING, ) @@ -60,7 +59,7 @@ def show_group(self, group_id: str) -> dict[str, Any]: return self._get(id=group_id) def create_group( - self, group_name: str, user_ids: Optional[list[str]] = None, role_ids: Optional[list[str]] = None + self, group_name: str, user_ids: list[str] | None = None, role_ids: list[str] | None = None ) -> list[dict[str, Any]]: """ Create a new group. @@ -93,9 +92,9 @@ def create_group( def update_group( self, group_id: str, - group_name: Optional[str] = None, - user_ids: Optional[list[str]] = None, - role_ids: Optional[list[str]] = None, + group_name: str | None = None, + user_ids: list[str] | None = None, + role_ids: list[str] | None = None, ) -> None: """ Update a group. diff --git a/bioblend/galaxy/histories/__init__.py b/bioblend/galaxy/histories/__init__.py index 6bbeb035b..ef6e03340 100644 --- a/bioblend/galaxy/histories/__init__.py +++ b/bioblend/galaxy/histories/__init__.py @@ -13,7 +13,6 @@ Any, IO, Literal, - Optional, overload, Union, ) @@ -41,7 +40,7 @@ class HistoryClient(Client): def __init__(self, galaxy_instance: "GalaxyInstance") -> None: super().__init__(galaxy_instance) - def create_history(self, name: Optional[str] = None) -> dict[str, Any]: + def create_history(self, name: str | None = None) -> dict[str, Any]: """ Create a new history, optionally setting the ``name``. @@ -56,7 +55,7 @@ def create_history(self, name: Optional[str] = None) -> dict[str, Any]: payload["name"] = name return self._post(payload) - def import_history(self, file_path: Optional[str] = None, url: Optional[str] = None) -> dict[str, Any]: + def import_history(self, file_path: str | None = None, url: str | None = None) -> dict[str, Any]: """ Import a history from an archive on disk or a URL. @@ -86,20 +85,20 @@ def import_history(self, file_path: Optional[str] = None, url: Optional[str] = N def _get_histories( self, - name: Optional[str] = None, + name: str | None = None, deleted: bool = False, - filter_user_published: Optional[bool] = None, + filter_user_published: bool | None = None, get_all_published: bool = False, - slug: Optional[str] = None, - all: Optional[bool] = False, - create_time_min: Optional[str] = None, - create_time_max: Optional[str] = None, - update_time_min: Optional[str] = None, - update_time_max: Optional[str] = None, - view: Optional[Literal["summary", "detailed"]] = None, - keys: Optional[list[str]] = None, - limit: Optional[int] = None, - offset: Optional[int] = None, + slug: str | None = None, + all: bool | None = False, + create_time_min: str | None = None, + create_time_max: str | None = None, + update_time_min: str | None = None, + update_time_max: str | None = None, + view: Literal["summary", "detailed"] | None = None, + keys: list[str] | None = None, + limit: int | None = None, + offset: int | None = None, ) -> list[dict[str, Any]]: """ Hidden method to be used by both get_histories() and get_published_histories() @@ -148,20 +147,20 @@ def _get_histories( def get_histories( self, - history_id: Optional[str] = None, - name: Optional[str] = None, + history_id: str | None = None, + name: str | None = None, deleted: bool = False, - published: Optional[bool] = None, - slug: Optional[str] = None, - all: Optional[bool] = False, - create_time_min: Optional[str] = None, - create_time_max: Optional[str] = None, - update_time_min: Optional[str] = None, - update_time_max: Optional[str] = None, - view: Optional[Literal["summary", "detailed"]] = None, - keys: Optional[list[str]] = None, - limit: Optional[int] = None, - offset: Optional[int] = None, + published: bool | None = None, + slug: str | None = None, + all: bool | None = False, + create_time_min: str | None = None, + create_time_max: str | None = None, + update_time_min: str | None = None, + update_time_max: str | None = None, + view: Literal["summary", "detailed"] | None = None, + keys: list[str] | None = None, + limit: int | None = None, + offset: int | None = None, ) -> list[dict[str, Any]]: """ Get all histories, or select a subset by specifying optional arguments @@ -249,13 +248,13 @@ def get_histories( def get_published_histories( self, - name: Optional[str] = None, + name: str | None = None, deleted: bool = False, - slug: Optional[str] = None, - create_time_min: Optional[str] = None, - create_time_max: Optional[str] = None, - update_time_min: Optional[str] = None, - update_time_max: Optional[str] = None, + slug: str | None = None, + create_time_min: str | None = None, + create_time_max: str | None = None, + update_time_min: str | None = None, + update_time_max: str | None = None, ) -> list[dict[str, Any]]: """ Get all published histories (by any user), or select a subset by @@ -314,23 +313,23 @@ def show_history( self, history_id: str, contents: Literal[True], - deleted: Optional[bool] = None, - visible: Optional[bool] = None, - details: Optional[str] = None, - types: Optional[list[str]] = None, - keys: Optional[list[str]] = None, + deleted: bool | None = None, + visible: bool | None = None, + details: str | None = None, + types: list[str] | None = None, + keys: list[str] | None = None, ) -> list[dict[str, Any]]: ... def show_history( self, history_id: str, contents: bool = False, - deleted: Optional[bool] = None, - visible: Optional[bool] = None, - details: Optional[str] = None, - types: Optional[list[str]] = None, - keys: Optional[list[str]] = None, - ) -> Union[dict[str, Any], list[dict[str, Any]]]: + deleted: bool | None = None, + visible: bool | None = None, + details: str | None = None, + types: list[str] | None = None, + keys: list[str] | None = None, + ) -> dict[str, Any] | list[dict[str, Any]]: """ Get details of a given history. By default, just get the history meta information. @@ -377,7 +376,7 @@ def show_history( more extensive functionality for filtering and ordering the results. """ - params: dict[str, Union[bool, list, str]] = {} + params: dict[str, bool | list | str] = {} if contents: if details: params["details"] = details @@ -477,7 +476,7 @@ def show_dataset_collection(self, history_id: str, dataset_collection_id: str) - return self._get(url=url) def show_matching_datasets( - self, history_id: str, name_filter: Optional[Union[str, Pattern[str]]] = None + self, history_id: str, name_filter: str | Pattern[str] | None = None ) -> list[dict[str, Any]]: """ Get dataset details for matching datasets within a history. @@ -826,7 +825,7 @@ def export_history( include_hidden: bool = False, include_deleted: bool = False, wait: bool = False, - maxwait: Optional[float] = None, + maxwait: float | None = None, ) -> str: """ Start a job to create an export archive for the given history. diff --git a/bioblend/galaxy/invocations/__init__.py b/bioblend/galaxy/invocations/__init__.py index 241897ddd..e33e9a69e 100644 --- a/bioblend/galaxy/invocations/__init__.py +++ b/bioblend/galaxy/invocations/__init__.py @@ -5,7 +5,6 @@ import logging from typing import ( Any, - Optional, TYPE_CHECKING, ) @@ -38,16 +37,16 @@ def __init__(self, galaxy_instance: "GalaxyInstance") -> None: def get_invocations( self, - workflow_id: Optional[str] = None, - history_id: Optional[str] = None, - user_id: Optional[str] = None, + workflow_id: str | None = None, + history_id: str | None = None, + user_id: str | None = None, include_terminal: bool = True, - limit: Optional[int] = None, + limit: int | None = None, *, - offset: Optional[int] = None, + offset: int | None = None, view: str = "collection", step_details: bool = False, - job_id: Optional[int] = None, + job_id: int | None = None, ) -> list[dict[str, Any]]: """ Get all workflow invocations, or select a subset by specifying optional @@ -163,16 +162,16 @@ def show_invocation(self, invocation_id: str) -> dict[str, Any]: def rerun_invocation( self, invocation_id: str, - inputs_update: Optional[dict] = None, - params_update: Optional[dict] = None, - history_id: Optional[str] = None, - history_name: Optional[str] = None, + inputs_update: dict | None = None, + params_update: dict | None = None, + history_id: str | None = None, + history_name: str | None = None, import_inputs_to_history: bool = False, - replacement_params: Optional[dict] = None, + replacement_params: dict | None = None, allow_tool_state_corrections: bool = False, - inputs_by: Optional[InputsBy] = None, + inputs_by: InputsBy | None = None, parameters_normalized: bool = False, - resource_params: Optional[dict[str, Any]] = None, + resource_params: dict[str, Any] | None = None, use_cached_job: bool = True, ) -> dict[str, Any]: """ @@ -504,10 +503,10 @@ def get_invocation_archive( include_deleted: bool = False, include_hidden: bool = False, bco_merge_history_metadata: bool = False, - bco_override_environment_variables: Optional[dict[str, Any]] = None, - bco_override_empirical_error: Optional[dict[str, Any]] = None, - bco_override_algorithmic_error: Optional[dict[str, Any]] = None, - bco_override_xref: Optional[dict[str, Any]] = None, + bco_override_environment_variables: dict[str, Any] | None = None, + bco_override_empirical_error: dict[str, Any] | None = None, + bco_override_algorithmic_error: dict[str, Any] | None = None, + bco_override_xref: dict[str, Any] | None = None, maxwait: float = 1200, ) -> requests.Response: """ diff --git a/bioblend/galaxy/jobs/__init__.py b/bioblend/galaxy/jobs/__init__.py index df0d45d89..3bbbce325 100644 --- a/bioblend/galaxy/jobs/__init__.py +++ b/bioblend/galaxy/jobs/__init__.py @@ -6,7 +6,6 @@ from typing import ( Any, Literal, - Optional, TYPE_CHECKING, ) @@ -34,14 +33,14 @@ def __init__(self, galaxy_instance: "GalaxyInstance") -> None: def get_jobs( self, - state: Optional[str] = None, - history_id: Optional[str] = None, - invocation_id: Optional[str] = None, - tool_id: Optional[str] = None, - workflow_id: Optional[str] = None, - user_id: Optional[str] = None, - date_range_min: Optional[str] = None, - date_range_max: Optional[str] = None, + state: str | None = None, + history_id: str | None = None, + invocation_id: str | None = None, + tool_id: str | None = None, + workflow_id: str | None = None, + user_id: str | None = None, + date_range_min: str | None = None, + date_range_max: str | None = None, limit: int = 500, offset: int = 0, user_details: bool = False, @@ -195,8 +194,8 @@ def rerun_job( self, job_id: str, remap: bool = False, - tool_inputs_update: Optional[dict[str, Any]] = None, - history_id: Optional[str] = None, + tool_inputs_update: dict[str, Any] | None = None, + history_id: str | None = None, ) -> dict[str, Any]: """ Rerun a job. @@ -272,7 +271,7 @@ def get_state(self, job_id: str) -> str: """ return self.show_job(job_id).get("state", "") - def search_jobs(self, tool_id: str, inputs: dict[str, Any], state: Optional[str] = None) -> list[dict[str, Any]]: + def search_jobs(self, tool_id: str, inputs: dict[str, Any], state: str | None = None) -> list[dict[str, Any]]: """ Return jobs matching input parameters. @@ -339,7 +338,7 @@ def cancel_job(self, job_id: str) -> bool: """ return self._delete(id=job_id) - def report_error(self, job_id: str, dataset_id: str, message: str, email: Optional[str] = None) -> dict[str, Any]: + def report_error(self, job_id: str, dataset_id: str, message: str, email: str | None = None) -> dict[str, Any]: """ Report an error for a given job and dataset to the server administrators. diff --git a/bioblend/galaxy/libraries/__init__.py b/bioblend/galaxy/libraries/__init__.py index ce3927eb7..610c1ab19 100644 --- a/bioblend/galaxy/libraries/__init__.py +++ b/bioblend/galaxy/libraries/__init__.py @@ -6,10 +6,8 @@ from typing import ( Any, Literal, - Optional, overload, TYPE_CHECKING, - Union, ) from bioblend import ( @@ -34,9 +32,7 @@ class LibraryClient(Client): def __init__(self, galaxy_instance: "GalaxyInstance") -> None: super().__init__(galaxy_instance) - def create_library( - self, name: str, description: Optional[str] = None, synopsis: Optional[str] = None - ) -> dict[str, Any]: + def create_library(self, name: str, description: str | None = None, synopsis: str | None = None) -> dict[str, Any]: """ Create a data library with the properties defined in the arguments. @@ -221,7 +217,7 @@ def _get_root_folder_id(self, library_id: str) -> str: return library_dict["root_folder_id"] def create_folder( - self, library_id: str, folder_name: str, description: Optional[str] = None, base_folder_id: Optional[str] = None + self, library_id: str, folder_name: str, description: str | None = None, base_folder_id: str | None = None ) -> list[dict[str, Any]]: """ Create a folder in a library. @@ -256,7 +252,7 @@ def create_folder( return self._post(payload, id=library_id, contents=True) def get_folders( - self, library_id: str, folder_id: Optional[str] = None, name: Optional[str] = None + self, library_id: str, folder_id: str | None = None, name: str | None = None ) -> list[dict[str, Any]]: """ Get all the folders in a library, or select a subset by specifying a @@ -289,7 +285,7 @@ def get_folders( return folders def get_libraries( - self, library_id: Optional[str] = None, name: Optional[str] = None, deleted: Optional[bool] = False + self, library_id: str | None = None, name: str | None = None, deleted: bool | None = False ) -> list[dict[str, Any]]: """ Get all libraries, or select a subset by specifying optional arguments @@ -325,7 +321,7 @@ def show_library(self, library_id: str, contents: Literal[False] = False) -> dic @overload def show_library(self, library_id: str, contents: Literal[True]) -> list[dict[str, Any]]: ... - def show_library(self, library_id: str, contents: bool = False) -> Union[dict[str, Any], list[dict[str, Any]]]: + def show_library(self, library_id: str, contents: bool = False) -> dict[str, Any] | list[dict[str, Any]]: """ Get information about a library. @@ -394,10 +390,10 @@ def upload_file_from_url( self, library_id: str, file_url: str, - folder_id: Optional[str] = None, + folder_id: str | None = None, file_type: str = "auto", dbkey: str = "?", - tags: Optional[list[str]] = None, + tags: list[str] | None = None, ) -> list[dict[str, Any]]: """ Upload a file to a library from a URL. @@ -432,10 +428,10 @@ def upload_file_contents( self, library_id: str, pasted_content: str, - folder_id: Optional[str] = None, + folder_id: str | None = None, file_type: str = "auto", dbkey: str = "?", - tags: Optional[list[str]] = None, + tags: list[str] | None = None, ) -> list[dict[str, Any]]: """ Upload pasted_content to a data library as a new file. @@ -470,10 +466,10 @@ def upload_file_from_local_path( self, library_id: str, file_local_path: str, - folder_id: Optional[str] = None, + folder_id: str | None = None, file_type: str = "auto", dbkey: str = "?", - tags: Optional[list[str]] = None, + tags: list[str] | None = None, ) -> list[dict[str, Any]]: """ Read local file contents from file_local_path and upload data to a @@ -514,14 +510,14 @@ def upload_file_from_server( self, library_id: str, server_dir: str, - folder_id: Optional[str] = None, + folder_id: str | None = None, file_type: str = "auto", dbkey: str = "?", - link_data_only: Optional[LinkDataOnly] = None, + link_data_only: LinkDataOnly | None = None, roles: str = "", preserve_dirs: bool = False, tag_using_filenames: bool = False, - tags: Optional[list[str]] = None, + tags: list[str] | None = None, ) -> list[dict[str, Any]]: """ Upload all files in the specified subdirectory of the Galaxy library @@ -592,14 +588,14 @@ def upload_from_galaxy_filesystem( self, library_id: str, filesystem_paths: str, - folder_id: Optional[str] = None, + folder_id: str | None = None, file_type: str = "auto", dbkey: str = "?", - link_data_only: Optional[LinkDataOnly] = None, + link_data_only: LinkDataOnly | None = None, roles: str = "", preserve_dirs: bool = False, tag_using_filenames: bool = False, - tags: Optional[list[str]] = None, + tags: list[str] | None = None, ) -> list[dict[str, Any]]: """ Upload a set of files already present on the filesystem of the Galaxy @@ -666,7 +662,7 @@ def upload_from_galaxy_filesystem( ) def copy_from_dataset( - self, library_id: str, dataset_id: str, folder_id: Optional[str] = None, message: str = "" + self, library_id: str, dataset_id: str, folder_id: str | None = None, message: str = "" ) -> dict[str, Any]: """ Copy a Galaxy dataset into a library. @@ -726,10 +722,10 @@ def get_dataset_permissions(self, dataset_id: str) -> dict[str, Any]: def set_library_permissions( self, library_id: str, - access_in: Optional[list[str]] = None, - modify_in: Optional[list[str]] = None, - add_in: Optional[list[str]] = None, - manage_in: Optional[list[str]] = None, + access_in: list[str] | None = None, + modify_in: list[str] | None = None, + add_in: list[str] | None = None, + manage_in: list[str] | None = None, ) -> dict[str, Any]: """ Set the permissions for a library. Note: it will override all security @@ -768,9 +764,9 @@ def set_library_permissions( def set_dataset_permissions( self, dataset_id: str, - access_in: Optional[list[str]] = None, - modify_in: Optional[list[str]] = None, - manage_in: Optional[list[str]] = None, + access_in: list[str] | None = None, + modify_in: list[str] | None = None, + manage_in: list[str] | None = None, ) -> dict[str, Any]: """ Set the permissions for a dataset. Note: it will override all security diff --git a/bioblend/galaxy/objects/client.py b/bioblend/galaxy/objects/client.py index 8f053bee4..378633da8 100644 --- a/bioblend/galaxy/objects/client.py +++ b/bioblend/galaxy/objects/client.py @@ -14,10 +14,8 @@ cast, Generic, Literal, - Optional, overload, TYPE_CHECKING, - Union, ) import bioblend @@ -66,7 +64,7 @@ def list(self) -> list: :return: a list of objects """ - def _select_id(self, id_: Optional[str] = None, name: Optional[str] = None) -> str: + def _select_id(self, id_: str | None = None, name: str | None = None) -> str: """ Return the id that corresponds to the given id or name info. """ @@ -84,9 +82,7 @@ def _select_id(self, id_: Optional[str] = None, name: Optional[str] = None) -> s else: return id_ - def _get_dict( - self, meth_name: str, reply: Optional[Union[dict[str, Any], builtins.list[dict[str, Any]]]] - ) -> dict[str, Any]: + def _get_dict(self, meth_name: str, reply: dict[str, Any] | builtins.list[dict[str, Any]] | None) -> dict[str, Any]: if reply is None: raise RuntimeError(f"{meth_name}: no reply") elif isinstance(reply, dict): @@ -112,7 +108,7 @@ def __init__(self, obj_gi: "GalaxyInstance") -> None: self._show_f = getattr(gi_client, show_fname) def get_previews( - self, name: Optional[str] = None, deleted: bool = False, **kwargs: Any + self, name: str | None = None, deleted: bool = False, **kwargs: Any ) -> list[wrappers.DatasetContainerPreviewSubtype]: dicts = self._get_f(name=name, deleted=deleted, **kwargs) return [ @@ -139,7 +135,7 @@ class ObjLibraryClient(ObjDatasetContainerClient[wrappers.Library, wrappers.Libr CONTAINER_TYPE = wrappers.Library CONTAINER_PREVIEW_TYPE = wrappers.LibraryPreview - def create(self, name: str, description: Optional[str] = None, synopsis: Optional[str] = None) -> wrappers.Library: + def create(self, name: str, description: str | None = None, synopsis: str | None = None) -> wrappers.Library: """ Create a data library with the properties defined in the arguments. @@ -150,7 +146,7 @@ def create(self, name: str, description: Optional[str] = None, synopsis: Optiona lib_info = self._get_dict("create_library", res) return self.get(lib_info["id"]) - def list(self, name: Optional[str] = None, deleted: bool = False) -> list[wrappers.Library]: + def list(self, name: str | None = None, deleted: bool = False) -> list[wrappers.Library]: """ Get libraries owned by the user of this Galaxy instance. @@ -170,7 +166,7 @@ def list(self, name: Optional[str] = None, deleted: bool = False) -> list[wrappe else: return [self.get(_["id"]) for _ in dicts] - def delete(self, id_: Optional[str] = None, name: Optional[str] = None) -> None: + def delete(self, id_: str | None = None, name: str | None = None) -> None: """ Delete the library with the given id or name. @@ -194,7 +190,7 @@ class ObjHistoryClient(ObjDatasetContainerClient[wrappers.History, wrappers.Hist CONTAINER_TYPE = wrappers.History CONTAINER_PREVIEW_TYPE = wrappers.HistoryPreview - def create(self, name: Optional[str] = None) -> wrappers.History: + def create(self, name: str | None = None) -> wrappers.History: """ Create a new Galaxy history, optionally setting its name. @@ -205,7 +201,7 @@ def create(self, name: Optional[str] = None) -> wrappers.History: hist_info = self._get_dict("create_history", res) return self.get(hist_info["id"]) - def list(self, name: Optional[str] = None, deleted: bool = False) -> list[wrappers.History]: + def list(self, name: str | None = None, deleted: bool = False) -> list[wrappers.History]: """ Get histories owned by the user of this Galaxy instance. @@ -219,7 +215,7 @@ def list(self, name: Optional[str] = None, deleted: bool = False) -> list[wrappe dicts = self.gi.histories.get_histories(name=name, deleted=deleted) return [self.get(_["id"]) for _ in dicts] - def delete(self, id_: Optional[str] = None, name: Optional[str] = None, purge: bool = False) -> None: + def delete(self, id_: str | None = None, name: str | None = None, purge: bool = False) -> None: """ Delete the history with the given id or name. @@ -244,7 +240,7 @@ class ObjWorkflowClient(ObjClient): Interacts with Galaxy workflows. """ - def import_new(self, src: Union[str, dict[str, Any]], publish: bool = False) -> wrappers.Workflow: + def import_new(self, src: str | dict[str, Any], publish: bool = False) -> wrappers.Workflow: """ Imports a new workflow into Galaxy. @@ -296,13 +292,13 @@ def get(self, id_: str) -> wrappers.Workflow: # the 'deleted' option is not available for workflows def get_previews( - self, name: Optional[str] = None, published: bool = False, **kwargs: Any + self, name: str | None = None, published: bool = False, **kwargs: Any ) -> list[wrappers.WorkflowPreview]: dicts = self.gi.workflows.get_workflows(name=name, published=published, **kwargs) return [wrappers.WorkflowPreview(_, gi=self.obj_gi) for _ in dicts] # the 'deleted' option is not available for workflows - def list(self, name: Optional[str] = None, published: bool = False) -> list[wrappers.Workflow]: + def list(self, name: str | None = None, published: bool = False) -> list[wrappers.Workflow]: """ Get workflows owned by the user of this Galaxy instance. @@ -316,7 +312,7 @@ def list(self, name: Optional[str] = None, published: bool = False) -> list[wrap dicts = self.gi.workflows.get_workflows(name=name, published=published) return [self.get(_["id"]) for _ in dicts] - def delete(self, id_: Optional[str] = None, name: Optional[str] = None) -> None: + def delete(self, id_: str | None = None, name: str | None = None) -> None: """ Delete the workflow with the given id or name. @@ -357,11 +353,11 @@ def get_previews(self, **kwargs: Any) -> list[wrappers.InvocationPreview]: def list( self, - workflow: Optional[wrappers.Workflow] = None, - history: Optional[wrappers.History] = None, + workflow: wrappers.Workflow | None = None, + history: wrappers.History | None = None, include_terminal: bool = True, - limit: Optional[int] = None, - offset: Optional[int] = None, + limit: int | None = None, + offset: int | None = None, ) -> list[wrappers.Invocation]: """ Get full listing of workflow invocations, or select a subset @@ -422,7 +418,7 @@ def get(self, id_: str, io_details: bool = False, link_details: bool = False) -> tool_dict = self._get_dict("show_tool", res) return wrappers.Tool(tool_dict, gi=self.obj_gi) - def get_previews(self, name: Optional[str] = None, trackster: bool = False, **kwargs: Any) -> list[wrappers.Tool]: + def get_previews(self, name: str | None = None, trackster: bool = False, **kwargs: Any) -> list[wrappers.Tool]: """ Get the list of tools installed on the Galaxy instance. @@ -439,7 +435,7 @@ def get_previews(self, name: Optional[str] = None, trackster: bool = False, **kw return [wrappers.Tool(_, gi=self.obj_gi) for _ in dicts] # the 'deleted' option is not available for tools - def list(self, name: Optional[str] = None, trackster: bool = False) -> list[wrappers.Tool]: + def list(self, name: str | None = None, trackster: bool = False) -> list[wrappers.Tool]: """ Get the list of tools installed on the Galaxy instance. diff --git a/bioblend/galaxy/objects/galaxy_instance.py b/bioblend/galaxy/objects/galaxy_instance.py index e06bb4ae5..59f9c92ff 100644 --- a/bioblend/galaxy/objects/galaxy_instance.py +++ b/bioblend/galaxy/objects/galaxy_instance.py @@ -4,7 +4,6 @@ import time from collections.abc import Iterable -from typing import Optional import bioblend import bioblend.galaxy @@ -50,13 +49,13 @@ class GalaxyInstance: def __init__( self, url: str, - api_key: Optional[str] = None, - email: Optional[str] = None, - password: Optional[str] = None, + api_key: str | None = None, + email: str | None = None, + password: str | None = None, *, - token: Optional[str] = None, + token: str | None = None, verify: bool = True, - user_agent: Optional[str] = None, + user_agent: str | None = None, ) -> None: self.gi = bioblend.galaxy.GalaxyInstance( url, key=api_key, email=email, password=password, token=token, verify=verify, user_agent=user_agent diff --git a/bioblend/galaxy/objects/wrappers.py b/bioblend/galaxy/objects/wrappers.py index 35504363a..5669a71b3 100644 --- a/bioblend/galaxy/objects/wrappers.py +++ b/bioblend/galaxy/objects/wrappers.py @@ -7,6 +7,7 @@ import abc import json from collections.abc import ( + Callable, Iterable, Iterator, Mapping, @@ -14,7 +15,6 @@ ) from typing import ( Any, - Callable, cast, ClassVar, Generic, @@ -189,9 +189,9 @@ class Step(Wrapper): input_steps: dict[str, dict] name: str type: str - tool_id: Optional[str] + tool_id: str | None tool_inputs: dict - tool_version: Optional[str] + tool_version: str | None def __init__(self, step_dict: dict[str, Any], parent: Wrapper) -> None: super().__init__(step_dict, parent=parent, gi=parent.gi) @@ -218,7 +218,7 @@ class InvocationStep(Wrapper): "workflow_step_label", "workflow_step_uuid", ) - action: Optional[object] + action: object | None gi: "GalaxyInstance" job_id: str order_index: int @@ -492,13 +492,13 @@ def delete(self) -> None: def invoke( self, - inputs: Optional[dict[str, Any]] = None, - params: Optional[dict[str, Any]] = None, - history: Optional[Union[str, "History"]] = None, + inputs: dict[str, Any] | None = None, + params: dict[str, Any] | None = None, + history: Union[str, "History"] | None = None, import_inputs_to_history: bool = False, - replacement_params: Optional[dict[str, Any]] = None, + replacement_params: dict[str, Any] | None = None, allow_tool_state_corrections: bool = True, - inputs_by: Optional[InputsBy] = None, + inputs_by: InputsBy | None = None, parameters_normalized: bool = False, ) -> "Invocation": """ @@ -708,9 +708,9 @@ def number_of_steps(self) -> int: def sorted_steps_by( self, - indices: Optional[Iterable[int]] = None, - states: Optional[Iterable[Union[str, None]]] = None, - step_ids: Optional[Iterable[str]] = None, + indices: Iterable[int] | None = None, + states: Iterable[str | None] | None = None, + step_ids: Iterable[str] | None = None, ) -> list[InvocationStep]: """ Get steps for this invocation, or get a subset by specifying @@ -728,7 +728,7 @@ def sorted_steps_by( :rtype: list of InvocationStep :return: invocation steps """ - steps: Union[list[InvocationStep], filter] = self.steps + steps: list[InvocationStep] | filter = self.steps if indices is not None: steps = filter(lambda step: step.order_index in indices, steps) if states is not None: @@ -1218,7 +1218,7 @@ class DatasetContainer(Wrapper, Generic[DatasetSubtype], metaclass=abc.ABCMeta): def __init__( self, c_dict: dict[str, Any], - content_infos: Optional[list[ContentInfo]] = None, + content_infos: list[ContentInfo] | None = None, gi: Optional["GalaxyInstance"] = None, ) -> None: """ @@ -1277,7 +1277,7 @@ def get_dataset(self, ds_id: str) -> DatasetSubtype: ds_dict = gi_client.show_dataset(self.id, ds_id) return self.DS_TYPE(ds_dict, self, gi=self.gi) - def get_datasets(self, name: Optional[str] = None) -> list[DatasetSubtype]: + def get_datasets(self, name: str | None = None) -> list[DatasetSubtype]: """ Get all datasets contained inside this dataset container. @@ -1458,7 +1458,7 @@ def export( include_hidden: bool = False, include_deleted: bool = False, wait: bool = False, - maxwait: Optional[int] = None, + maxwait: int | None = None, ) -> str: """ Start a job to create an export archive for this history. See @@ -1548,7 +1548,7 @@ def delete(self) -> None: self.refresh() self.unmap() - def _pre_upload(self, folder: Optional["Folder"]) -> Optional[str]: + def _pre_upload(self, folder: Optional["Folder"]) -> str | None: """ Return the id of the given folder, after sanity checking. """ @@ -1606,7 +1606,7 @@ def upload_from_local(self, path: str, folder: Optional["Folder"] = None, **kwar def upload_from_galaxy_fs( self, - paths: Union[str, Iterable[str]], + paths: str | Iterable[str], folder: Optional["Folder"] = None, link_data_only: Literal["copy_files", "link_to_files"] = "copy_files", **kwargs: Any, @@ -1663,7 +1663,7 @@ def copy_from_dataset( return self.get_dataset(res["library_dataset_id"]) def create_folder( - self, name: str, description: Optional[str] = None, base_folder: Optional["Folder"] = None + self, name: str, description: str | None = None, base_folder: Optional["Folder"] = None ) -> "Folder": """ Create a folder in this library. diff --git a/bioblend/galaxy/quotas/__init__.py b/bioblend/galaxy/quotas/__init__.py index 30bd990f8..6c449c403 100644 --- a/bioblend/galaxy/quotas/__init__.py +++ b/bioblend/galaxy/quotas/__init__.py @@ -5,7 +5,6 @@ from typing import ( Any, Literal, - Optional, TYPE_CHECKING, ) @@ -79,10 +78,10 @@ def create_quota( description: str, amount: str, operation: QuotaOperations, - default: Optional[DefaultQuotaValues] = "no", - in_users: Optional[list[str]] = None, - in_groups: Optional[list[str]] = None, - quota_source_label: Optional[str] = None, + default: DefaultQuotaValues | None = "no", + in_users: list[str] | None = None, + in_groups: list[str] | None = None, + quota_source_label: str | None = None, ) -> dict[str, Any]: """ Create a new quota @@ -143,13 +142,13 @@ def create_quota( def update_quota( self, quota_id: str, - name: Optional[str] = None, - description: Optional[str] = None, - amount: Optional[str] = None, - operation: Optional[QuotaOperations] = "=", - default: Optional[DefaultQuotaValues] = None, - in_users: Optional[list[str]] = None, - in_groups: Optional[list[str]] = None, + name: str | None = None, + description: str | None = None, + amount: str | None = None, + operation: QuotaOperations | None = "=", + default: DefaultQuotaValues | None = None, + in_users: list[str] | None = None, + in_groups: list[str] | None = None, ) -> str: """ Update an existing quota diff --git a/bioblend/galaxy/roles/__init__.py b/bioblend/galaxy/roles/__init__.py index c6c449928..303e2f6e7 100644 --- a/bioblend/galaxy/roles/__init__.py +++ b/bioblend/galaxy/roles/__init__.py @@ -4,7 +4,6 @@ from typing import ( Any, - Optional, TYPE_CHECKING, ) @@ -63,8 +62,8 @@ def create_role( self, role_name: str, description: str, - user_ids: Optional[list[str]] = None, - group_ids: Optional[list[str]] = None, + user_ids: list[str] | None = None, + group_ids: list[str] | None = None, ) -> dict[str, Any]: """ Create a new role. diff --git a/bioblend/galaxy/tool_dependencies/__init__.py b/bioblend/galaxy/tool_dependencies/__init__.py index 0b2f689af..927f9aa63 100644 --- a/bioblend/galaxy/tool_dependencies/__init__.py +++ b/bioblend/galaxy/tool_dependencies/__init__.py @@ -5,7 +5,6 @@ from typing import ( Any, Literal, - Optional, TYPE_CHECKING, ) @@ -23,11 +22,11 @@ def __init__(self, galaxy_instance: "GalaxyInstance") -> None: def summarize_toolbox( self, - index: Optional[int] = None, - tool_ids: Optional[list[str]] = None, - resolver_type: Optional[str] = None, + index: int | None = None, + tool_ids: list[str] | None = None, + resolver_type: str | None = None, include_containers: bool = False, - container_type: Optional[str] = None, + container_type: str | None = None, index_by: Literal["requirements", "tools"] = "requirements", ) -> list: """ diff --git a/bioblend/galaxy/tools/__init__.py b/bioblend/galaxy/tools/__init__.py index 78f16c7a2..71935b411 100644 --- a/bioblend/galaxy/tools/__init__.py +++ b/bioblend/galaxy/tools/__init__.py @@ -6,9 +6,7 @@ from typing import ( Any, Literal, - Optional, TYPE_CHECKING, - Union, ) from bioblend.galaxy.client import Client @@ -28,7 +26,7 @@ def __init__(self, galaxy_instance: "GalaxyInstance") -> None: super().__init__(galaxy_instance) def get_tools( - self, tool_id: Optional[str] = None, name: Optional[str] = None, trackster: Optional[bool] = None + self, tool_id: str | None = None, name: str | None = None, trackster: bool | None = None ) -> list[dict[str, Any]]: """ Get all tools, or select a subset by specifying optional arguments for @@ -71,7 +69,7 @@ def get_tool_panel(self) -> list[dict[str, Any]]: """ return self._raw_get_tool(in_panel=True) - def _raw_get_tool(self, in_panel: Optional[bool] = None, trackster: Optional[bool] = None) -> list[dict[str, Any]]: + def _raw_get_tool(self, in_panel: bool | None = None, trackster: bool | None = None) -> list[dict[str, Any]]: params = { "in_panel": in_panel, "trackster": trackster, @@ -206,7 +204,7 @@ def show_tool(self, tool_id: str, io_details: bool = False, link_details: bool = } return self._get(id=tool_id, params=params) - def get_tool_tests(self, tool_id: str, tool_version: Optional[str] = None) -> list[dict[str, Any]]: + def get_tool_tests(self, tool_id: str, tool_version: str | None = None) -> list[dict[str, Any]]: """ Fetch the test case definitions configured for a tool. @@ -241,9 +239,9 @@ def get_tool_tests(self, tool_id: str, tool_version: Optional[str] = None) -> li def build( self, tool_id: str, - inputs: Optional[dict[str, Any]] = None, - tool_version: Optional[str] = None, - history_id: Optional[str] = None, + inputs: dict[str, Any] | None = None, + tool_version: str | None = None, + history_id: str | None = None, ) -> dict[str, Any]: """ This method returns the tool model, which includes an updated input parameter array for the given tool, @@ -342,7 +340,7 @@ def build( } """ - params: dict[str, Union[str, dict]] = {} + params: dict[str, str | dict] = {} if inputs: params["inputs"] = inputs @@ -361,9 +359,9 @@ def run_tool( self, history_id: str, tool_id: str, - tool_inputs: Union[InputsBuilder, dict], + tool_inputs: InputsBuilder | dict, input_format: Literal["21.01", "legacy"] = "legacy", - data_manager_mode: Optional[Literal["populate", "dry_run", "bundle"]] = None, + data_manager_mode: Literal["populate", "dry_run", "bundle"] | None = None, ) -> dict[str, Any]: """ Runs tool specified by ``tool_id`` in history indicated @@ -447,7 +445,7 @@ def run_tool( You can also check the examples in `Galaxy's API test suite `_. """ - payload: dict[str, Union[str, dict]] = { + payload: dict[str, str | dict] = { "history_id": history_id, "tool_id": tool_id, "input_format": input_format, @@ -467,9 +465,9 @@ def upload_file( self, path: str, history_id: str, - storage: Optional[str] = None, - metadata: Optional[dict] = None, - chunk_size: Optional[int] = UPLOAD_CHUNK_SIZE, + storage: str | None = None, + metadata: dict | None = None, + chunk_size: int | None = UPLOAD_CHUNK_SIZE, **kwargs: Any, ) -> dict[str, Any]: """ diff --git a/bioblend/galaxy/tools/inputs.py b/bioblend/galaxy/tools/inputs.py index bfab60992..c50573bd5 100644 --- a/bioblend/galaxy/tools/inputs.py +++ b/bioblend/galaxy/tools/inputs.py @@ -1,8 +1,6 @@ from collections.abc import Iterator from typing import ( Any, - Optional, - Union, ) @@ -30,7 +28,7 @@ def to_dict(self) -> dict[str, Any]: values[key] = value return values - def flat_iter(self, prefix: Optional[str] = None) -> Iterator[tuple[str, Any]]: + def flat_iter(self, prefix: str | None = None) -> Iterator[tuple[str, Any]]: for key, value in self._input_dict.items(): effective_key = key if prefix is None else f"{prefix}|{key}" if hasattr(value, "flat_iter"): @@ -59,7 +57,7 @@ def __init__(self, value: Any) -> None: class DatasetParam(Param): - def __init__(self, value: Union[dict[str, str], str], src: str = "hda") -> None: + def __init__(self, value: dict[str, str] | str, src: str = "hda") -> None: if not isinstance(value, dict): value = {"src": src, "id": value} super().__init__(value) diff --git a/bioblend/galaxy/toolshed/__init__.py b/bioblend/galaxy/toolshed/__init__.py index 38d807783..96fdf8477 100644 --- a/bioblend/galaxy/toolshed/__init__.py +++ b/bioblend/galaxy/toolshed/__init__.py @@ -4,9 +4,7 @@ from typing import ( Any, - Optional, TYPE_CHECKING, - Union, ) from bioblend.galaxy.client import Client @@ -79,9 +77,9 @@ def install_repository_revision( install_tool_dependencies: bool = False, install_repository_dependencies: bool = False, install_resolver_dependencies: bool = False, - tool_panel_section_id: Optional[str] = None, - new_tool_panel_section_label: Optional[str] = None, - ) -> Union[list[dict[str, Any]], dict[str, str]]: + tool_panel_section_id: str | None = None, + new_tool_panel_section_label: str | None = None, + ) -> list[dict[str, Any]] | dict[str, str]: """ Install a specified repository revision from a specified Tool Shed into this Galaxy instance. This example demonstrates installation of a repository diff --git a/bioblend/galaxy/users/__init__.py b/bioblend/galaxy/users/__init__.py index 040f987af..0c6fe56fa 100644 --- a/bioblend/galaxy/users/__init__.py +++ b/bioblend/galaxy/users/__init__.py @@ -6,7 +6,6 @@ from typing import ( Any, - Optional, TYPE_CHECKING, ) @@ -26,9 +25,9 @@ def __init__(self, galaxy_instance: "GalaxyInstance") -> None: def get_users( self, deleted: bool = False, - f_email: Optional[str] = None, - f_name: Optional[str] = None, - f_any: Optional[str] = None, + f_email: str | None = None, + f_name: str | None = None, + f_any: str | None = None, ) -> list[dict[str, Any]]: """ Get a list of all registered users. If ``deleted`` is set to ``True``, @@ -230,7 +229,7 @@ def get_or_create_user_apikey(self, user_id: str) -> str: url = self._make_url(user_id) + "/api_key" return self._get(url=url) - def update_user(self, user_id: str, user_data: Optional[dict] = None, **kwargs: Any) -> dict[str, Any]: + def update_user(self, user_id: str, user_data: dict | None = None, **kwargs: Any) -> dict[str, Any]: """ Update user information. You can either pass the attributes you want to change in the user_data dictionary, or provide them separately as diff --git a/bioblend/galaxy/workflows/__init__.py b/bioblend/galaxy/workflows/__init__.py index 9daed5577..bcbf75631 100644 --- a/bioblend/galaxy/workflows/__init__.py +++ b/bioblend/galaxy/workflows/__init__.py @@ -7,7 +7,6 @@ from typing import ( Any, Literal, - Optional, TYPE_CHECKING, ) @@ -29,7 +28,7 @@ def __init__(self, galaxy_instance: "GalaxyInstance") -> None: # the 'deleted' option is not available for workflows def get_workflows( - self, workflow_id: Optional[str] = None, name: Optional[str] = None, published: bool = False + self, workflow_id: str | None = None, name: str | None = None, published: bool = False ) -> list[dict[str, Any]]: """ Get all workflows, or select a subset by specifying optional arguments @@ -68,9 +67,9 @@ def get_workflows( def show_workflow( self, workflow_id: str, - version: Optional[int] = None, - instance: Optional[bool] = None, - legacy: Optional[bool] = None, + version: int | None = None, + instance: bool | None = None, + legacy: bool | None = None, ) -> dict[str, Any]: """ Display information needed to run a workflow. @@ -217,7 +216,7 @@ def import_shared_workflow(self, workflow_id: str) -> dict[str, Any]: return self._post(url=url, payload=payload) def export_workflow_dict( - self, workflow_id: str, version: Optional[int] = None, style: Optional[Literal["ga", "format2"]] = None + self, workflow_id: str, version: int | None = None, style: Literal["ga", "format2"] | None = None ) -> dict[str, Any]: """ Exports a workflow. @@ -311,24 +310,24 @@ def update_workflow(self, workflow_id: str, **kwargs: Any) -> dict[str, Any]: def invoke_workflow( self, workflow_id: str, - inputs: Optional[dict] = None, - params: Optional[dict] = None, - history_id: Optional[str] = None, - history_name: Optional[str] = None, + inputs: dict | None = None, + params: dict | None = None, + history_id: str | None = None, + history_name: str | None = None, import_inputs_to_history: bool = False, - replacement_params: Optional[dict] = None, + replacement_params: dict | None = None, allow_tool_state_corrections: bool = False, - inputs_by: Optional[InputsBy] = None, + inputs_by: InputsBy | None = None, parameters_normalized: bool = False, require_exact_tool_versions: bool = True, - version: Optional[int] = None, + version: int | None = None, use_cached_job: bool = False, - parameters: Optional[dict] = None, + parameters: dict | None = None, instance: bool = False, - resource_params: Optional[dict[str, Any]] = None, - preferred_object_store_id: Optional[str] = None, - preferred_intermediate_object_store_id: Optional[str] = None, - preferred_outputs_object_store_id: Optional[str] = None, + resource_params: dict[str, Any] | None = None, + preferred_object_store_id: str | None = None, + preferred_intermediate_object_store_id: str | None = None, + preferred_outputs_object_store_id: str | None = None, ) -> dict[str, Any]: """ Invoke the workflow identified by ``workflow_id``. This will @@ -804,9 +803,9 @@ def extract_workflow_from_history( self, history_id: str, workflow_name: str, - job_ids: Optional[list[str]] = None, - dataset_hids: Optional[list[str]] = None, - dataset_collection_hids: Optional[list[str]] = None, + job_ids: list[str] | None = None, + dataset_hids: list[str] | None = None, + dataset_collection_hids: list[str] | None = None, ) -> dict[str, Any]: """ Extract a workflow from a history. diff --git a/bioblend/galaxyclient.py b/bioblend/galaxyclient.py index 049aff35f..13d3b806c 100644 --- a/bioblend/galaxyclient.py +++ b/bioblend/galaxyclient.py @@ -12,8 +12,6 @@ import logging from typing import ( Any, - Optional, - Union, ) import requests @@ -35,14 +33,14 @@ class GalaxyClient: def __init__( self, url: str, - key: Optional[str] = None, - email: Optional[str] = None, - password: Optional[str] = None, + key: str | None = None, + email: str | None = None, + password: str | None = None, *, - token: Optional[str] = None, + token: str | None = None, verify: bool = True, - timeout: Optional[float] = None, - user_agent: Optional[str] = None, + timeout: float | None = None, + user_agent: str | None = None, ) -> None: """ :param verify: Whether to verify the server's TLS certificate @@ -76,14 +74,14 @@ def __init__( # If key has been supplied, use it; otherwise just set email and # password and grab user's key before first request. if key: - self._key: Optional[str] = key + self._key: str | None = key elif token: - self.token: Optional[str] = token + self.token: str | None = token else: self._key = None self.email = email self.password = password - self.json_headers: dict[str, Union[str, bytes, None]] = {"Content-Type": "application/json"} + self.json_headers: dict[str, str | bytes | None] = {"Content-Type": "application/json"} if user_agent: self.json_headers["User-Agent"] = user_agent # json_headers needs to be set before key can be defined, otherwise authentication with email/password causes an error @@ -149,7 +147,7 @@ def make_get_request(self, url: str, **kwargs: Any) -> requests.Response: return r def make_post_request( - self, url: str, payload: Optional[dict] = None, params: Optional[dict] = None, files_attached: bool = False + self, url: str, payload: dict | None = None, params: dict | None = None, files_attached: bool = False ) -> Any: """ Make a POST request using the provided ``url`` and ``payload``. @@ -212,7 +210,7 @@ def my_dumps(d: dict) -> dict: ) def make_delete_request( - self, url: str, payload: Optional[dict] = None, params: Optional[dict] = None + self, url: str, payload: dict | None = None, params: dict | None = None ) -> requests.Response: """ Make a DELETE request using the provided ``url`` and the optional @@ -237,7 +235,7 @@ def make_delete_request( ) return r - def make_put_request(self, url: str, payload: Optional[dict] = None, params: Optional[dict] = None) -> Any: + def make_put_request(self, url: str, payload: dict | None = None, params: dict | None = None) -> Any: """ Make a PUT request using the provided ``url`` with required payload. @@ -273,7 +271,7 @@ def make_put_request(self, url: str, payload: Optional[dict] = None, params: Opt status_code=r.status_code, ) - def make_patch_request(self, url: str, payload: Optional[dict] = None, params: Optional[dict] = None) -> Any: + def make_patch_request(self, url: str, payload: dict | None = None, params: dict | None = None) -> Any: """ Make a PATCH request using the provided ``url`` with required payload. @@ -313,9 +311,9 @@ def get_tus_uploader( self, path: str, url: str = "/upload/resumable_upload", - storage: Optional[str] = None, - metadata: Optional[dict] = None, - chunk_size: Optional[int] = UPLOAD_CHUNK_SIZE, + storage: str | None = None, + metadata: dict | None = None, + chunk_size: int | None = UPLOAD_CHUNK_SIZE, ) -> tusclient.uploader.Uploader: """ Return the tus client uploader object for uploading to the Galaxy tus endpoint @@ -357,7 +355,7 @@ def get_tus_uploader( ) @property - def key(self) -> Optional[str]: + def key(self) -> str | None: if not self._key and self.email is not None and self.password is not None: unencoded_credentials = f"{self.email}:{self.password}" authorization = base64.b64encode(unencoded_credentials.encode()) diff --git a/bioblend/toolshed/__init__.py b/bioblend/toolshed/__init__.py index 4644babde..05477f931 100644 --- a/bioblend/toolshed/__init__.py +++ b/bioblend/toolshed/__init__.py @@ -2,8 +2,6 @@ A base representation of an instance of Tool Shed """ -from typing import Optional - from bioblend.galaxyclient import GalaxyClient from bioblend.toolshed import ( categories, @@ -16,12 +14,12 @@ class ToolShedInstance(GalaxyClient): def __init__( self, url: str, - key: Optional[str] = None, - email: Optional[str] = None, - password: Optional[str] = None, + key: str | None = None, + email: str | None = None, + password: str | None = None, *, verify: bool = True, - user_agent: Optional[str] = None, + user_agent: str | None = None, ) -> None: """ A base representation of a connection to a ToolShed instance, identified diff --git a/bioblend/toolshed/repositories/__init__.py b/bioblend/toolshed/repositories/__init__.py index 06ab081c7..9deefd76b 100644 --- a/bioblend/toolshed/repositories/__init__.py +++ b/bioblend/toolshed/repositories/__init__.py @@ -5,9 +5,7 @@ from typing import ( Any, Literal, - Optional, TYPE_CHECKING, - Union, ) from bioblend.galaxy.client import Client @@ -23,7 +21,7 @@ class ToolShedRepositoryClient(Client): def __init__(self, toolshed_instance: "ToolShedInstance") -> None: super().__init__(toolshed_instance) - def get_repositories(self, name: Optional[str] = None, owner: Optional[str] = None) -> list[dict[str, Any]]: + def get_repositories(self, name: str | None = None, owner: str | None = None) -> list[dict[str, Any]]: """ Get all repositories in a Galaxy Tool Shed, or select a subset by specifying optional arguments for filtering (e.g. a repository name). @@ -299,10 +297,10 @@ def get_repository_revision_install_info( def repository_revisions( self, - downloadable: Optional[bool] = None, - malicious: Optional[bool] = None, - missing_test_components: Optional[bool] = None, - includes_tools: Optional[bool] = None, + downloadable: bool | None = None, + malicious: bool | None = None, + missing_test_components: bool | None = None, + includes_tools: bool | None = None, ) -> list[dict[str, Any]]: """ Returns a (possibly filtered) list of dictionaries that include @@ -410,7 +408,7 @@ def show_repository_revision( url = "/".join((self.gi.url, "repository_revisions", metadata_id)) return self._get(url=url) - def update_repository(self, id: str, tar_ball_path: str, commit_message: Optional[str] = None) -> dict[str, Any]: + def update_repository(self, id: str, tar_ball_path: str, commit_message: str | None = None) -> dict[str, Any]: """ Update the contents of a Tool Shed repository with specified tar ball. @@ -448,11 +446,11 @@ def create_repository( self, name: str, synopsis: str, - description: Optional[str] = None, + description: str | None = None, type: Literal["unrestricted", "repository_suite_definition", "tool_dependency_definition"] = "unrestricted", - remote_repository_url: Optional[str] = None, - homepage_url: Optional[str] = None, - category_ids: Optional[list[str]] = None, + remote_repository_url: str | None = None, + homepage_url: str | None = None, + category_ids: list[str] | None = None, ) -> dict[str, Any]: """ Create a new repository in a Tool Shed. @@ -499,7 +497,7 @@ def create_repository( "type": "unrestricted", "user_id": "adb5f5c93f827949"} """ - payload: dict[str, Union[str, list[str]]] = { + payload: dict[str, str | list[str]] = { "name": name, "synopsis": synopsis, } @@ -520,12 +518,12 @@ def create_repository( def update_repository_metadata( self, toolShed_id: str, - name: Optional[str] = None, - synopsis: Optional[str] = None, - description: Optional[str] = None, - remote_repository_url: Optional[str] = None, - homepage_url: Optional[str] = None, - category_ids: Optional[list[str]] = None, + name: str | None = None, + synopsis: str | None = None, + description: str | None = None, + remote_repository_url: str | None = None, + homepage_url: str | None = None, + category_ids: list[str] | None = None, ) -> dict[str, Any]: """ Update metadata of a Tool Shed repository. @@ -555,7 +553,7 @@ def update_repository_metadata( :rtype: dict :return: a dictionary containing information about the updated repository. """ - payload: dict[str, Union[str, list[str]]] = {} + payload: dict[str, str | list[str]] = {} if name: payload["name"] = name if synopsis: diff --git a/bioblend/util/__init__.py b/bioblend/util/__init__.py index fd05b9299..fd3cd3c8f 100644 --- a/bioblend/util/__init__.py +++ b/bioblend/util/__init__.py @@ -3,7 +3,6 @@ Any, IO, NamedTuple, - Optional, TypeVar, ) @@ -16,7 +15,7 @@ def close(self) -> None: self.fd.close() -def attach_file(path: str, name: Optional[str] = None) -> FileStream: +def attach_file(path: str, name: str | None = None) -> FileStream: """ Attach a path to a request payload object. diff --git a/pyproject.toml b/pyproject.toml index 48583af37..15b492f5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,6 @@ classifiers = [ "Intended Audience :: Developers", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -31,7 +30,7 @@ classifiers = [ "Topic :: Scientific/Engineering :: Bio-Informatics", "Typing :: Typed", ] -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ "PyYAML", "requests>=2.20.0", @@ -56,13 +55,13 @@ Documentation = "https://bioblend.readthedocs.io/" [tool.black] include = '\.pyi?$' line-length = 120 -target-version = ['py39'] +target-version = ['py310'] [tool.darker] isort = true [tool.ruff] -target-version = "py39" +target-version = "py310" [tool.ruff.lint] select = ["E", "F", "B", "C4", "G", "ISC", "UP"] diff --git a/run_bioblend_tests.sh b/run_bioblend_tests.sh index d9e641cb6..050b4e896 100755 --- a/run_bioblend_tests.sh +++ b/run_bioblend_tests.sh @@ -14,7 +14,7 @@ Options: -p PORT Port to use for the Galaxy server. Defaults to 8080. -e TOX_ENV - Work against specified tox environments. Defaults to py39. + Work against specified tox environments. Defaults to py310. -t BIOBLEND_TESTS Subset of tests to run, e.g. 'tests/TestGalaxyObjects.py::TestHistory::test_create_delete' . Defaults @@ -33,7 +33,7 @@ get_abs_dirname () { cd "$1" && pwd } -e_val=py39 +e_val=py310 GALAXY_PORT=8080 while getopts 'hcg:e:p:t:r:v:' option; do case $option in diff --git a/tox.ini b/tox.ini index f5a8f9b6b..fe50d188d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = lint, py39 +envlist = lint, py310 [testenv] commands =