Hi Rubin Community,
I’m sorry for posting this during the weekend—I know it’s not ideal, but I’ve been stuck on this issue and wanted to get it out there in case anyone has insights.
I’m trying to initialize a Butler instance for the DP1 repository in a RSP notebook (using lsst-scipipe-10.1.0 environment), but I’m getting a 401 Unauthorized error on the /api/butler/repo/dp1/v1/universe endpoint. This started today, even though I’m accessing and logging in the same way as always.
Here’s the full traceback for reference:
from lsst.daf.butler import Butler
butler = Butler("dp1", collections="LSSTComCam/DP1")
---------------------------------------------------------------------------
HTTPStatusError Traceback (most recent call last)
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_http_connection.py:220, in RemoteButlerHttpConnection._send_request(self, request)
219 response = self._send_with_retries(request, stream=False)
--> 220 self._handle_http_status(response, request.request_id)
221 return response
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_http_connection.py:274, in RemoteButlerHttpConnection._handle_http_status(self, response, request_id)
269 # If model is None, server sent an expected error code, but
270 # the body wasn't in the expected JSON format. This likely
271 # means some HTTP thing between us and the server is
272 # misbehaving.
--> 274 response.raise_for_status()
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/lib/python3.12/site-packages/httpx/_models.py:763, in Response.raise_for_status(self)
762 message = message.format(self, error_type=error_type)
--> 763 raise HTTPStatusError(message, request=request, response=self)
HTTPStatusError: Client error '401 Unauthorized' for url 'https://data.lsst.cloud/api/butler/repo/dp1/v1/universe'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401
The above exception was the direct cause of the following exception:
ButlerServerError Traceback (most recent call last)
Cell In[3], line 1
----> 1 butler = Butler("dp1", collections="LSSTComCam/DP1")
2 assert butler is not None
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/_butler.py:166, in Butler.__new__(cls, config, collections, run, searchPaths, writeable, inferDefaults, without_datastore, metrics, **kwargs)
152 def __new__(
153 cls,
154 config: Config | ResourcePathExpression | None = None,
(...)
163 **kwargs: Any,
164 ) -> Butler:
165 if cls is Butler:
--> 166 return Butler.from_config(
167 config=config,
168 collections=collections,
169 run=run,
170 searchPaths=searchPaths,
171 writeable=writeable,
172 inferDefaults=inferDefaults,
173 without_datastore=without_datastore,
174 metrics=metrics,
175 **kwargs,
176 )
178 # Note: we do not pass any parameters to __new__, Python will pass them
179 # to __init__ after __new__ returns sub-class instance.
180 return super().__new__(cls)
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/_butler.py:355, in Butler.from_config(cls, config, collections, run, searchPaths, writeable, inferDefaults, without_datastore, metrics, **kwargs)
352 # Assume this is being created by a client who would like
353 # default caching of remote datasets.
354 factory = RemoteButlerFactory.create_factory_from_config(butler_config)
--> 355 return factory.create_butler_with_credentials_from_environment(
356 butler_options=options, use_disabled_datastore_cache=False
357 )
358 case _:
359 raise TypeError(f"Unknown Butler type '{butler_type}'")
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_factory.py:132, in RemoteButlerFactory.create_butler_with_credentials_from_environment(self, butler_options, use_disabled_datastore_cache)
127 if token is None:
128 raise RuntimeError(
129 "Attempting to connect to Butler server,"
130 " but no access credentials were found in the environment."
131 )
--> 132 return self.create_butler_for_access_token(
133 token, butler_options=butler_options, use_disabled_datastore_cache=use_disabled_datastore_cache
134 )
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_factory.py:111, in RemoteButlerFactory.create_butler_for_access_token(self, access_token, butler_options, use_disabled_datastore_cache)
109 if butler_options is None:
110 butler_options = ButlerInstanceOptions()
--> 111 return RemoteButler(
112 connection=RemoteButlerHttpConnection(
113 http_client=self.http_client, server_url=self.server_url, access_token=access_token
114 ),
115 defaults=RegistryDefaults.from_butler_instance_options(butler_options),
116 cache=self._cache,
117 use_disabled_datastore_cache=use_disabled_datastore_cache,
118 )
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_remote_butler.py:163, in RemoteButler.__new__(cls, connection, defaults, cache, use_disabled_datastore_cache, metrics)
161 self._registry_defaults = DefaultsHolder(defaults)
162 self._registry = RemoteButlerRegistry(self, self._registry_defaults, self._connection)
--> 163 defaults.finish(self._registry)
165 return self
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/registry/_defaults.py:219, in RegistryDefaults.finish(self, registry)
216 if hasattr(self, "_finished"):
217 return
--> 219 allGovernorDimensions = registry.dimensions.governor_dimensions
220 if not self._kwargs.keys() <= allGovernorDimensions.names:
221 raise TypeError(
222 "Only governor dimensions may be identified by a default data "
223 f"ID, not {self._kwargs.keys() - allGovernorDimensions.names}. "
224 "(These may just be unrecognized keyword arguments passed at "
225 "Butler construction.)"
226 )
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_registry.py:111, in RemoteButlerRegistry.dimensions(self)
109 @property
110 def dimensions(self) -> DimensionUniverse:
--> 111 return self._butler.dimensions
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_remote_butler.py:193, in RemoteButler.dimensions(self)
190 if cache.dimensions is not None:
191 return cache.dimensions
--> 193 response = self._connection.get("universe")
194 model = parse_model(response, GetUniverseResponseModel)
196 config = DimensionConfig.from_simple(model.universe)
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_http_connection.py:167, in RemoteButlerHttpConnection.get(self, path, params)
145 """Send a GET request to the Butler server.
146
147 Parameters
(...)
164 If there is an issue communicating with the server.
165 """
166 request = self._build_request("GET", path, params=params)
--> 167 return self._send_request(request)
File /opt/lsst/software/stack/conda/envs/lsst-scipipe-10.1.0/share/eups/Linux64/daf_butler/g6dd59efbe6+ec144cf465/python/lsst/daf/butler/remote_butler/_http_connection.py:223, in RemoteButlerHttpConnection._send_request(self, request)
221 return response
222 except httpx.HTTPStatusError as e:
--> 223 raise ButlerServerError(
224 client_request_id=request.request_id, status_code=e.response.status_code
225 ) from e
226 except httpx.HTTPError as e:
227 raise ButlerServerError(client_request_id=request.request_id) from e
ButlerServerError: Error while communicating with Butler server. Request ID: 47b83aba-abee-4632-acf2-52c2dceed62b
Has anyone seen this before or know what might be going on?
Thanks in advance, and apologies again for the weekend timing!
Best,
Karen