Mercurial > repos > shellac > sam_consensus_v3
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 """Define the context around Planemo computation. | |
2 | |
3 Abstractions for cross cutting concerns (logging, workspace management, | |
4 etc.). | |
5 """ | |
6 import abc | |
7 import logging.config | |
8 import os | |
9 import shutil | |
10 import sys | |
11 import traceback | |
12 from urllib.request import urlopen | |
13 | |
14 from planemo.config import read_global_config | |
15 | |
16 | |
17 class PlanemoContextInterface(metaclass=abc.ABCMeta): | |
18 """Interface Planemo operations use to access workspace context.""" | |
19 | |
20 @abc.abstractmethod | |
21 def set_option_source(self, param_name, option_source, force=False): | |
22 """Specify how an option was set.""" | |
23 | |
24 @abc.abstractmethod | |
25 def get_option_source(self, param_name): | |
26 """Return OptionSource value indicating how the option was set.""" | |
27 | |
28 @abc.abstractproperty | |
29 def global_config(self): | |
30 """Read Planemo's global configuration.""" | |
31 | |
32 @abc.abstractmethod | |
33 def log(self, msg, *args): | |
34 """Log a message.""" | |
35 | |
36 @abc.abstractmethod | |
37 def vlog(self, msg, *args, **kwds): | |
38 """Log a message only if verbose is enabled.""" | |
39 | |
40 @abc.abstractproperty | |
41 def workspace(self): | |
42 """Create and return Planemo's workspace.""" | |
43 | |
44 @abc.abstractproperty | |
45 def galaxy_profiles_directory(self): | |
46 """Create a return a directory for storing Galaxy profiles.""" | |
47 | |
48 @abc.abstractmethod | |
49 def cache_download(self, url, destination): | |
50 """Use workspace to cache download of ``url``.""" | |
51 | |
52 | |
53 class PlanemoContext(PlanemoContextInterface): | |
54 """Implementation of ``PlanemoContextInterface``""" | |
55 | |
56 def __init__(self): | |
57 """Construct a Context object using execution environment.""" | |
58 self.home = os.getcwd() | |
59 self._global_config = None | |
60 # Will be set by planemo CLI driver | |
61 self.verbose = False | |
62 self.planemo_config = None | |
63 self.planemo_directory = None | |
64 self.option_source = {} | |
65 | |
66 def set_option_source(self, param_name, option_source, force=False): | |
67 """Specify how an option was set.""" | |
68 if not force: | |
69 assert param_name not in self.option_source, "No option source for [%s]" % param_name | |
70 self.option_source[param_name] = option_source | |
71 | |
72 def get_option_source(self, param_name): | |
73 """Return OptionSource value indicating how the option was set.""" | |
74 assert param_name in self.option_source, "No option source for [%s]" % param_name | |
75 return self.option_source[param_name] | |
76 | |
77 @property | |
78 def global_config(self): | |
79 """Read Planemo's global configuration. | |
80 | |
81 As defined most simply by ~/.planemo.yml. | |
82 """ | |
83 if self._global_config is None: | |
84 self._global_config = read_global_config(self.planemo_config) | |
85 return self._global_config or {} | |
86 | |
87 def log(self, msg, *args): | |
88 """Log a message.""" | |
89 if args: | |
90 msg %= args | |
91 self._log_message(msg) | |
92 | |
93 def vlog(self, msg, *args, **kwds): | |
94 """Log a message only if verbose is enabled.""" | |
95 if self.verbose: | |
96 self.log(msg, *args) | |
97 if kwds.get("exception", False): | |
98 traceback.print_exc(file=sys.stderr) | |
99 | |
100 @property | |
101 def workspace(self): | |
102 """Create and return Planemo's workspace. | |
103 | |
104 By default this will be ``~/.planemo``. | |
105 """ | |
106 if not self.planemo_directory: | |
107 raise Exception("No planemo workspace defined.") | |
108 workspace = self.planemo_directory | |
109 return self._ensure_directory(workspace, "workspace") | |
110 | |
111 @property | |
112 def galaxy_profiles_directory(self): | |
113 """Create a return a directory for storing Galaxy profiles.""" | |
114 path = os.path.join(self.workspace, "profiles") | |
115 return self._ensure_directory(path, "Galaxy profiles") | |
116 | |
117 def cache_download(self, url, destination): | |
118 """Use workspace to cache download of ``url``.""" | |
119 cache = os.path.join(self.workspace, "cache") | |
120 if not os.path.exists(cache): | |
121 os.makedirs(cache) | |
122 filename = os.path.basename(url) | |
123 cache_destination = os.path.join(cache, filename) | |
124 if not os.path.exists(cache_destination): | |
125 with urlopen(url) as fh: | |
126 content = fh.read() | |
127 if len(content) == 0: | |
128 raise Exception("Failed to download [%s]." % url) | |
129 with open(cache_destination, "wb") as f: | |
130 f.write(content) | |
131 | |
132 shutil.copy(cache_destination, destination) | |
133 | |
134 def _ensure_directory(self, path, name): | |
135 if not os.path.exists(path): | |
136 os.makedirs(path) | |
137 if not os.path.isdir(path): | |
138 template = "Planemo %s directory [%s] unavailable." | |
139 message = template % (name, path) | |
140 raise Exception(message) | |
141 return path | |
142 | |
143 def _log_message(self, message): | |
144 """Extension point for overriding I/O.""" | |
145 print(message) | |
146 | |
147 | |
148 def configure_standard_planemo_logging(verbose): | |
149 """Configure Planemo's default logging rules.""" | |
150 logging_config = { | |
151 'version': 1, | |
152 'disable_existing_loggers': False, | |
153 'formatters': { | |
154 'verbose': { | |
155 'format': '%(name)s %(levelname)s %(asctime)s: %(message)s' | |
156 }, | |
157 'simple': { | |
158 'format': '%(name)s %(levelname)s: %(message)s' | |
159 }, | |
160 }, | |
161 'handlers': { | |
162 'console': { | |
163 'level': 'DEBUG', | |
164 'class': 'logging.StreamHandler', | |
165 'formatter': 'simple' if not verbose else 'verbose' | |
166 }, | |
167 }, | |
168 'loggers': { | |
169 # Suppress CWL is beta warning, for Planemo purposes - it is absolutely not. | |
170 'galaxy.tools.parser.factory': { | |
171 'handlers': ['console'], | |
172 'propagate': False, | |
173 'level': 'ERROR' if not verbose else "DEBUG", | |
174 }, | |
175 'galaxy.tools.deps.commands': { | |
176 'handlers': ['console'], | |
177 'propagate': False, | |
178 'level': 'ERROR' if not verbose else "DEBUG", | |
179 }, | |
180 'galaxy': { | |
181 'handlers': ['console'], | |
182 'propagate': False, | |
183 'level': 'INFO' if not verbose else "DEBUG", | |
184 }, | |
185 # @jmchilton | |
186 # I'm fixing up Planemo's lint functionality for CWL and I keep seeing this for the | |
187 # schema metadata stuff (e.g. in the workflows repo). "rdflib.term WARNING: | |
188 # http://schema.org/docs/!DOCTYPE html does not look like a valid URI, trying to | |
189 # serialize this will break.". I'm going to suppress this warning I think, or are the | |
190 # examples wrong and should declare their namespaces differently in some way? | |
191 # @mr-c | |
192 # That particular warning is worth suppressing. A PR to silence it permanently would be very welcome! | |
193 # https://github.com/RDFLib/rdflib/blob/master/rdflib/term.py#L225 | |
194 'rdflib.term': { | |
195 'handlers': ['console'], | |
196 'propagate': False, | |
197 'level': 'ERROR' if not verbose else "DEBUG", | |
198 } | |
199 }, | |
200 'root': { | |
201 'handlers': ['console'], | |
202 'propagate': False, | |
203 'level': 'WARNING' if not verbose else "DEBUG", | |
204 } | |
205 } | |
206 logging.config.dictConfig(logging_config) | |
207 | |
208 | |
209 __all__ = ( | |
210 'configure_standard_planemo_logging', | |
211 'PlanemoContextInterface', | |
212 'PlanemoContext', | |
213 ) |