91 def from_uri(cls, uri: ResourcePathExpression) -> ApdbConfig:
92 """Load configuration object from external file.
93
94 Parameters
95 ----------
96 uri : `~lsst.resources.ResourcePathExpression`
97 Location of the file containing serialized configuration in YAML
98 format.
99
100 Returns
101 -------
102 config : `ApdbConfig`
103 Apdb configuration object.
104 """
105 if isinstance(uri, str) and uri.startswith("label:"):
106 tag, _, label = uri.partition(":")
107 index = ApdbIndex()
108
109
110
111 try:
112 uri = index.get_apdb_uri(label, "yaml")
113 except ValueError as yaml_exc:
114 try:
115 uri = index.get_apdb_uri(label, "pex_config")
116 except ValueError:
117
118
119 yaml_exc.add_note(f"Legacy label {label}/pex_config is also missing.")
120 raise yaml_exc from None
121
122 path = ResourcePath(uri)
123 config_bytes = path.read()
124
125
126
127
128 if config_bytes.startswith(b"import lsst.dax.apdb"):
129 from . import legacy_config
130
131 pex_config = legacy_config.ApdbConfig.legacy_load(config_bytes)
132 new_config = pex_config.to_model()
133 warnings.warn(
134 (
135 f"APDB is instantiated using legacy pex_config format from file {path}. "
136 "Support for pex_config format will be removed after v29. Please update "
137 "configuration to new YAML format with `apdb-cli convert-legacy-config` command."
138 ),
139 category=FutureWarning,
140 stacklevel=2,
141 )
142 return new_config
143
144 config_object = yaml.full_load(config_bytes)
145 if not isinstance(config_object, Mapping):
146 raise TypeError("YAML configuration file does not represent valid object")
147 config_dict: dict[str, Any] = dict(config_object)
148 type_name = config_dict.pop("implementation_type", None)
149 if not type_name:
150 raise LookupError("YAML configuration file does not have `implementation_type` key")
151 klass = config_type_for_name(cast(str, type_name))
152 return klass.model_validate(config_dict)
153