Spaces:
Runtime error
Runtime error
| # ========= Copyright 2023-2024 @ 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-2024 @ 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, create_file_from_raw_bytes | |
| from camel.storages.object_storages.base import BaseObjectStorage | |
| 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." | |
| ) | |
| 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 = 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() | |