Coverage for python/lsst/daf/butler/registry/_butler_registry.py: 84%

31 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-10-02 08:00 +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 ..core import Config, DimensionConfig 

38from ._config import RegistryConfig 

39from ._defaults import RegistryDefaults 

40from ._registry import Registry 

41 

42if TYPE_CHECKING: 

43 from .._butlerConfig import ButlerConfig 

44 from .interfaces import CollectionRecord, DatastoreRegistryBridgeManager 

45 

46 

47class _ButlerRegistry(Registry): 

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

49 

50 Each registry implementation can have its own constructor parameters. 

51 The assumption is that an instance of a specific subclass will be 

52 constructed from configuration using `Registry.fromConfig()`. 

53 The base class will look for a ``cls`` entry and call that specific 

54 `fromConfig()` method. 

55 """ 

56 

57 defaultConfigFile: str | None = None 

58 """Path to configuration defaults. Accessed within the ``configs`` resource 

59 or relative to a search path. Can be None if no defaults specified. 

60 """ 

61 

62 @classmethod 

63 def forceRegistryConfig( 

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

65 ) -> RegistryConfig: 

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

67 

68 Parameters 

69 ---------- 

70 config : `RegistryConfig`, `Config` or `str` or `None` 

71 Registry configuration, if missing then default configuration will 

72 be loaded from registry.yaml. 

73 

74 Returns 

75 ------- 

76 registry_config : `RegistryConfig` 

77 A registry config. 

78 """ 

79 if not isinstance(config, RegistryConfig): 

80 if isinstance(config, str | Config) or config is None: 

81 config = RegistryConfig(config) 

82 else: 

83 raise ValueError(f"Incompatible Registry configuration: {config}") 

84 return config 

85 

86 @classmethod 

87 @abstractmethod 

88 def createFromConfig( 

89 cls, 

90 config: RegistryConfig | str | None = None, 

91 dimensionConfig: DimensionConfig | str | None = None, 

92 butlerRoot: ResourcePathExpression | None = None, 

93 ) -> _ButlerRegistry: 

94 """Create registry database and return `_ButlerRegistry` instance. 

95 

96 This method initializes database contents, database must be empty 

97 prior to calling this method. 

98 

99 Parameters 

100 ---------- 

101 config : `RegistryConfig` or `str`, optional 

102 Registry configuration, if missing then default configuration will 

103 be loaded from registry.yaml. 

104 dimensionConfig : `DimensionConfig` or `str`, optional 

105 Dimensions configuration, if missing then default configuration 

106 will be loaded from dimensions.yaml. 

107 butlerRoot : convertible to `lsst.resources.ResourcePath`, optional 

108 Path to the repository root this `Registry` will manage. 

109 

110 Returns 

111 ------- 

112 registry : `_ButlerRegistry` 

113 A new `_ButlerRegistry` instance. 

114 

115 Notes 

116 ----- 

117 This class will determine the concrete `_ButlerRegistry` subclass to 

118 use from configuration. Each subclass should implement this method 

119 even if it can not create a registry. 

120 """ 

121 raise NotImplementedError() 

122 

123 @classmethod 

124 @abstractmethod 

125 def fromConfig( 

126 cls, 

127 config: ButlerConfig | RegistryConfig | Config | str, 

128 butlerRoot: ResourcePathExpression | None = None, 

129 writeable: bool = True, 

130 defaults: RegistryDefaults | None = None, 

131 ) -> _ButlerRegistry: 

132 """Create `_ButlerRegistry` subclass instance from ``config``. 

133 

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

135 

136 Parameters 

137 ---------- 

138 config : `ButlerConfig`, `RegistryConfig`, `Config` or `str` 

139 Registry configuration 

140 butlerRoot : convertible to `lsst.resources.ResourcePath`, optional 

141 Path to the repository root this `Registry` will manage. 

142 writeable : `bool`, optional 

143 If `True` (default) create a read-write connection to the database. 

144 defaults : `~lsst.daf.butler.registry.RegistryDefaults`, optional 

145 Default collection search path and/or output `~CollectionType.RUN` 

146 collection. 

147 

148 Returns 

149 ------- 

150 registry : `_ButlerRegistry` (subclass) 

151 A new `_ButlerRegistry` subclass instance. 

152 

153 Notes 

154 ----- 

155 This class will determine the concrete `_ButlerRegistry` subclass to 

156 use from configuration. Each subclass should implement this method. 

157 """ 

158 # The base class implementation should trampoline to the correct 

159 # subclass. No implementation should ever use this implementation 

160 # directly. If no class is specified, default to the standard 

161 # registry. 

162 raise NotImplementedError() 

163 

164 @abstractmethod 

165 def copy(self, defaults: RegistryDefaults | None = None) -> _ButlerRegistry: 

166 """Create a new `_ButlerRegistry` backed by the same data repository 

167 and connection as this one, but independent defaults. 

168 

169 Parameters 

170 ---------- 

171 defaults : `~lsst.daf.butler.registry.RegistryDefaults`, optional 

172 Default collections and data ID values for the new registry. If 

173 not provided, ``self.defaults`` will be used (but future changes 

174 to either registry's defaults will not affect the other). 

175 

176 Returns 

177 ------- 

178 copy : `_ButlerRegistry` 

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

180 

181 Notes 

182 ----- 

183 Because the new registry shares a connection with the original, they 

184 also share transaction state (despite the fact that their `transaction` 

185 context manager methods do not reflect this), and must be used with 

186 care. 

187 """ 

188 raise NotImplementedError() 

189 

190 @abstractmethod 

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

192 """Return the record for this collection. 

193 

194 Parameters 

195 ---------- 

196 name : `str` 

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

198 

199 Returns 

200 ------- 

201 record : `CollectionRecord` 

202 The record for this collection. 

203 """ 

204 raise NotImplementedError() 

205 

206 @abstractmethod 

207 def getDatastoreBridgeManager(self) -> DatastoreRegistryBridgeManager: 

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

209 communicate with this `Registry`. 

210 

211 Returns 

212 ------- 

213 manager : `~.interfaces.DatastoreRegistryBridgeManager` 

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

215 associated datastores. 

216 """ 

217 raise NotImplementedError()