Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env_integration_tests.example
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ CLOUD_SDK_CFG_OBJECTSTORE_DEFAULT_ACCESS_KEY_ID=your-access-key-id-here
CLOUD_SDK_CFG_OBJECTSTORE_DEFAULT_SECRET_ACCESS_KEY=your-secret-access-key-here
CLOUD_SDK_CFG_OBJECTSTORE_DEFAULT_BUCKET=your-bucket-name-here

# OBJECT STORE - Azure Blob Storage
CLOUD_SDK_CFG_OBJECTSTORE_AZURE_CONTAINER_NAME=your-container-name-here
CLOUD_SDK_CFG_OBJECTSTORE_AZURE_CONTAINER_URI=https://your-account.blob.core.windows.net/your-container
CLOUD_SDK_CFG_OBJECTSTORE_AZURE_SAS_TOKEN=your-sas-token-here

# OBJECT STORE - Google Cloud Storage
CLOUD_SDK_CFG_OBJECTSTORE_GCS_BASE64ENCODEDPRIVATEKEYDATA=your-base64-encoded-service-account-json
CLOUD_SDK_CFG_OBJECTSTORE_GCS_PROJECTID=your-gcp-project-id
CLOUD_SDK_CFG_OBJECTSTORE_GCS_BUCKET=your-gcs-bucket-name

# OUTPUT MANAGEMENT
# For cloud mode (destination-based):
CLOUD_SDK_OMS_DESTINATION_NAME=your-output-management-destination-name-here
Expand Down
17 changes: 15 additions & 2 deletions docs/INTEGRATION_TESTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,28 @@ CLOUD_SDK_CFG_SDM_DEFAULT_UAA='{"url":"https://your-auth-url","clientid":"your-c

### ObjectStore Integration Tests

For ObjectStore integration tests, configure the following variables in `.env_integration_tests`:
ObjectStore scenarios run once for each fully configured provider. Providers
with incomplete credentials are skipped independently. Configure one or more
of the following groups in `.env_integration_tests`:
Provider auto-detection is also verified for each configured group.

```bash
# ObjectStore Configuration
# S3 / S3-compatible ObjectStore
CLOUD_SDK_CFG_OBJECTSTORE_DEFAULT_HOST=your-host-here
CLOUD_SDK_CFG_OBJECTSTORE_DEFAULT_ACCESS_KEY_ID=your-access-key-id-here
CLOUD_SDK_CFG_OBJECTSTORE_DEFAULT_SECRET_ACCESS_KEY=your-secret-access-key-kere
CLOUD_SDK_CFG_OBJECTSTORE_DEFAULT_BUCKET=your-bucket-here
CLOUD_SDK_CFG_OBJECTSTORE_DEFAULT_SSL_ENABLED=false

# Azure Blob Storage
CLOUD_SDK_CFG_OBJECTSTORE_AZURE_CONTAINER_NAME=your-container-name-here
CLOUD_SDK_CFG_OBJECTSTORE_AZURE_CONTAINER_URI=https://your-account.blob.core.windows.net/your-container
CLOUD_SDK_CFG_OBJECTSTORE_AZURE_SAS_TOKEN=your-sas-token-here

# Google Cloud Storage
CLOUD_SDK_CFG_OBJECTSTORE_GCS_BASE64ENCODEDPRIVATEKEYDATA=your-base64-encoded-service-account-json
CLOUD_SDK_CFG_OBJECTSTORE_GCS_PROJECTID=your-gcp-project-id
CLOUD_SDK_CFG_OBJECTSTORE_GCS_BUCKET=your-bucket-here
```

## Running Integration Tests
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ authors = [
requires-python = ">=3.11"
dependencies = [
"minio~=7.2.16",
"azure-storage-blob>=12.20.0",
"google-cloud-storage>=2.18.0",
"setuptools>=83.0",
"requests>=2.33.0",
"requests-oauthlib~=2.0.0",
Expand Down Expand Up @@ -76,6 +78,8 @@ dev = [
"django>=4.0",
"flask>=3.0",
"a2a-sdk>=0.2.0",
"azure-storage-blob>=12.20.0",
"google-cloud-storage>=2.18.0",
"langchain-core>=1.2.7",
"langgraph>=0.2.0",
"langchain-community>=0.3.0",
Expand Down
77 changes: 24 additions & 53 deletions src/sap_cloud_sdk/objectstore/__init__.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,47 @@
"""SAP Cloud SDK for Python - Object Store module

The create_client() uses secret resolver to load credentials from mounts/env vars
``create_client()`` auto-detects the cloud provider from the service binding and
returns a client implementing the ``ObjectStoreClient`` protocol. Supported
providers: S3/MinIO, Azure Blob Storage, Google Cloud Storage.

Usage:
from sap_cloud_sdk.objectstore import create_client

client = create_client("object-store-1")
"""

from typing import Optional

from sap_cloud_sdk.objectstore._factory import create_client
from sap_cloud_sdk.objectstore._models import ObjectMetadata
from sap_cloud_sdk.objectstore._protocol import ObjectReader, ObjectStoreClient
from sap_cloud_sdk.objectstore.config import (
AzureConfig,
GcsConfig,
S3Config,
)
from sap_cloud_sdk.objectstore.exceptions import (
ObjectStoreError,
ClientCreationError,
ObjectOperationError,
ObjectNotFoundError,
ConfigError,
ListObjectsError,
ObjectNotFoundError,
ObjectOperationError,
ObjectStoreError,
)
from sap_cloud_sdk.objectstore._models import ObjectStoreBindingData, ObjectMetadata
from sap_cloud_sdk.objectstore._s3 import ObjectStoreClient
from sap_cloud_sdk.core.secret_resolver import read_from_mount_and_fallback_to_env_var


def create_client(
instance: str,
*,
config: Optional[ObjectStoreBindingData] = None,
disable_ssl: bool = False,
) -> ObjectStoreClient:
"""Creates an ObjectStoreClient with automatic local/cloud detection.
Uses secret resolver to load credentials from mounted secrets or environment variables

Args:
instance: Instance name for cloud mode secret resolution. Must be a non-empty string.
config: Optional explicit configuration. If provided, auto-detection is skipped
and this configuration is used directly.
disable_ssl: Whether to disable SSL/TLS connections. Defaults to False.

Returns:
ObjectStoreClient: Configured client ready for object storage operations.

Raises:
ValueError: If instance parameter is empty or None.
ClientCreationError: If client creation fails due to configuration or connection issues.
"""
if not instance or not instance.strip():
raise ValueError("instance parameter must be a non-empty string")

# Cloud mode: with explicit configuration
if config is not None:
return ObjectStoreClient(config, disable_ssl=disable_ssl)

# Cloud mode: use secret resolver to load configuration
config = ObjectStoreBindingData()
read_from_mount_and_fallback_to_env_var(
base_volume_mount="/etc/secrets/appfnd",
base_var_name="CLOUD_SDK_CFG",
module="objectstore",
instance=instance,
target=config,
)
return ObjectStoreClient(config, disable_ssl=disable_ssl)


__all__ = [
# Public user-facing types
# Protocol (usable as a type annotation)
"ObjectStoreClient",
"ObjectReader",
# Config types (pass to create_client() to bypass auto-detection)
"S3Config",
"AzureConfig",
"GcsConfig",
# Metadata model
"ObjectMetadata",
"ObjectStoreBindingData",
# Factory function
"create_client",
# Exceptions
"ObjectStoreError",
"ConfigError",
"ClientCreationError",
"ObjectOperationError",
"ObjectNotFoundError",
Expand Down
Loading