Skip to content

Commit b014171

Browse files
committed
Use ResourcePath instead of ButlerURI throughout.
Also replaces a few Union[str, ButlerURI] and similar with the new ResourcePathExpression type alias.
1 parent 347f216 commit b014171

8 files changed

Lines changed: 86 additions & 83 deletions

File tree

doc/lsst.pipe.base/creating-a-pipeline.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ s, and discussing common conventions when creating `Pipelines`.
2727
A Basic Pipeline
2828
----------------
2929

30-
`Pipeline` documents are written using yaml syntax. If you are unfamiliar with
30+
`Pipeline` documents are written using yaml syntax. If you are unfamiliar with
3131
yaml, there are many guides across the internet, but the basic idea is that it
3232
is a simple markup language to describe key, value mappings, and lists of
3333
values (which may be further mappings).
@@ -109,12 +109,12 @@ configuration options that alter the way the task executes. Because
109109
description field) some tasks may need specific configurations set to
110110
enable/disable behavior in the context of the specific `Pipeline`.
111111

112-
To configure a task associated with a particular label, the value associated
112+
To configure a task associated with a particular label, the value associated
113113
with the label must be changed from the qualified task name to a new
114114
sub-mapping. This new sub mapping should have two keys, ``class`` and
115115
``config``.
116116

117-
The ``class`` key should point to the same qualified task name as before. The
117+
The ``class`` key should point to the same qualified task name as before. The
118118
value associated with the ``config`` keyword is itself a mapping where
119119
configuration overrides are declared. The example below shows this behavior
120120
in action.
@@ -371,7 +371,7 @@ extend the total `Pipeline`.
371371

372372
If a ``label`` declared in the the ``tasks`` section was declared in one of
373373
the imported ``Pipelines``, one of two things happen. If the label is
374-
associated with the same `PipelineTask` that was declared in the imported
374+
associated with the same `PipelineTask` that was declared in the imported
375375
pipeline, this definition will be extended. This means that any configs
376376
declared in the imported `Pipeline` will be merged with configs declared in
377377
the current `Pipeline` with the current declaration taking config precedence.
@@ -421,7 +421,7 @@ is loaded.
421421

422422
The simplest form of a `Pipeline` specification is the URI at which the
423423
`Pipeline` can be found. This URI may be any supported by
424-
`lsst.daf.butler.ButlerURI`. In the case that the pipeline resides in a file
424+
`lsst.resources.ResourcePath`. In the case that the pipeline resides in a file
425425
located on a filesystem accessible by the machine that will be processing the
426426
`Pipeline` (i.e. a file URI), there is no need to preface the URI with
427427
``file://``, a bare file path is assumed to be a file based URI.

python/lsst/pipe/base/configOverrides.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from enum import Enum
3030
from operator import attrgetter
3131

32-
from lsst.daf.butler import ButlerURI
32+
from lsst.resources import ResourcePath
3333
from lsst.utils import doImport
3434

3535
OverrideTypes = Enum("OverrideTypes", "Value File Python Instrument")
@@ -148,11 +148,11 @@ def addFileOverride(self, filename):
148148
149149
Parameters
150150
----------
151-
filename : `str` or `ButlerURI`
151+
filename : convertible to `ResourcePath`
152152
Path or URI to the override file. All URI schemes supported by
153-
`ButlerURI` are supported.
153+
`ResourcePath` are supported.
154154
"""
155-
self._overrides.append((OverrideTypes.File, ButlerURI(filename)))
155+
self._overrides.append((OverrideTypes.File, ResourcePath(filename)))
156156

157157
def addValueOverride(self, field, value):
158158
"""Add override for a specific field.

python/lsst/pipe/base/executionButlerBuilder.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@
2727
from collections import defaultdict
2828
from typing import Callable, DefaultDict, Iterable, List, Mapping, Optional, Set, Tuple, Union
2929

30-
from lsst.daf.butler import Butler, ButlerURI, Config, DataCoordinate, DatasetRef, DatasetType
30+
from lsst.daf.butler import Butler, Config, DataCoordinate, DatasetRef, DatasetType
3131
from lsst.daf.butler.core.repoRelocation import BUTLER_ROOT_TAG
3232
from lsst.daf.butler.transfers import RepoExportContext
33+
from lsst.resources import ResourcePath, ResourcePathExpression
3334
from lsst.utils.introspection import get_class_of
3435

3536
from .graph import QuantumGraph, QuantumNode
@@ -142,7 +143,7 @@ def _export(
142143
return yamlBuffer
143144

144145

145-
def _setupNewButler(butler: Butler, outputLocation: ButlerURI, dirExists: bool) -> Butler:
146+
def _setupNewButler(butler: Butler, outputLocation: ResourcePath, dirExists: bool) -> Butler:
146147
# Set up the new butler object at the specified location
147148
if dirExists:
148149
# Remove the existing table, if the code got this far and this exists
@@ -218,7 +219,7 @@ def _import(
218219
def buildExecutionButler(
219220
butler: Butler,
220221
graph: QuantumGraph,
221-
outputLocation: Union[str, ButlerURI],
222+
outputLocation: ResourcePathExpression,
222223
run: str,
223224
*,
224225
clobber: bool = False,
@@ -242,9 +243,9 @@ def buildExecutionButler(
242243
graph : `QuantumGraph`
243244
Graph containing nodes that are to be exported into an execution
244245
butler
245-
outputLocation : `str` or `~lsst.daf.butler.ButlerURI`
246+
outputLocation : convertible to `ResourcePath
246247
URI Location at which the execution butler is to be exported. May be
247-
specified as a string or a ButlerURI instance.
248+
specified as a string or a `ResourcePath` instance.
248249
run : `str` optional
249250
The run collection that the exported datasets are to be placed in. If
250251
None, the default value in registry.defaults will be used.
@@ -282,7 +283,7 @@ def buildExecutionButler(
282283
Raised if specified output URI does not correspond to a directory
283284
"""
284285
# We know this must refer to a directory.
285-
outputLocation = ButlerURI(outputLocation, forceDirectory=True)
286+
outputLocation = ResourcePath(outputLocation, forceDirectory=True)
286287

287288
# Do this first to Fail Fast if the output exists
288289
if (dirExists := outputLocation.exists()) and not clobber:

python/lsst/pipe/base/graph/graph.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
)
5555

5656
import networkx as nx
57-
from lsst.daf.butler import ButlerURI, DatasetRef, DimensionRecordsAccumulator, DimensionUniverse, Quantum
57+
from lsst.daf.butler import DatasetRef, DimensionRecordsAccumulator, DimensionUniverse, Quantum
58+
from lsst.resources import ResourcePath, ResourcePathExpression
5859
from networkx.drawing.nx_agraph import write_dot
5960

6061
from ..connections import iterConnections
@@ -717,14 +718,14 @@ def saveUri(self, uri):
717718
718719
Parameters
719720
----------
720-
uri : `ButlerURI` or `str`
721+
uri : convertible to `ResourcePath`
721722
URI to where the graph should be saved.
722723
"""
723724
buffer = self._buildSaveObject()
724-
butlerUri = ButlerURI(uri)
725-
if butlerUri.getExtension() not in (".qgraph"):
725+
path = ResourcePath(uri)
726+
if path.getExtension() not in (".qgraph"):
726727
raise TypeError(f"Can currently only save a graph in qgraph format not {uri}")
727-
butlerUri.write(buffer) # type: ignore # Ignore because bytearray is safe to use in place of bytes
728+
path.write(buffer) # type: ignore # Ignore because bytearray is safe to use in place of bytes
728729

729730
@property
730731
def metadata(self) -> Optional[MappingProxyType[str, Any]]:
@@ -736,7 +737,7 @@ def metadata(self) -> Optional[MappingProxyType[str, Any]]:
736737
@classmethod
737738
def loadUri(
738739
cls,
739-
uri: Union[ButlerURI, str],
740+
uri: ResourcePathExpression,
740741
universe: DimensionUniverse,
741742
nodes: Optional[Iterable[Union[str, uuid.UUID]]] = None,
742743
graphID: Optional[BuildId] = None,
@@ -746,7 +747,7 @@ def loadUri(
746747
747748
Parameters
748749
----------
749-
uri : `ButlerURI` or `str`
750+
uri : convertible to `ResourcePath`
750751
URI from where to load the graph.
751752
universe: `~lsst.daf.butler.DimensionUniverse`
752753
DimensionUniverse instance, not used by the method itself but
@@ -789,8 +790,8 @@ def loadUri(
789790
initialization. To make sure that DimensionUniverse exists this method
790791
accepts dummy DimensionUniverse argument.
791792
"""
792-
uri = ButlerURI(uri)
793-
# With ButlerURI we have the choice of always using a local file
793+
uri = ResourcePath(uri)
794+
# With ResourcePath we have the choice of always using a local file
794795
# or reading in the bytes directly. Reading in bytes can be more
795796
# efficient for reasonably-sized pickle files when the resource
796797
# is remote. For now use the local file variant. For a local file
@@ -810,16 +811,15 @@ def loadUri(
810811
return qgraph
811812

812813
@classmethod
813-
def readHeader(cls, uri: Union[ButlerURI, str], minimumVersion: int = 3) -> Optional[str]:
814+
def readHeader(cls, uri: ResourcePathExpression, minimumVersion: int = 3) -> Optional[str]:
814815
"""Read the header of a `QuantumGraph` pointed to by the uri parameter
815816
and return it as a string.
816817
817818
Parameters
818819
----------
819-
uri : `~lsst.daf.butler.ButlerURI` or `str`
820+
uri : convertible to `ResourcePath`
820821
The location of the `QuantumGraph` to load. If the argument is a
821-
string, it must correspond to a valid `~lsst.daf.butler.ButlerURI`
822-
path.
822+
string, it must correspond to a valid `ResourcePath` path.
823823
minimumVersion : int
824824
Minimum version of a save file to load. Set to -1 to load all
825825
versions. Older versions may need to be loaded, and re-saved
@@ -839,7 +839,7 @@ def readHeader(cls, uri: Union[ButlerURI, str], minimumVersion: int = 3) -> Opti
839839
Raised if the extention of the file specified by uri is not a
840840
`QuantumGraph` extention.
841841
"""
842-
uri = ButlerURI(uri)
842+
uri = ResourcePath(uri)
843843
if uri.getExtension() in (".pickle", ".pkl"):
844844
raise ValueError("Reading a header from a pickle save is not supported")
845845
elif uri.getExtension() in (".qgraph"):

python/lsst/pipe/base/pipeline.py

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@
5353

5454
# -----------------------------
5555
# Imports for other modules --
56-
from lsst.daf.butler import ButlerURI, DatasetType, NamedValueSet, Registry, SkyPixDimension
56+
from lsst.daf.butler import DatasetType, NamedValueSet, Registry, SkyPixDimension
57+
from lsst.resources import ResourcePath, ResourcePathExpression
5758
from lsst.utils import doImport
5859
from lsst.utils.introspection import get_full_type_name
5960

@@ -245,27 +246,27 @@ def fromFile(cls, filename: str) -> Pipeline:
245246
return cls.from_uri(filename)
246247

247248
@classmethod
248-
def from_uri(cls, uri: Union[str, ButlerURI]) -> Pipeline:
249+
def from_uri(cls, uri: ResourcePathExpression) -> Pipeline:
249250
"""Load a pipeline defined in a pipeline yaml file at a location
250251
specified by a URI.
251252
252253
Parameters
253254
----------
254-
uri: `str` or `ButlerURI`
255-
If a string is supplied this should be a URI path that points to a
256-
pipeline defined in yaml format, either as a direct path to the yaml
257-
file, or as a directory containing a "pipeline.yaml" file (the form
258-
used by `write_to_uri` with ``expand=True``). This uri may also
259-
supply additional labels to be used in subsetting the loaded
260-
Pipeline. These labels are separated from the path by a \\#, and
261-
may be specified as a comma separated list, or a range denoted as
262-
beginning..end. Beginning or end may be empty, in which case the
263-
range will be a half open interval. Unlike python iteration bounds,
264-
end bounds are *INCLUDED*. Note that range based selection is not
265-
well defined for pipelines that are not linear in nature, and
266-
correct behavior is not guaranteed, or may vary from run to run. The
267-
same specifiers can be used with a ButlerURI object, by being the
268-
sole contents in the fragments attribute.
255+
uri: convertible to `ResourcePath`
256+
If a string is supplied this should be a URI path that points to a
257+
pipeline defined in yaml format, either as a direct path to the
258+
yaml file, or as a directory containing a "pipeline.yaml" file (the
259+
form used by `write_to_uri` with ``expand=True``). This uri may
260+
also supply additional labels to be used in subsetting the loaded
261+
Pipeline. These labels are separated from the path by a \\#, and
262+
may be specified as a comma separated list, or a range denoted as
263+
beginning..end. Beginning or end may be empty, in which case the
264+
range will be a half open interval. Unlike python iteration bounds,
265+
end bounds are *INCLUDED*. Note that range based selection is not
266+
well defined for pipelines that are not linear in nature, and
267+
correct behavior is not guaranteed, or may vary from run to run.
268+
The same specifiers can be used with a `ResourcePath` object, by
269+
being the sole contents in the fragments attribute.
269270
270271
Returns
271272
-------
@@ -359,7 +360,7 @@ def subsetFromLabels(self, labelSpecifier: LabelSpecifier) -> Pipeline:
359360
return Pipeline.fromIR(self._pipelineIR.subset_from_labels(labelSet))
360361

361362
@staticmethod
362-
def _parse_file_specifier(uri: Union[str, ButlerURI]) -> Tuple[ButlerURI, Optional[LabelSpecifier]]:
363+
def _parse_file_specifier(uri: ResourcePathExpression) -> Tuple[ResourcePath, Optional[LabelSpecifier]]:
363364
"""Split appart a uri and any possible label subsets"""
364365
if isinstance(uri, str):
365366
# This is to support legacy pipelines during transition
@@ -373,9 +374,9 @@ def _parse_file_specifier(uri: Union[str, ButlerURI]) -> Tuple[ButlerURI, Option
373374
)
374375
if uri.count("#") > 1:
375376
raise ValueError("Only one set of labels is allowed when specifying a pipeline to load")
376-
uri = ButlerURI(uri)
377+
uri = ResourcePath(uri)
377378
elif isinstance(uri, Path):
378-
uri = ButlerURI(uri)
379+
uri = ResourcePath(uri)
379380
label_subset = uri.fragment or None
380381

381382
specifier: Optional[LabelSpecifier]
@@ -595,19 +596,19 @@ def toFile(self, filename: str) -> None:
595596

596597
def write_to_uri(
597598
self,
598-
uri: Union[str, ButlerURI],
599+
uri: ResourcePathExpression,
599600
expand: bool = False,
600601
task_defs: Optional[Iterable[TaskDef]] = None,
601602
) -> None:
602603
"""Write the pipeline to a file or directory.
603604
604605
Parameters
605606
----------
606-
uri : `str` or `ButlerURI`
607-
URI to write to; may have any scheme with `ButlerURI` write
608-
or no scheme for a local file/directory. Should have a ``.yaml``
609-
extension if ``expand=False`` and a trailing slash (indicating
610-
a directory-like URI) if ``expand=True``.
607+
uri : convertible to `ResourcePath`
608+
URI to write to; may have any scheme with `ResourcePath` write
609+
support or no scheme for a local file/directory. Should have a
610+
``.yaml`` extension if ``expand=False`` and a trailing slash
611+
(indicating a directory-like URI) if ``expand=True``.
611612
expand : `bool`, optional
612613
If `False`, write the pipeline to a single YAML file with
613614
references to configuration files and other config overrides
@@ -627,7 +628,7 @@ def write_to_uri(
627628
raise RuntimeError(
628629
f"Expanded pipelines are written to directories, not YAML files like {uri}."
629630
)
630-
self._write_expanded_dir(ButlerURI(uri, forceDirectory=True), task_defs=task_defs)
631+
self._write_expanded_dir(ResourcePath(uri, forceDirectory=True), task_defs=task_defs)
631632
else:
632633
self._pipelineIR.write_to_uri(uri)
633634

@@ -741,16 +742,16 @@ def description(self) -> str:
741742
"""The string description of the pipeline."""
742743
return self._pipelineIR.description
743744

744-
def _write_expanded_dir(self, uri: ButlerURI, task_defs: Optional[Iterable[TaskDef]] = None) -> None:
745+
def _write_expanded_dir(self, uri: ResourcePath, task_defs: Optional[Iterable[TaskDef]] = None) -> None:
745746
"""Internal implementation of `write_to_uri` with ``expand=True`` and
746747
a directory-like URI.
747748
748749
Parameters
749750
----------
750-
uri : `str` or `ButlerURI`
751-
URI to write to; may have any scheme with `ButlerURI` write or no
752-
scheme for a local file/directory. Should have a trailing slash
753-
(indicating a directory-like URI).
751+
uri : `ResourcePath`
752+
URI to write to; may have any scheme with `ResourcePath` write
753+
support or no scheme for a local file/directory. Should have a
754+
trailing slash (indicating a directory-like URI).
754755
task_defs : `Iterable` [ `TaskDef` ], optional
755756
Output of `toExpandedPipeline`; may be passed to avoid a second
756757
call to that method internally.

0 commit comments

Comments
 (0)