Coverage for python/lsst/daf/butler/registry/_butler_registry.py: 84%
32 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-12 09:44 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-12 09:44 +0000
1# This file is part of daf_butler.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This software is dual licensed under the GNU General Public License and also
10# under a 3-clause BSD license. Recipients may choose which of these licenses
11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12# respectively. If you choose the GPL option then the following text applies
13# (but note that there is still no warranty even if you opt for BSD instead):
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation, either version 3 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
28from __future__ import annotations
30__all__ = ("_ButlerRegistry",)
32from abc import abstractmethod
33from typing import TYPE_CHECKING
35from lsst.resources import ResourcePathExpression
37from .._config import Config
38from ..dimensions import DimensionConfig
39from ._config import RegistryConfig
40from ._defaults import RegistryDefaults
41from ._registry import Registry
43if TYPE_CHECKING:
44 from .._butler_config import ButlerConfig
45 from .interfaces import CollectionRecord, DatastoreRegistryBridgeManager
48class _ButlerRegistry(Registry):
49 """Registry interface extended with methods used by Butler implementation.
51 Each registry implementation can have its own constructor parameters.
52 The assumption is that an instance of a specific subclass will be
53 constructed from configuration using `Registry.fromConfig()`.
54 The base class will look for a ``cls`` entry and call that specific
55 `fromConfig()` method.
56 """
58 defaultConfigFile: str | None = None
59 """Path to configuration defaults. Accessed within the ``configs`` resource
60 or relative to a search path. Can be None if no defaults specified.
61 """
63 @classmethod
64 def forceRegistryConfig(
65 cls, config: ButlerConfig | RegistryConfig | Config | str | None
66 ) -> RegistryConfig:
67 """Force the supplied config to a `RegistryConfig`.
69 Parameters
70 ----------
71 config : `RegistryConfig`, `Config` or `str` or `None`
72 Registry configuration, if missing then default configuration will
73 be loaded from registry.yaml.
75 Returns
76 -------
77 registry_config : `RegistryConfig`
78 A registry config.
79 """
80 if not isinstance(config, RegistryConfig):
81 if isinstance(config, str | Config) or config is None:
82 config = RegistryConfig(config)
83 else:
84 raise ValueError(f"Incompatible Registry configuration: {config}")
85 return config
87 @classmethod
88 @abstractmethod
89 def createFromConfig(
90 cls,
91 config: RegistryConfig | str | None = None,
92 dimensionConfig: DimensionConfig | str | None = None,
93 butlerRoot: ResourcePathExpression | None = None,
94 ) -> _ButlerRegistry:
95 """Create registry database and return `_ButlerRegistry` instance.
97 This method initializes database contents, database must be empty
98 prior to calling this method.
100 Parameters
101 ----------
102 config : `RegistryConfig` or `str`, optional
103 Registry configuration, if missing then default configuration will
104 be loaded from registry.yaml.
105 dimensionConfig : `DimensionConfig` or `str`, optional
106 Dimensions configuration, if missing then default configuration
107 will be loaded from dimensions.yaml.
108 butlerRoot : convertible to `lsst.resources.ResourcePath`, optional
109 Path to the repository root this `Registry` will manage.
111 Returns
112 -------
113 registry : `_ButlerRegistry`
114 A new `_ButlerRegistry` instance.
116 Notes
117 -----
118 This class will determine the concrete `_ButlerRegistry` subclass to
119 use from configuration. Each subclass should implement this method
120 even if it can not create a registry.
121 """
122 raise NotImplementedError()
124 @classmethod
125 @abstractmethod
126 def fromConfig(
127 cls,
128 config: ButlerConfig | RegistryConfig | Config | str,
129 butlerRoot: ResourcePathExpression | None = None,
130 writeable: bool = True,
131 defaults: RegistryDefaults | None = None,
132 ) -> _ButlerRegistry:
133 """Create `_ButlerRegistry` subclass instance from ``config``.
135 Registry database must be initialized prior to calling this method.
137 Parameters
138 ----------
139 config : `ButlerConfig`, `RegistryConfig`, `Config` or `str`
140 Registry configuration
141 butlerRoot : convertible to `lsst.resources.ResourcePath`, optional
142 Path to the repository root this `Registry` will manage.
143 writeable : `bool`, optional
144 If `True` (default) create a read-write connection to the database.
145 defaults : `~lsst.daf.butler.registry.RegistryDefaults`, optional
146 Default collection search path and/or output `~CollectionType.RUN`
147 collection.
149 Returns
150 -------
151 registry : `_ButlerRegistry` (subclass)
152 A new `_ButlerRegistry` subclass instance.
154 Notes
155 -----
156 This class will determine the concrete `_ButlerRegistry` subclass to
157 use from configuration. Each subclass should implement this method.
158 """
159 # The base class implementation should trampoline to the correct
160 # subclass. No implementation should ever use this implementation
161 # directly. If no class is specified, default to the standard
162 # registry.
163 raise NotImplementedError()
165 @abstractmethod
166 def copy(self, defaults: RegistryDefaults | None = None) -> _ButlerRegistry:
167 """Create a new `_ButlerRegistry` backed by the same data repository
168 and connection as this one, but independent defaults.
170 Parameters
171 ----------
172 defaults : `~lsst.daf.butler.registry.RegistryDefaults`, optional
173 Default collections and data ID values for the new registry. If
174 not provided, ``self.defaults`` will be used (but future changes
175 to either registry's defaults will not affect the other).
177 Returns
178 -------
179 copy : `_ButlerRegistry`
180 A new `_ButlerRegistry` instance with its own defaults.
182 Notes
183 -----
184 Because the new registry shares a connection with the original, they
185 also share transaction state (despite the fact that their `transaction`
186 context manager methods do not reflect this), and must be used with
187 care.
188 """
189 raise NotImplementedError()
191 @abstractmethod
192 def _get_collection_record(self, name: str) -> CollectionRecord:
193 """Return the record for this collection.
195 Parameters
196 ----------
197 name : `str`
198 Name of the collection for which the record is to be retrieved.
200 Returns
201 -------
202 record : `CollectionRecord`
203 The record for this collection.
204 """
205 raise NotImplementedError()
207 @abstractmethod
208 def getDatastoreBridgeManager(self) -> DatastoreRegistryBridgeManager:
209 """Return an object that allows a new `Datastore` instance to
210 communicate with this `Registry`.
212 Returns
213 -------
214 manager : `~.interfaces.DatastoreRegistryBridgeManager`
215 Object that mediates communication between this `Registry` and its
216 associated datastores.
217 """
218 raise NotImplementedError()