mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge pull request #12783 from jmchilton/type_fixes_managers_3
Type fixes for various visualization backend Python files.
This commit is contained in:
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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] = {}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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=<HistoryDatasetAssociation>).
|
||||
"""
|
||||
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?
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user