In a storage account, you can create a SAS scoped to a specific container, however, that SAS does not have permission to execute BlobClient.exists() as this requires at least list privileges on the parent object (e.g. the account), and when you try to perform the check, you’ll get this error:
azure.core.exceptions.HttpResponseError: This request is not authorized to perform this operation.
Note that this is an HttpResponseError, not a ClientAuthenticationError (which is actually a more specific error which extends HttpResponseError), so you need to interrogate the specific response code, although note that if the container client does not exist, you might also get a ClientAuthenticationError with this message:
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:a52b0bdf-401e-0030-755f-fc3a0f000000\nTime:2024-09-01T11:09:19.0123125Z\nErrorCode:AuthenticationFailed\nauthenticationerrordetail:Signature did not match. String to sign used was rwl\n2022-01-01T00:00:00.0000000Z\n2030-01-01T00:00:00.0000000Z\n/blob/<account>/<container>\n\n\nhttps\n2015-04-05\nmax-age=5\ninline\ndeflate\n\napplication/json
As a workaround, you can instead try to read from or write to (depending on the privilege level you want to test for) the container. For example, you might do something like this:
def test_if_container_exists(container_client: ContainerClient) -> bool:
"""check if a container exists first by calling the .exists() method, even if the SAS scope is restricted to the specific container"""
# first use the .exists() method to check if the container exists
try:
container_client.exists()
return True
except ClientAuthenticationError:
# we dont know if this is because the SAS token doesnt have access or the container doesnt exist
pass
except HttpResponseError as e:
if e.status_code == 404:
return False
elif e.status_code == 403:
pass # could be a SAS token scope restriction
except ResourceNotFoundError:
return False
except Exception as e:
# if we got any other exception, raise it
raise
# if we got ClientAuthenticationError, try to write a small blob to check if the SAS token is valid
try:
blob_client = container_client.get_blob_client("test_blob")
blob_client.upload_blob(b"Test content", overwrite=True)
return True
except ClientAuthenticationError or ResourceNotFoundError:
return False
except Exception as e:
# if we got any other exception, raise it
raise