Mercurial > repos > shellac > sam_consensus_v3
diff env/lib/python3.9/site-packages/planemo/context.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/env/lib/python3.9/site-packages/planemo/context.py Mon Mar 22 18:12:50 2021 +0000 @@ -0,0 +1,213 @@ +"""Define the context around Planemo computation. + +Abstractions for cross cutting concerns (logging, workspace management, +etc.). +""" +import abc +import logging.config +import os +import shutil +import sys +import traceback +from urllib.request import urlopen + +from planemo.config import read_global_config + + +class PlanemoContextInterface(metaclass=abc.ABCMeta): + """Interface Planemo operations use to access workspace context.""" + + @abc.abstractmethod + def set_option_source(self, param_name, option_source, force=False): + """Specify how an option was set.""" + + @abc.abstractmethod + def get_option_source(self, param_name): + """Return OptionSource value indicating how the option was set.""" + + @abc.abstractproperty + def global_config(self): + """Read Planemo's global configuration.""" + + @abc.abstractmethod + def log(self, msg, *args): + """Log a message.""" + + @abc.abstractmethod + def vlog(self, msg, *args, **kwds): + """Log a message only if verbose is enabled.""" + + @abc.abstractproperty + def workspace(self): + """Create and return Planemo's workspace.""" + + @abc.abstractproperty + def galaxy_profiles_directory(self): + """Create a return a directory for storing Galaxy profiles.""" + + @abc.abstractmethod + def cache_download(self, url, destination): + """Use workspace to cache download of ``url``.""" + + +class PlanemoContext(PlanemoContextInterface): + """Implementation of ``PlanemoContextInterface``""" + + def __init__(self): + """Construct a Context object using execution environment.""" + self.home = os.getcwd() + self._global_config = None + # Will be set by planemo CLI driver + self.verbose = False + self.planemo_config = None + self.planemo_directory = None + self.option_source = {} + + def set_option_source(self, param_name, option_source, force=False): + """Specify how an option was set.""" + if not force: + assert param_name not in self.option_source, "No option source for [%s]" % param_name + self.option_source[param_name] = option_source + + def get_option_source(self, param_name): + """Return OptionSource value indicating how the option was set.""" + assert param_name in self.option_source, "No option source for [%s]" % param_name + return self.option_source[param_name] + + @property + def global_config(self): + """Read Planemo's global configuration. + + As defined most simply by ~/.planemo.yml. + """ + if self._global_config is None: + self._global_config = read_global_config(self.planemo_config) + return self._global_config or {} + + def log(self, msg, *args): + """Log a message.""" + if args: + msg %= args + self._log_message(msg) + + def vlog(self, msg, *args, **kwds): + """Log a message only if verbose is enabled.""" + if self.verbose: + self.log(msg, *args) + if kwds.get("exception", False): + traceback.print_exc(file=sys.stderr) + + @property + def workspace(self): + """Create and return Planemo's workspace. + + By default this will be ``~/.planemo``. + """ + if not self.planemo_directory: + raise Exception("No planemo workspace defined.") + workspace = self.planemo_directory + return self._ensure_directory(workspace, "workspace") + + @property + def galaxy_profiles_directory(self): + """Create a return a directory for storing Galaxy profiles.""" + path = os.path.join(self.workspace, "profiles") + return self._ensure_directory(path, "Galaxy profiles") + + def cache_download(self, url, destination): + """Use workspace to cache download of ``url``.""" + cache = os.path.join(self.workspace, "cache") + if not os.path.exists(cache): + os.makedirs(cache) + filename = os.path.basename(url) + cache_destination = os.path.join(cache, filename) + if not os.path.exists(cache_destination): + with urlopen(url) as fh: + content = fh.read() + if len(content) == 0: + raise Exception("Failed to download [%s]." % url) + with open(cache_destination, "wb") as f: + f.write(content) + + shutil.copy(cache_destination, destination) + + def _ensure_directory(self, path, name): + if not os.path.exists(path): + os.makedirs(path) + if not os.path.isdir(path): + template = "Planemo %s directory [%s] unavailable." + message = template % (name, path) + raise Exception(message) + return path + + def _log_message(self, message): + """Extension point for overriding I/O.""" + print(message) + + +def configure_standard_planemo_logging(verbose): + """Configure Planemo's default logging rules.""" + logging_config = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'verbose': { + 'format': '%(name)s %(levelname)s %(asctime)s: %(message)s' + }, + 'simple': { + 'format': '%(name)s %(levelname)s: %(message)s' + }, + }, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'simple' if not verbose else 'verbose' + }, + }, + 'loggers': { + # Suppress CWL is beta warning, for Planemo purposes - it is absolutely not. + 'galaxy.tools.parser.factory': { + 'handlers': ['console'], + 'propagate': False, + 'level': 'ERROR' if not verbose else "DEBUG", + }, + 'galaxy.tools.deps.commands': { + 'handlers': ['console'], + 'propagate': False, + 'level': 'ERROR' if not verbose else "DEBUG", + }, + 'galaxy': { + 'handlers': ['console'], + 'propagate': False, + 'level': 'INFO' if not verbose else "DEBUG", + }, + # @jmchilton + # I'm fixing up Planemo's lint functionality for CWL and I keep seeing this for the + # schema metadata stuff (e.g. in the workflows repo). "rdflib.term WARNING: + # http://schema.org/docs/!DOCTYPE html does not look like a valid URI, trying to + # serialize this will break.". I'm going to suppress this warning I think, or are the + # examples wrong and should declare their namespaces differently in some way? + # @mr-c + # That particular warning is worth suppressing. A PR to silence it permanently would be very welcome! + # https://github.com/RDFLib/rdflib/blob/master/rdflib/term.py#L225 + 'rdflib.term': { + 'handlers': ['console'], + 'propagate': False, + 'level': 'ERROR' if not verbose else "DEBUG", + } + }, + 'root': { + 'handlers': ['console'], + 'propagate': False, + 'level': 'WARNING' if not verbose else "DEBUG", + } + } + logging.config.dictConfig(logging_config) + + +__all__ = ( + 'configure_standard_planemo_logging', + 'PlanemoContextInterface', + 'PlanemoContext', +)