Source code for camel.storages.object_storages.azure_blob

# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
# Licensed under the Apache License, Version 2.0 (the “License”);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an “AS IS” BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
import os
from pathlib import Path, PurePath
from typing import Optional, Tuple
from warnings import warn

from camel.loaders import File
from camel.storages.object_storages.base import BaseObjectStorage


[docs] class AzureBlobStorage(BaseObjectStorage): r"""A class to connect to Azure Blob Storage. It will connect to one container in the storage account. Args: storage_account_name (str): The name of the storage account. container_name (str): The name of the container. access_key (Optional[str], optional): The access key of the storage account. Defaults to None. References: https://azure.microsoft.com/en-us/products/storage/blobs """ def __init__( self, storage_account_name: str, container_name: str, create_if_not_exists: bool = True, access_key: Optional[str] = None, ) -> None: access_key = access_key or os.getenv("AZURE_ACCESS_KEY") self._create_if_not_exists = create_if_not_exists if not access_key: warn("AZURE_ACCESS_KEY not provided.") # Make all the empty values None access_key = None from azure.storage.blob import ContainerClient self._client = ContainerClient( account_url="https://" f"{storage_account_name}.blob.core.windows.net", credential=access_key, container_name=container_name, ) self._prepare_and_check() def _prepare_and_check(self) -> None: r"""Check privileges and existence of the container.""" from azure.core.exceptions import ClientAuthenticationError try: exists = self._client.exists() if not exists and self._create_if_not_exists: self._client.create_container() warn( f"Container {self._client.container_name} not found. " f"Automatically created." ) elif not exists: raise FileNotFoundError( f"Failed to access container {self._client.container_name}" f": Not found." ) except ClientAuthenticationError: raise PermissionError( f"Failed to access container {self._client.container_name}: " f"No permission." )
[docs] @staticmethod def canonicalize_path(file_path: PurePath) -> Tuple[str, str]: r"""Canonicalize file path for Azure Blob Storage. Args: file_path (PurePath): The path to be canonicalized. Returns: Tuple[str, str]: The canonicalized file key and file name. """ # for Azure, both slash and backslash will be treated as separator filename = file_path.name if "\\" in filename: raise ValueError( "Azure Blob Storage does not support backslash in filename." ) return file_path.as_posix(), filename
def _put_file(self, file_key: str, file: File) -> None: r"""Put a file to the Azure Blob Storage container. Args: file_key (str): The path to the object in the container. file (File): The file to be uploaded. """ self._client.upload_blob( name=file_key, data=file.raw_bytes, overwrite=True ) def _get_file(self, file_key: str, filename: str) -> File: r"""Get a file from the Azure Blob Storage container. Args: file_key (str): The path to the object in the container. filename (str): The name of the file. Returns: File: The object from the container. """ raw_bytes = self._client.download_blob(file_key).readall() file = File.create_file_from_raw_bytes(raw_bytes, filename) return file def _upload_file( self, local_file_path: Path, remote_file_key: str ) -> None: r"""Upload a local file to the Azure Blob Storage container. Args: local_file_path (Path): The path to the local file to be uploaded. remote_file_key (str): The path to the object in the container. """ with open(local_file_path, "rb") as f: self._client.upload_blob( name=remote_file_key, data=f, overwrite=True ) def _download_file( self, local_file_path: Path, remote_file_key: str ) -> None: r"""Download a file from the Azure Blob Storage container to the local system. Args: local_file_path (Path): The path to the local file to be saved. remote_file_key (str): The key of the object in the container. """ with open(local_file_path, "wb") as f: f.write(self._client.download_blob(remote_file_key).readall()) def _object_exists(self, file_key: str) -> bool: r""" Check if the object exists in the Azure Blob Storage container. Args: file_key: The key of the object in the container. Returns: bool: Whether the object exists in the container. """ return self._client.get_blob_client(file_key).exists()