diff --git a/lib/galaxy/visualization/data_providers/basic.py b/lib/galaxy/visualization/data_providers/basic.py index e6a704197c1..dfbcbdec324 100644 --- a/lib/galaxy/visualization/data_providers/basic.py +++ b/lib/galaxy/visualization/data_providers/basic.py @@ -1,7 +1,9 @@ import sys from json import loads +from typing import Iterator from galaxy.datatypes.tabular import Tabular +from galaxy.model import DatasetInstance class BaseDataProvider: @@ -12,6 +14,7 @@ class BaseDataProvider: - write subsets of data to new datasets """ + original_dataset: DatasetInstance def __init__(self, converted_dataset=None, original_dataset=None, dependencies=None, error_max_vals="Only the first %i values are returned."): @@ -28,7 +31,7 @@ class BaseDataProvider: """ raise Exception("Unimplemented Function") - def get_iterator(self, **kwargs): + def get_iterator(self, data_file, chrom, start, end, **kwargs) -> Iterator[str]: """ Returns an iterator that provides data in the region chrom:start-end """ diff --git a/lib/galaxy/visualization/data_providers/genome.py b/lib/galaxy/visualization/data_providers/genome.py index 99e4d7f8df3..0291258bc38 100644 --- a/lib/galaxy/visualization/data_providers/genome.py +++ b/lib/galaxy/visualization/data_providers/genome.py @@ -10,7 +10,7 @@ import re import sys from contextlib import contextmanager from json import loads -from typing import Dict, Union +from typing import Any, Dict, IO, Iterator, List, Optional, Tuple, Union import pysam from bx.bbi.bigbed_file import BigBedFile @@ -19,6 +19,7 @@ from bx.interval_index_file import Indexes from galaxy.datatypes.interval import Bed, Gff, Gtf from galaxy.datatypes.util.gff_util import convert_gff_coords_to_bed, GFFFeature, GFFInterval, GFFReaderWrapper, parse_gff_attributes +from galaxy.model import DatasetInstance from galaxy.visualization.data_providers.basic import BaseDataProvider from galaxy.visualization.data_providers.cigar import get_ref_based_read_seq_and_cigar @@ -30,6 +31,8 @@ from galaxy.visualization.data_providers.cigar import get_ref_based_read_seq_and # Can be be removed once https://github.com/pysam-developers/pysam/issues/939 is resolved. pysam.set_verbosity(0) +PAYLOAD_LIST_TYPE = List[Optional[Union[str, int, float, List[Tuple[int, int]]]]] + def float_nan(n): ''' @@ -89,9 +92,9 @@ class FeatureLocationIndexDataProvider(BaseDataProvider): # Find query in file using binary search. low = 0 - high = file_len / line_len + high = int(file_len / line_len) while low < high: - mid = (low + high) // 2 + mid: int = (low + high) // 2 position = mid * line_len textloc_file.seek(position) @@ -171,7 +174,7 @@ class GenomeDataProvider(BaseDataProvider): """ raise Exception("Unimplemented Function") - def get_iterator(self, data_file, chrom, start, end, **kwargs): + def get_iterator(self, data_file, chrom, start, end, **kwargs) -> Iterator[str]: """ Returns an iterator that provides data in the region chrom:start-end """ @@ -272,6 +275,8 @@ class GenomeDataProvider(BaseDataProvider): class FilterableMixin: + original_dataset: DatasetInstance + def get_filters(self): """ Returns a dataset's filters. """ # Get filters. @@ -329,7 +334,7 @@ class TabixDataProvider(GenomeDataProvider, FilterableMixin): with pysam.TabixFile(self.dependencies['bgzip'].file_name, index=index_path) as f: yield f - def get_iterator(self, data_file, chrom, start, end, **kwargs): + def get_iterator(self, data_file, chrom, start, end, **kwargs) -> Iterator[str]: # chrom must be a string, start/end integers. # in previous versions of pysam, unicode was accepted for chrom, but not in 8.4 chrom = str(chrom) @@ -338,7 +343,7 @@ class TabixDataProvider(GenomeDataProvider, FilterableMixin): if end >= (2 << 29): end = (2 << 29 - 1) # Tabix-enforced maximum # Get iterator using either naming scheme. - iterator = iter([]) + iterator: Iterator[str] = iter([]) if chrom in data_file.contigs: iterator = data_file.fetch(reference=chrom, start=start, end=end) else: @@ -406,7 +411,7 @@ class IntervalDataProvider(GenomeDataProvider): feature = line.split() length = len(feature) # Unique id is just a hash of the line - payload = [hash(line), int(feature[start_col]), int(feature[end_col])] + payload: PAYLOAD_LIST_TYPE = [hash(line), int(feature[start_col]), int(feature[end_col])] if no_detail: rval.append(payload) @@ -484,7 +489,7 @@ class BedDataProvider(GenomeDataProvider): feature = line.split() length = len(feature) # Unique id is just a hash of the line - payload = [hash(line), int(feature[1]), int(feature[2])] + payload: PAYLOAD_LIST_TYPE = [hash(line), int(feature[1]), int(feature[2])] if no_detail: rval.append(payload) @@ -549,7 +554,7 @@ class RawBedDataProvider(BedDataProvider): for large datasets. """ - def get_iterator(self, data_file, chrom=None, start=None, end=None, **kwargs): + def get_iterator(self, data_file, chrom, start, end, **kwargs): # Read first line in order to match chrom naming format. line = data_file.readline() dataset_chrom = line.split()[0] @@ -677,7 +682,7 @@ class VcfDataProvider(GenomeDataProvider): if samples_data: # Process and pack samples' genotype and count alleles across samples. - alleles_seen = {} + alleles_seen: Dict[int, bool] = {} has_alleles = False for sample in samples_data: @@ -685,10 +690,10 @@ class VcfDataProvider(GenomeDataProvider): genotype = sample.split(':')[0] has_alleles = False alleles_seen.clear() - for allele in genotype_re.split(genotype): + for allele_str in genotype_re.split(genotype): try: # This may throw a ValueError if allele is missing. - allele = int(allele) + allele = int(allele_str) # Only count allele if it hasn't been seen yet. if allele != 0 and allele not in alleles_seen: @@ -856,7 +861,7 @@ class BamDataProvider(GenomeDataProvider, FilterableMixin): index_filename=self.converted_dataset.file_name) as f: yield f - def get_iterator(self, data_file, chrom, start, end, **kwargs): + def get_iterator(self, data_file, chrom, start, end, **kwargs) -> Iterator[str]: """ Returns an iterator that provides data in the region chrom:start-end """ @@ -873,7 +878,7 @@ class BamDataProvider(GenomeDataProvider, FilterableMixin): try: data = data_file.fetch(start=start, end=end, reference=chrom) except ValueError: - return None + return iter([]) return data def process_data(self, iterator, start_val=0, max_vals=None, ref_seq=None, @@ -966,7 +971,7 @@ class BamDataProvider(GenomeDataProvider, FilterableMixin): # Encode reads as list of lists. # results = [] - paired_pending = {} + paired_pending: Dict[str, Dict[str, Any]] = {} unmapped = 0 message = None count = 0 @@ -1110,6 +1115,9 @@ class BBIDataProvider(GenomeDataProvider): dataset_type = 'bigwig' + def _get_dataset(self) -> Tuple[IO[bytes], Union[BigBedFile, BigWigFile]]: + ... + def valid_chroms(self): # No way to return this info as of now return None @@ -1146,7 +1154,7 @@ class BBIDataProvider(GenomeDataProvider): min_val = 0 max_val = 0 mean = 0 - sd = 0 + sd = 0.0 if summary is not None: # Does the summary contain any defined values? valid_count = summary.valid_count[0] @@ -1288,7 +1296,7 @@ class IntervalIndexDataProvider(GenomeDataProvider, FilterableMixin): i = Indexes(self.converted_dataset.file_name) yield i - def get_iterator(self, data_file, chrom, start, end, **kwargs): + def get_iterator(self, data_file, chrom, start, end, **kwargs) -> Iterator[str]: """ Returns an iterator for data in data_file in chrom:start-end """ @@ -1406,16 +1414,18 @@ class GtfTabixDataProvider(TabixDataProvider): # TODO: extend this code or use code in gff_util to process GFF/3 as well # and then create a generic GFFDataProvider that can be used with both # raw and tabix datasets. - features = {} + features: Dict[str, List[GFFInterval]] = {} + for line in iterator: line_attrs = parse_gff_attributes(line.split('\t')[8]) transcript_id = line_attrs['transcript_id'] + feature_list: List[GFFInterval] if transcript_id in features: - feature = features[transcript_id] + feature_list = features[transcript_id] else: - feature = [] - features[transcript_id] = feature - feature.append(GFFInterval(None, line.split('\t'))) + feature_list = [] + features[transcript_id] = feature_list + feature_list.append(GFFInterval(None, line.split('\t'))) # Process data. filter_cols = loads(kwargs.get("filter_cols", "[]")) @@ -1480,7 +1490,7 @@ class ENCODEPeakDataProvider(GenomeDataProvider): feature = line.split() # Feature initialization. - payload = [ + payload: PAYLOAD_LIST_TYPE = [ # GUID is just a hash of the line hash(line), # Add start, end. @@ -1597,7 +1607,7 @@ class ChromatinInteractionsDataProvider(GenomeDataProvider): class ChromatinInteractionsTabixDataProvider(TabixDataProvider, ChromatinInteractionsDataProvider): - def get_iterator(self, data_file, chrom, start=0, end=sys.maxsize, interchromosomal=False, **kwargs): + def get_iterator(self, data_file, chrom, start=0, end=sys.maxsize, interchromosomal=False, **kwargs) -> Iterator[str]: """ """ # Modify start as needed to get earlier interactions with start region. @@ -1625,7 +1635,7 @@ class ChromatinInteractionsTabixDataProvider(TabixDataProvider, ChromatinInterac # -def package_gff_feature(feature, no_detail=False, filter_cols=None): +def package_gff_feature(feature, no_detail=False, filter_cols=None) -> PAYLOAD_LIST_TYPE: """ Package a GFF feature in an array for data providers. """ filter_cols = filter_cols or [] feature = convert_gff_coords_to_bed(feature) diff --git a/lib/galaxy/visualization/data_providers/phyloviz/__init__.py b/lib/galaxy/visualization/data_providers/phyloviz/__init__.py index c1778a30ebc..d869c5a6e7e 100644 --- a/lib/galaxy/visualization/data_providers/phyloviz/__init__.py +++ b/lib/galaxy/visualization/data_providers/phyloviz/__init__.py @@ -1,4 +1,5 @@ """ Data providers code for PhyloViz """ +from typing import Any, Dict from galaxy.visualization.data_providers.basic import BaseDataProvider from galaxy.visualization.data_providers.phyloviz.newickparser import Newick_Parser @@ -23,7 +24,7 @@ class PhylovizDataProvider(BaseDataProvider): file_name = self.original_dataset.file_name parseMsg = None jsonDicts = [] - rval = {'dataset_type': self.dataset_type} + rval: Dict[str, Any] = {'dataset_type': self.dataset_type} if file_ext in ["newick", "nhx"]: # parses newick files newickParser = Newick_Parser() diff --git a/lib/galaxy/visualization/data_providers/phyloviz/baseparser.py b/lib/galaxy/visualization/data_providers/phyloviz/baseparser.py index 45d9e1f6ae6..162a20c90b3 100644 --- a/lib/galaxy/visualization/data_providers/phyloviz/baseparser.py +++ b/lib/galaxy/visualization/data_providers/phyloviz/baseparser.py @@ -1,4 +1,5 @@ import json +from typing import Any, Dict class Node: @@ -14,6 +15,8 @@ class Node: self.length, self.bootstrap = kwargs.get("length", 0), kwargs.get("bootstrap", None) self.events = kwargs.get("events", "") + self.parent = None + # clean up boot strap values if self.bootstrap == -1: self.bootstrap = None @@ -28,7 +31,7 @@ class Node: def __str__(self): return f"{self.name} id:{str(self.id)}, depth: {str(self.depth)}" - def toJson(self): + def toJson(self) -> Dict[str, Any]: """Converts the data in the node to a dict representation of json""" thisJson = { "name": self.name, @@ -79,7 +82,7 @@ class PhyloTree: self.id += 1 return Node(nodeName, **kwargs) - def addRoot(self, root): + def addRoot(self, root: Node): """Creates a root for phyloTree""" assert isinstance(root, Node) root.parent = None @@ -88,7 +91,7 @@ class PhyloTree: def generateJsonableDict(self): """Changes itself into a dictonary by recurssively calling the tojson on all its nodes. Think of it as a dict in an array of dict in an array of dict and so on...""" - jsonTree = "" + jsonTree: Dict[str, Any] if self.root: assert isinstance(self.root, Node) jsonTree = self.root.toJson() diff --git a/lib/galaxy/visualization/data_providers/phyloviz/newickparser.py b/lib/galaxy/visualization/data_providers/phyloviz/newickparser.py index e329d7cb8ec..1328884805c 100644 --- a/lib/galaxy/visualization/data_providers/phyloviz/newickparser.py +++ b/lib/galaxy/visualization/data_providers/phyloviz/newickparser.py @@ -52,17 +52,17 @@ class Newick_Parser(Base_Parser): if len(childString) == 0: continue nodeInfo = childString.split(":") - name, length, bootstrap = "", None, -1 + name, length, bootstrap = "", None, -1.0 if len(nodeInfo) == 2: # has length info length = nodeInfo[1] # checking for bootstap values name = nodeInfo[0] try: # Nexus may bootstrap in names position - name = float(name) - if 0 <= name <= 1: - bootstrap = name - elif 1 <= name <= 100: - bootstrap = name / 100 + name_as_float = float(name) + if 0 <= name_as_float <= 1: + bootstrap = name_as_float + elif 1 <= name_as_float <= 100: + bootstrap = name_as_float / 100 name = "" except ValueError: name = nodeInfo[0] diff --git a/lib/galaxy/visualization/data_providers/registry.py b/lib/galaxy/visualization/data_providers/registry.py index ad573b80608..a0557b13582 100644 --- a/lib/galaxy/visualization/data_providers/registry.py +++ b/lib/galaxy/visualization/data_providers/registry.py @@ -1,4 +1,8 @@ -from galaxy.datatypes.data import Newick, Nexus +from typing import Dict, Optional, Type, Union + +from typing_extensions import Literal + +from galaxy.datatypes.data import Data, Newick, Nexus from galaxy.datatypes.interval import ( Bed, ChromatinInteractions, @@ -11,10 +15,15 @@ from galaxy.datatypes.tabular import Tabular, Vcf from galaxy.datatypes.xml import Phyloxml from galaxy.model import NoConverterException from galaxy.visualization.data_providers import genome -from galaxy.visualization.data_providers.basic import ColumnDataProvider +from galaxy.visualization.data_providers.basic import BaseDataProvider, ColumnDataProvider from galaxy.visualization.data_providers.phyloviz import PhylovizDataProvider +# a dict keyed on datatype with a 'default' string key. +PROVIDER_BY_DATATYPE_CLASS_DICT = Dict[Union[Literal["default"], Type[Data]], Type[BaseDataProvider]] +DATA_PROVIDER_BY_TYPE_NAME_DICT = Dict[str, Union[Type[BaseDataProvider], PROVIDER_BY_DATATYPE_CLASS_DICT]] + + class DataProviderRegistry: """ Registry for data providers that enables listing and lookup. @@ -24,7 +33,7 @@ class DataProviderRegistry: # Mapping from dataset type name to a class that can fetch data from a file of that # type. First key is converted dataset type; if result is another dict, second key # is original dataset type. - self.dataset_type_name_to_data_provider = { + self.dataset_type_name_to_data_provider: DATA_PROVIDER_BY_TYPE_NAME_DICT = { "tabix": { Vcf: genome.VcfTabixDataProvider, Bed: genome.BedTabixDataProvider, @@ -49,7 +58,9 @@ class DataProviderRegistry: sources, source parameter is ignored. """ - data_provider = None + data_provider: Optional[BaseDataProvider] + data_provider_class: Type[BaseDataProvider] + if raw: # Working with raw data. if isinstance(original_dataset.datatype, Gff): @@ -72,9 +83,12 @@ class DataProviderRegistry: # Provider requested by name; get from mappings. value = self.dataset_type_name_to_data_provider[name] if isinstance(value, dict): + # value is a PROVIDER_BY_DATATYPE_CLASS_DICT # Get converter by dataset extension; if there is no data provider, # get the default. - data_provider_class = value.get(original_dataset.datatype.__class__, value.get("default")) + default_type = value.get("default") + assert default_type + data_provider_class = value.get(original_dataset.datatype.__class__, default_type) else: data_provider_class = value diff --git a/lib/galaxy/visualization/genomes.py b/lib/galaxy/visualization/genomes.py index 1e780af553b..3624f087e3b 100644 --- a/lib/galaxy/visualization/genomes.py +++ b/lib/galaxy/visualization/genomes.py @@ -11,7 +11,7 @@ from galaxy.exceptions import ( ObjectNotFound, ReferenceDataError, ) -from galaxy.structured_app import MinimalManagerApp +from galaxy.structured_app import StructuredApp from galaxy.util.bunch import Bunch log = logging.getLogger(__name__) @@ -197,7 +197,7 @@ class Genomes: Provides information about available genome data and methods for manipulating that data. """ - def __init__(self, app: MinimalManagerApp): + def __init__(self, app: StructuredApp): self.app = app # Create list of genomes from app.genome_builds self.genomes: Dict[str, Genome] = {} diff --git a/lib/galaxy/visualization/plugins/config_parser.py b/lib/galaxy/visualization/plugins/config_parser.py index ca2c2f7972f..29b345fc65c 100644 --- a/lib/galaxy/visualization/plugins/config_parser.py +++ b/lib/galaxy/visualization/plugins/config_parser.py @@ -1,5 +1,5 @@ import logging - +from typing import Any, Dict, List import galaxy.model from galaxy.util import asbool @@ -108,7 +108,7 @@ class VisualizationsConfigParser: # param modifiers provide extra information for other params (e.g. hda_ldda='hda' -> dataset_id is an hda id) # store these modifiers in a 2-level dictionary { target_param: { param_modifier_key: { param_mod_data } # ugh - wish we didn't need these - param_modifiers = {} + param_modifiers: Dict[str, Any] = {} param_modifier_elements = param_confs.findall('param_modifier') if param_confs is not None else [] for param_modifier_conf in param_modifier_elements: param_modifier = self.param_modifier_parser.parse(param_modifier_conf) @@ -287,7 +287,7 @@ class DataSourceParser: # tests should NOT include expensive operations: reading file data, running jobs, etc. # do as much here as possible to reduce the overhead of seeing if a visualization is applicable # currently tests are or'd only (could be and'd or made into compound boolean tests) - tests = [] + tests: List[Dict[str, Any]] = [] if not xml_tree_list: return tests @@ -354,7 +354,7 @@ class DataSourceParser: the registry to convert the data_source into one or more appropriate params for the visualization. """ - to_param_dict = {} + to_param_dict: Dict[str, Any] = {} if not xml_tree_list: return to_param_dict @@ -419,13 +419,15 @@ class DictParser(dict): self.update(dict(parent_element.items())) for element in parent_element: if len(element) > 0: + asJson: Any if element.tag == element[0].tag: - aDict = ListParser(element) + asJson = ListParser(element) else: aDict = DictParser(element) - if element.items(): - aDict.update(dict(element.items())) - self.update({element.tag: aDict}) + if element.items(): + aDict.update(dict(element.items())) + asJson = aDict + self.update({element.tag: asJson}) elif element.items(): self.update({element.tag: dict(element.items())}) else: diff --git a/lib/galaxy/visualization/plugins/plugin.py b/lib/galaxy/visualization/plugins/plugin.py index 26466b286da..64d5b1439ef 100644 --- a/lib/galaxy/visualization/plugins/plugin.py +++ b/lib/galaxy/visualization/plugins/plugin.py @@ -5,6 +5,7 @@ from a query string and render a webpage based on those data. import copy import logging import os +from typing import Any, Dict import mako.lookup @@ -23,6 +24,7 @@ class ServesTemplatesPluginMixin: """ An object that renders (mako) template files from the server. """ + path: str #: default number of templates to search for plugin template lookup DEFAULT_TEMPLATE_COLLECTION_SIZE = 10 @@ -85,9 +87,8 @@ class VisualizationPlugin(ServesTemplatesPluginMixin): Render and return the text of the non-saved plugin webpage/fragment. """ # not saved - no existing config - config = {} # set up render vars based on plugin.config and kwargs - render_vars = self._build_render_vars(config, trans=trans, **kwargs) + render_vars = self._build_render_vars({}, trans=trans, **kwargs) return self._render(render_vars, trans=trans, embedded=embedded) def render_saved(self, visualization, trans=None, embedded=None, **kwargs): @@ -95,7 +96,7 @@ class VisualizationPlugin(ServesTemplatesPluginMixin): Render and return the text of the plugin webpage/fragment using the config/data of a saved visualization. """ - config = self._get_saved_visualization_config(visualization, **kwargs) + config: Dict[str, Any] = self._get_saved_visualization_config(visualization, **kwargs) # pass the saved visualization config for parsing into render vars render_vars = self._build_render_vars(config, trans=trans, **kwargs) # update any values that were loaded from the saved Visualization @@ -134,7 +135,7 @@ class VisualizationPlugin(ServesTemplatesPluginMixin): else: log.debug(f'Visualization has no static path: {path}.') - def _get_saved_visualization_config(self, visualization, revision=None, **kwargs): + def _get_saved_visualization_config(self, visualization, revision=None, **kwargs) -> Dict[str, Any]: """ Return the config of a saved visualization and revision. @@ -144,11 +145,11 @@ class VisualizationPlugin(ServesTemplatesPluginMixin): return copy.copy(visualization.latest_revision.config) # ---- non-public - def _build_render_vars(self, config, trans=None, **kwargs): + def _build_render_vars(self, config: Dict[str, Any], trans=None, **kwargs) -> Dict[str, Any]: """ Build all the variables that will be passed into the renderer. """ - render_vars = {} + render_vars: Dict[str, Any] = {} # Meta variables passed to the template/renderer to describe the visualization being rendered. render_vars.update( visualization_name=self.name, @@ -161,14 +162,14 @@ class VisualizationPlugin(ServesTemplatesPluginMixin): query=kwargs, ) # config based on existing or kwargs - config = self._build_config(config, trans=trans, **kwargs) - render_vars['config'] = config + render_config = self._build_config(config, trans=trans, **kwargs) + render_vars['config'] = render_config # further parse config to resources (models, etc.) used in template based on registry config - resources = self._config_to_resources(trans, config) + resources = self._config_to_resources(trans, render_config) render_vars.update(resources) return render_vars - def _build_config(self, config, trans=None, **kwargs): + def _build_config(self, config, trans=None, **kwargs) -> utils.OpenObject: """ Build the configuration for this new/saved visualization by combining any existing config and the kwargs (gen. from the url query). diff --git a/lib/galaxy/visualization/plugins/resource_parser.py b/lib/galaxy/visualization/plugins/resource_parser.py index 8f583b06122..b1f33bf2d6c 100644 --- a/lib/galaxy/visualization/plugins/resource_parser.py +++ b/lib/galaxy/visualization/plugins/resource_parser.py @@ -5,6 +5,7 @@ a dictionary of string data/ids (often from a query string). import json import logging import weakref +from typing import Callable, Dict, Optional, Union import galaxy.exceptions import galaxy.util @@ -12,11 +13,16 @@ from galaxy.managers import ( hdas as hda_manager, visualizations as visualization_manager ) +from galaxy.model import HistoryDatasetAssociation, LibraryDatasetDatasetAssociation, Visualization from galaxy.util import bunch log = logging.getLogger(__name__) +ParameterPrimitiveType = Union[int, float, str] +ParameterType = Union[ParameterPrimitiveType, HistoryDatasetAssociation, LibraryDatasetDatasetAssociation, Visualization] + + class ResourceParser: """ Given a parameter dictionary (often a converted query string) and a @@ -28,7 +34,7 @@ class ResourceParser: The keys used to store the new values can optionally be re-mapped to new keys (e.g. dataset_id="NNN" -> hda=). """ - primitive_parsers = { + primitive_parsers: Dict[str, Callable[[str], ParameterPrimitiveType]] = { 'str': lambda param: galaxy.util.sanitize_html.sanitize_html(param), 'bool': lambda param: galaxy.util.string_as_bool(param), 'int': int, @@ -127,20 +133,21 @@ class ResourceParser: return config # TODO: I would LOVE to rip modifiers out completely - def parse_parameter_modifiers(self, trans, param_modifiers, query_params): + def parse_parameter_modifiers(self, trans, param_modifiers, query_params) -> Dict[str, Dict[str, Optional[ParameterType]]]: """ Parse and return parameters that are meant to modify other parameters, be grouped with them, or are needed to successfully parse other parameters. """ # only one level of modification - down that road lies madness # parse the modifiers out of query_params first since they modify the other params coming next - parsed_modifiers = {} + parsed_modifiers: Dict[str, Dict[str, Optional[ParameterType]]] = {} if not param_modifiers: return parsed_modifiers # precondition: expects a two level dictionary # { target_param_name -> { param_modifier_name -> { param_modifier_data }}} for target_param_name, modifier_dict in param_modifiers.items(): - parsed_modifiers[target_param_name] = target_modifiers = {} + target_modifiers: Dict[str, Optional[ParameterType]] = {} + parsed_modifiers[target_param_name] = target_modifiers for modifier_name, modifier_config in modifier_dict.items(): query_val = query_params.get(modifier_name, None) @@ -153,7 +160,7 @@ class ResourceParser: return parsed_modifiers - def parse_parameter_default(self, trans, param_config): + def parse_parameter_default(self, trans, param_config) -> Optional[ParameterType]: """ Parse any default values for the given param, defaulting the default to `None`. @@ -175,18 +182,7 @@ class ResourceParser: a resource usable directly by a template. """ param_type = expected_param_data.get('type') - # constrain_to = expected_param_data.get( 'constrain_to' ) - csv = expected_param_data.get('csv') - - parsed_param = None - - # handle recursion for csv values - if csv and recurse: - parsed_param = [] - query_param_list = galaxy.util.listify(query_param) - for query_param in query_param_list: - parsed_param.append(self._parse_param(trans, expected_param_data, query_param, recurse=False)) - return parsed_param + parsed_param: Optional[ParameterType] = None if param_type in self.primitive_parsers: # TODO: what about param modifiers on primitives? diff --git a/lib/galaxy/webapps/galaxy/controllers/visualization.py b/lib/galaxy/webapps/galaxy/controllers/visualization.py index 6763ec833eb..3900d330e1c 100644 --- a/lib/galaxy/webapps/galaxy/controllers/visualization.py +++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py @@ -18,14 +18,12 @@ from sqlalchemy import ( from sqlalchemy.orm import eagerload, undefer from galaxy import model, util, web -from galaxy.datatypes.interval import Bed from galaxy.managers.hdas import HDAManager from galaxy.managers.sharable import SlugBuilder from galaxy.model.item_attrs import UsesAnnotations, UsesItemRatings from galaxy.structured_app import StructuredApp from galaxy.util import sanitize_text, unicodify from galaxy.util.sanitize_html import sanitize_html -from galaxy.visualization.data_providers.genome import RawBedDataProvider from galaxy.visualization.data_providers.phyloviz import PhylovizDataProvider from galaxy.visualization.genomes import decode_dbkey from galaxy.visualization.genomes import GenomeRegion @@ -879,26 +877,3 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization if len(args) > 0: nargs += args return os.path.join(*nargs) - - @web.json - def bookmarks_from_dataset(self, trans, hda_id=None, ldda_id=None): - if hda_id: - hda_ldda = "hda" - dataset_id = hda_id - elif ldda_id: - hda_ldda = "ldda" - dataset_id = ldda_id - dataset = self.get_hda_or_ldda(trans, hda_ldda, dataset_id) - - rows = [] - if isinstance(dataset.datatype, Bed): - data = RawBedDataProvider(original_dataset=dataset).get_iterator() - for i, line in enumerate(data): - if (i > 500): - break - fields = line.split() - location = name = f"{fields[0]}:{fields[1]}-{fields[2]}" - if len(fields) > 3: - name = fields[4] - rows.append([location, name]) - return {'data': rows} diff --git a/setup.cfg b/setup.cfg index 3bda14a42a1..2bfa4b570ba 100644 --- a/setup.cfg +++ b/setup.cfg @@ -80,10 +80,6 @@ check_untyped_defs = False check_untyped_defs = False [mypy-galaxy.web.framework.middleware.error] check_untyped_defs = False -[mypy-galaxy.visualization.genomes] -check_untyped_defs = False -[mypy-galaxy.visualization.data_providers.phyloviz.baseparser] -check_untyped_defs = False [mypy-galaxy.util.topsort] check_untyped_defs = False [mypy-galaxy.util.submodules] @@ -135,8 +131,6 @@ check_untyped_defs = False check_untyped_defs = False [mypy-galaxy.containers.docker_decorators] check_untyped_defs = False -[mypy-galaxy.visualization.data_providers.phyloviz.newickparser] -check_untyped_defs = False [mypy-galaxy.tools.bundled.maf.maf_to_interval] check_untyped_defs = False [mypy-galaxy.tools.bundled.maf.maf_stats] @@ -373,8 +367,6 @@ check_untyped_defs = False check_untyped_defs = False [mypy-tool_shed.repository_types.registry] check_untyped_defs = False -[mypy-galaxy.visualization.plugins.config_parser] -check_untyped_defs = False [mypy-galaxy.util.pastescript.serve] check_untyped_defs = False [mypy-galaxy.tools.errors] @@ -511,14 +503,8 @@ check_untyped_defs = False check_untyped_defs = False [mypy-tool_shed.utility_containers] check_untyped_defs = False -[mypy-galaxy.visualization.data_providers.genome] -check_untyped_defs = False -[mypy-galaxy.visualization.data_providers.phyloviz] -check_untyped_defs = False [mypy-galaxy.datatypes.registry] check_untyped_defs = False -[mypy-galaxy.visualization.data_providers.registry] -check_untyped_defs = False [mypy-galaxy.tools.data_fetch] check_untyped_defs = False [mypy-galaxy.tools.parameters.dynamic_options] @@ -599,16 +585,12 @@ check_untyped_defs = False check_untyped_defs = False [mypy-galaxy.queue_worker] check_untyped_defs = False -[mypy-galaxy.visualization.plugins.resource_parser] -check_untyped_defs = False [mypy-galaxy.tools] check_untyped_defs = False [mypy-galaxy.jobs.mapper] check_untyped_defs = False [mypy-galaxy.workflow.modules] check_untyped_defs = False -[mypy-galaxy.visualization.plugins.plugin] -check_untyped_defs = False [mypy-galaxy.tools.evaluation] check_untyped_defs = False [mypy-galaxy.managers.history_contents]