def get_registry(cls): """ Return all objects of this class registered with current workflow """ workflow = get_workflow() if not hasattr(workflow, "ymp_object_registry"): workflow.ymp_object_registry = AttrDict() registry = workflow.ymp_object_registry if cls.__name__ not in registry: registry[cls.__name__] = AttrDict() return registry[cls.__name__]
def absdir(self): """ Dictionary of absolute paths of named YMP directories """ return AttrDict({ name: os.path.normpath(os.path.join(self.root, os.path.expanduser(value))) for name, value in self.dir.items() })
def rules(self): return AttrDict(self.workflow._rules)
def get_paths(self, absolute=False): return AttrDict((key, self.get_path(key, absolute)) for key in self.keys() if self.get(key) is not None)
def ref(self): """ Configure references """ return AttrDict(self._references)
def projects(self): """ Configured projects """ return AttrDict(self._datasets)
def __init__(self, env_file: Optional[str] = None, dag: Optional[object] = None, singularity_img=None, name: Optional[str] = None, packages: Optional[Union[list, str]] = None, base: str = "none", channels: Optional[Union[list, str]] = None, rule: Optional[Rule] = None) -> None: """Creates an inline defined conda environment Args: name: Name of conda environment (and basename of file) packages: package(s) to be installed into environment. Version constraints can be specified in each package string separated from the package name by whitespace. E.g. ``"blast =2.6*"`` channels: channel(s) to be selected for the environment base: Select a set of default channels and packages to be added to the newly created environment. Sets are defined in conda.defaults in ``yml.yml`` """ cfg = ymp.get_config() pseudo_dag = AttrDict({ 'workflow': { 'persistence': { 'conda_env_path': cfg.absdir.conda_prefix, 'conda_env_archive_path': cfg.absdir.conda_archive_prefix } } }) # must have either name or env_file: if (name and env_file) or not (name or env_file): raise YmpRuleError( self, "Env must have exactly one of `name` and `file`") if name: self.name = name else: self.name, _ = op.splitext(op.basename(env_file)) if env_file: self.dynamic = False self.filename = env_file self.lineno = 1 else: self.dynamic = True env_file = op.join(cfg.ensuredir.dynamic_envs, f"{name}.yml") defaults = { 'name': self.name, 'dependencies': list( ensure_list(packages) + cfg.conda.defaults[base].dependencies), 'channels': list( ensure_list(channels) + cfg.conda.defaults[base].channels) } yaml = YAML(typ='rt') yaml.default_flow_style = False buf = io.StringIO() yaml.dump(defaults, buf) contents = buf.getvalue() disk_contents = "" if op.exists(env_file): with open(env_file, "r") as inf: disk_contents = inf.read() if contents != disk_contents: with open(env_file, "w") as out: out.write(contents) super().__init__(env_file, pseudo_dag, singularity_img) self.register()
def __init__( self, # Snakemake Params: env_file: Optional[str] = None, workflow=None, env_dir=None, container_img=None, cleanup=None, # YMP Params: name: Optional[str] = None, packages: Optional[Union[list, str]] = None, base: str = "none", channels: Optional[Union[list, str]] = None) -> None: """Creates an inline defined conda environment Args: name: Name of conda environment (and basename of file) packages: package(s) to be installed into environment. Version constraints can be specified in each package string separated from the package name by whitespace. E.g. ``"blast =2.6*"`` channels: channel(s) to be selected for the environment base: Select a set of default channels and packages to be added to the newly created environment. Sets are defined in conda.defaults in ``yml.yml`` """ if 'name' in self.__dict__: # already initialized return cfg = ymp.get_config() if env_file: if name: import pdb pdb.set_trace() raise YmpRuleError( self, "Env must not have both 'name' and 'env_file' parameters'") self.dynamic = False self.name, _ = op.splitext(op.basename(env_file)) self.packages = None self.base = None self.channels = None # Override location for exceptions: self.filename = env_file self.lineno = 1 elif name: self.dynamic = True self.name = name self.packages = ensure_list( packages) + cfg.conda.defaults[base].dependencies self.channels = ensure_list( channels) + cfg.conda.defaults[base].channels env_file = op.join(cfg.ensuredir.dynamic_envs, f"{name}.yml") contents = self._get_dynamic_contents() self._update_file(env_file, contents) else: raise YmpRuleError( self, "Env must have either 'name' or 'env_file' parameter") # Unlike within snakemake, we create these objects before the workflow is fully # initialized, which means we need to create a fake one: if not workflow: workflow = AttrDict({ 'persistence': { 'conda_env_path': cfg.ensuredir.conda_prefix, 'conda_env_archive_path': cfg.ensuredir.conda_archive_prefix, }, 'conda_frontend': cfg.conda.frontend, 'singularity_args': '', }) super().__init__(env_file, workflow, env_dir if env_dir else cfg.ensuredir.conda_prefix, container_img, cleanup) self.register()