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

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/>. 

27 

28from __future__ import annotations 

29 

30__all__ = ("_ButlerRegistry",) 

31 

32from abc import abstractmethod 

33from typing import TYPE_CHECKING 

34 

35from lsst.resources import ResourcePathExpression 

36 

37from .._config import Config 

38from ..dimensions import DimensionConfig 

39from ._config import RegistryConfig 

40from ._defaults import RegistryDefaults 

41from ._registry import Registry 

42 

43if TYPE_CHECKING: 

44 from .._butler_config import ButlerConfig 

45 from .interfaces import CollectionRecord, DatastoreRegistryBridgeManager 

46 

47 

48class _ButlerRegistry(Registry): 

49 """Registry interface extended with methods used by Butler implementation. 

50 

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 """ 

57 

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 """ 

62 

63 @classmethod 

64 def forceRegistryConfig( 

65 cls, config: ButlerConfig | RegistryConfig | Config | str | None 

66 ) -> RegistryConfig: 

67 """Force the supplied config to a `RegistryConfig`. 

68 

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. 

74 

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 

86 

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. 

96 

97 This method initializes database contents, database must be empty 

98 prior to calling this method. 

99 

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. 

110 

111 Returns 

112 ------- 

113 registry : `_ButlerRegistry` 

114 A new `_ButlerRegistry` instance. 

115 

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() 

123 

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``. 

134 

135 Registry database must be initialized prior to calling this method. 

136 

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. 

148 

149 Returns 

150 ------- 

151 registry : `_ButlerRegistry` (subclass) 

152 A new `_ButlerRegistry` subclass instance. 

153 

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() 

164 

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. 

169 

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). 

176 

177 Returns 

178 ------- 

179 copy : `_ButlerRegistry` 

180 A new `_ButlerRegistry` instance with its own defaults. 

181 

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() 

190 

191 @abstractmethod 

192 def _get_collection_record(self, name: str) -> CollectionRecord: 

193 """Return the record for this collection. 

194 

195 Parameters 

196 ---------- 

197 name : `str` 

198 Name of the collection for which the record is to be retrieved. 

199 

200 Returns 

201 ------- 

202 record : `CollectionRecord` 

203 The record for this collection. 

204 """ 

205 raise NotImplementedError() 

206 

207 @abstractmethod 

208 def getDatastoreBridgeManager(self) -> DatastoreRegistryBridgeManager: 

209 """Return an object that allows a new `Datastore` instance to 

210 communicate with this `Registry`. 

211 

212 Returns 

213 ------- 

214 manager : `~.interfaces.DatastoreRegistryBridgeManager` 

215 Object that mediates communication between this `Registry` and its 

216 associated datastores. 

217 """ 

218 raise NotImplementedError()